mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-09-30 08:07:28 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45a0ccec2a | ||
|
|
d9bb403264 |
+19
-10
@@ -1,25 +1,34 @@
|
||||
# Last match in file takes precedence.
|
||||
# See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#example-of-a-codeowners-file
|
||||
|
||||
* @DeltaV-Station/maintainers
|
||||
# C# code
|
||||
/Content.*/ @DeltaV-Station/maintainers
|
||||
|
||||
# Any assets
|
||||
/Resources/ @DeltaV-Station/maintainers
|
||||
|
||||
# Server config files
|
||||
/Resources/ConfigPresets/ @DeltaV-Station/lead-maintainers
|
||||
|
||||
# Github workflows
|
||||
/.github/ @DeltaV-Station/lead-maintainers
|
||||
/Resources/ConfigPresets/ @Toby222
|
||||
|
||||
# Lobby art and music - automatically direction issues since its immediately visible to players
|
||||
/Resources/Audio/Lobby/ @DeltaV-Station/direction @DeltaV-Station/maintainers
|
||||
/Resources/Textures/LobbyScreens/ @DeltaV-Station/direction @DeltaV-Station/maintainers
|
||||
/Resources/Audio/Lobby/ @DeltaV-Station/direction
|
||||
/Resources/Textures/LobbyScreens/ @DeltaV-Station/direction
|
||||
|
||||
# Maps
|
||||
/Resources/Maps/ @DeltaV-Station/maptainers
|
||||
/Resources/Prototypes/Maps/ @DeltaV-Station/maptainers
|
||||
/Content.IntegrationTests/Tests/PostMapInitTest.cs @DeltaV-Station/maptainers @DeltaV-Station/maintainers
|
||||
/Content.IntegrationTests/Tests/PostMapInitTest.cs @DeltaV-Station/maptainers
|
||||
|
||||
# Server rules
|
||||
/Resources/ServerInfo/Guidebook/_DV/Rules/ @DeltaV-Station/head-administrators
|
||||
|
||||
# Wiki
|
||||
/.wiki/ @DeltaV-Station/direction
|
||||
/.wiki/ @DeltaV-Station/direction
|
||||
|
||||
# Tools and scripts
|
||||
/Tools/ @Toby222
|
||||
|
||||
# Workflows, codeowners, templates, etc.
|
||||
/.github/ @Toby222
|
||||
|
||||
# Standalone files in the root repo
|
||||
/* @Toby222
|
||||
|
||||
@@ -26,7 +26,7 @@ This just saves them the trouble. Note that AGPL or MIT licensing is only applic
|
||||
- [ ] I confirm that I am the creator of the code in this PR, and allow licensing it under the following license(s), or that the original author(s) has given me permission to do so:
|
||||
- [X] AGPL (https://github.com/DeltaV-Station/Delta-v/blob/master/LICENSE-AGPLv3.txt) <!-- This one is required to contribute to DeltaV -->
|
||||
- [X] MIT (https://github.com/DeltaV-Station/Delta-v/blob/master/LICENSE-MIT.txt) <!-- Optional - A lot of other SS14 forks use MIT -->
|
||||
<!-- Feel free to add more licenses as you see fit -->
|
||||
<!-- Feel free to add more licenses as you see fit -->
|
||||
|
||||
**Changelog**
|
||||
<!-- Add a Changelog entry to make players aware of new features or changes that could affect gameplay.
|
||||
|
||||
@@ -2,7 +2,6 @@ using Content.Client.Cargo.UI;
|
||||
using Content.Shared.Cargo.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
using Content.Shared._DV.Cargo.Components; // DeltaV: Bounty claim messages
|
||||
|
||||
namespace Content.Client.Cargo.BUI;
|
||||
|
||||
@@ -31,18 +30,6 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
SendMessage(new BountySkipMessage(id));
|
||||
};
|
||||
|
||||
// DeltaV: bounty claim stuff begins
|
||||
_menu.OnClaimButtonPressed += id =>
|
||||
{
|
||||
SendMessage(new BountyClaimedMessage(id));
|
||||
};
|
||||
|
||||
_menu.OnStatusOptionSelected += (id, status) =>
|
||||
{
|
||||
SendMessage(new BountySetStatusMessage(id, status));
|
||||
};
|
||||
// DeltaV: bounty claim stuff ends
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState message)
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
|
||||
<RichTextLabel Name="RewardLabel"/>
|
||||
<RichTextLabel Name="ManifestLabel"/>
|
||||
<RichTextLabel Name="ClaimedBylabel"/> <!-- DeltaV bounty claim -->
|
||||
<RichTextLabel Name="StatusLabel"/> <!-- DeltaV bounty claim -->
|
||||
</BoxContainer>
|
||||
<Control MinWidth="10"/>
|
||||
<BoxContainer Orientation="Vertical" MinWidth="120">
|
||||
@@ -19,22 +17,14 @@
|
||||
<Button Name="PrintButton"
|
||||
Text="{Loc 'bounty-console-label-button-text'}"
|
||||
HorizontalExpand="False"
|
||||
StyleClasses="OpenBoth"/>
|
||||
HorizontalAlignment="Right"
|
||||
StyleClasses="OpenRight"/>
|
||||
<Button Name="SkipButton"
|
||||
Text="{Loc 'bounty-console-skip-button-text'}"
|
||||
HorizontalExpand="True"
|
||||
HorizontalExpand="False"
|
||||
HorizontalAlignment="Right"
|
||||
StyleClasses="OpenLeft"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" MinWidth="120"> <!-- Begin DeltaV bounty claim content -->
|
||||
<Button Name="ClaimButton"
|
||||
Text= "{Loc 'bounty-console-claim-button-text'}"
|
||||
HorizontalExpand="False"
|
||||
StyleClasses="OpenRight"/>
|
||||
<OptionButton Name="BountyStatusSelector"
|
||||
Access="Public"
|
||||
StyleClasses="OpenBoth"
|
||||
HorizontalExpand="True"/>
|
||||
</BoxContainer> <!-- End DeltaV content-->
|
||||
<RichTextLabel Name="IdLabel" HorizontalAlignment="Right" Margin="0 0 5 0"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
@@ -17,8 +17,6 @@ public sealed partial class BountyEntry : BoxContainer
|
||||
|
||||
public Action? OnLabelButtonPressed;
|
||||
public Action? OnSkipButtonPressed;
|
||||
public Action? OnClaimButtonPressed; // DeltaV
|
||||
public Action? OnStatusOptionSelected; // DeltaV
|
||||
|
||||
public TimeSpan EndTime;
|
||||
public TimeSpan UntilNextSkip;
|
||||
@@ -47,20 +45,6 @@ public sealed partial class BountyEntry : BoxContainer
|
||||
|
||||
PrintButton.OnPressed += _ => OnLabelButtonPressed?.Invoke();
|
||||
SkipButton.OnPressed += _ => OnSkipButtonPressed?.Invoke();
|
||||
|
||||
// Begin DeltaV bounty claiming
|
||||
ClaimButton.OnPressed += _ => OnClaimButtonPressed?.Invoke();
|
||||
BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.Undelivered)}"), 0);
|
||||
BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.Waiting)}"), 1);
|
||||
BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.OnShuttle)}"), 2);
|
||||
|
||||
BountyStatusSelector.Select((int) bounty.Status);
|
||||
BountyStatusSelector.ToolTip = Loc.GetString($"bounty-console-status-tooltip-{bounty.Status.ToString()}");
|
||||
|
||||
var claimedByText = string.IsNullOrEmpty(bounty.ClaimedBy) ? Loc.GetString("bounty-console-claimed-by-none") : bounty.ClaimedBy;
|
||||
ClaimedBylabel.SetMarkup(Loc.GetString("bounty-console-claimed-by", ("claimant", claimedByText)));
|
||||
StatusLabel.SetMarkup(Loc.GetString($"bounty-console-status-formatted-{bounty.Status.ToString()}"));
|
||||
// End DeltaV bounty claiming
|
||||
}
|
||||
|
||||
private void UpdateSkipButton(float deltaSeconds)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<!--DeltaV - SetSize was 550, now 750 to accomodate bounty claim UI -->
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'bounty-console-menu-title'}"
|
||||
SetSize="750 420"
|
||||
SetSize="550 420"
|
||||
MinSize="400 350">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
VerticalExpand="True"
|
||||
|
||||
@@ -11,8 +11,6 @@ public sealed partial class CargoBountyMenu : FancyWindow
|
||||
{
|
||||
public Action<string>? OnLabelButtonPressed;
|
||||
public Action<string>? OnSkipButtonPressed;
|
||||
public Action<string>? OnClaimButtonPressed; // DeltaV
|
||||
public Action<string, int>? OnStatusOptionSelected; // DeltaV
|
||||
|
||||
public CargoBountyMenu()
|
||||
{
|
||||
@@ -33,8 +31,6 @@ public sealed partial class CargoBountyMenu : FancyWindow
|
||||
var entry = new BountyEntry(b, untilNextSkip);
|
||||
entry.OnLabelButtonPressed += () => OnLabelButtonPressed?.Invoke(b.Id);
|
||||
entry.OnSkipButtonPressed += () => OnSkipButtonPressed?.Invoke(b.Id);
|
||||
entry.OnClaimButtonPressed += () => OnClaimButtonPressed?.Invoke(b.Id); // DeltaV
|
||||
entry.BountyStatusSelector.OnItemSelected += args => OnStatusOptionSelected?.Invoke(b.Id, args.Id); // DeltaV
|
||||
|
||||
BountyEntriesContainer.AddChild(entry);
|
||||
}
|
||||
|
||||
@@ -59,12 +59,9 @@
|
||||
<Label Text="{Loc 'health-analyzer-window-entity-temperature-text'}" />
|
||||
<Label Name="TemperatureLabel" />
|
||||
<Label Text="{Loc 'health-analyzer-window-entity-blood-level-text'}" />
|
||||
<!-- Begin DeltaV - Health Analyzer Plus -->
|
||||
<Label Name="BloodLevelLabel" />
|
||||
<!-- Label Name="BloodLabel" / -->
|
||||
<!-- Label Text="{Loc 'health-analyzer-window-entity-damage-total-text'}" / -->
|
||||
<!-- Label Name="DamageLabel" / -->
|
||||
<!-- End DeltaV - Health Analyzer Plus -->
|
||||
<Label Name="BloodLabel" />
|
||||
<Label Text="{Loc 'health-analyzer-window-entity-damage-total-text'}" />
|
||||
<Label Name="DamageLabel" />
|
||||
</GridContainer>
|
||||
</BoxContainer>
|
||||
|
||||
@@ -76,41 +73,10 @@
|
||||
|
||||
<PanelContainer StyleClasses="LowDivider" />
|
||||
|
||||
<!-- Begin DeltaV - Health Analyzer Plus -->
|
||||
<!-- BoxContainer Name="GroupsContainer" Margin="0 5 0 5" Orientation="Vertical" -->
|
||||
<!-- /BoxContainer -->
|
||||
|
||||
<GridContainer Margin="0 5 0 5" Columns="3" HorizontalAlignment="Center">
|
||||
<BoxContainer Name="DamageBox" Margin="5 5 5 5" Orientation="Vertical">
|
||||
<Label Name="TotalDamageLabel" HorizontalAlignment="Center" />
|
||||
<PanelContainer Name="DamageGroupsDivider" StyleClasses="LowDivider" />
|
||||
<Label
|
||||
Name="NoDamageLabel"
|
||||
HorizontalAlignment="Center"
|
||||
Text="{Loc 'health-analyzer-plus-window-no-damage-text'}"
|
||||
FontColorOverride="DeepSkyBlue"
|
||||
Margin="0 5 0 5" />
|
||||
<BoxContainer HorizontalAlignment="Center">
|
||||
<BoxContainer Name="DamageGroupsContainer" Margin="0 5 0 5" Orientation="Vertical" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<PanelContainer StyleClasses="LowDivider" />
|
||||
|
||||
<BoxContainer Name="BloodstreamBox" Margin="5 5 5 5" Orientation="Vertical">
|
||||
<Label Name="TotalReagentQuantityLabel" HorizontalAlignment="Center" />
|
||||
<PanelContainer Name="BloodstreamReagentsDivider" StyleClasses="LowDivider" />
|
||||
<Label
|
||||
Name="NoReagentsLabel"
|
||||
HorizontalAlignment="Center"
|
||||
Text="{Loc 'health-analyzer-plus-window-no-reagents-text'}"
|
||||
FontColorOverride="DeepSkyBlue"
|
||||
Margin="0 5 0 5" />
|
||||
<BoxContainer HorizontalAlignment="Center">
|
||||
<BoxContainer Name="BloodstreamReagentListContainer" Orientation="Vertical" Margin="0 5 0 5" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</GridContainer>
|
||||
<!-- End DeltaV - Health Analyzer Plus -->
|
||||
<BoxContainer
|
||||
Name="GroupsContainer"
|
||||
Margin="0 5 0 5"
|
||||
Orientation="Vertical">
|
||||
</BoxContainer>
|
||||
|
||||
</BoxContainer>
|
||||
|
||||
@@ -19,25 +19,12 @@ using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
// BEGIN DeltaV
|
||||
using Content.Client._DV.Traits.Assorted;
|
||||
using Content.Shared._DV.Traits.Assorted;
|
||||
using Content.Shared._DV.Medical; // Uncloneable
|
||||
using Content.Shared._DV.MedicalRecords; // Medical Records
|
||||
|
||||
// Health Analyzer Plus
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Body.Systems;
|
||||
using Content.Client.Body.Systems;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Client.Chemistry.Containers.EntitySystems;
|
||||
using Content.Shared.Body.Components;
|
||||
// END DeltaV
|
||||
namespace Content.Client.HealthAnalyzer.UI;
|
||||
|
||||
|
||||
using Content.Client._DV.Traits.Assorted; // DeltaV
|
||||
using Content.Shared._DV.Traits.Assorted; // DeltaV
|
||||
using Content.Shared._DV.Medical; // DeltaV - Uncloneable
|
||||
using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
|
||||
|
||||
// Health analyzer UI is split from its window because it's used by both the
|
||||
// health analyzer item and the cryo pod UI.
|
||||
@@ -45,8 +32,6 @@ namespace Content.Client.HealthAnalyzer.UI;
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
{
|
||||
private const string REAGENT_GROUP_MEDICINE = "Medicine"; // DeltaV - Health Analyzer
|
||||
|
||||
private readonly IEntityManager _entityManager;
|
||||
private readonly SpriteSystem _spriteSystem;
|
||||
private readonly IPrototypeManager _prototypes;
|
||||
@@ -56,8 +41,6 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
private readonly UnborgableSystem _unborgable; // DeltaV
|
||||
private readonly RedshirtSystem _redshirt; // DeltaV
|
||||
private readonly UncloneableSystem _uncloneable; // DeltaV
|
||||
private readonly SharedBloodstreamSystem _bloodstream; // DeltaV
|
||||
private readonly SharedSolutionContainerSystem _solutionContainer; // DeltaV
|
||||
|
||||
// Begin DeltaV - Medical Records
|
||||
private readonly ButtonGroup _triageStatusGroup = new();
|
||||
@@ -83,8 +66,6 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
_unborgable = _entityManager.System<UnborgableSystem>(); // DeltaV
|
||||
_redshirt = _entityManager.System<RedshirtSystem>(); // DeltaV
|
||||
_uncloneable = _entityManager.System<UncloneableSystem>(); // DeltaV
|
||||
_bloodstream = _entityManager.System<BloodstreamSystem>(); // DeltaV
|
||||
_solutionContainer = _entityManager.System<SolutionContainerSystem>(); // DeltaV
|
||||
|
||||
// Begin DeltaV - Medical Records
|
||||
foreach (var item in Enum.GetValues<TriageStatus>())
|
||||
@@ -157,13 +138,9 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
? $"{state.Temperature - Atmospherics.T0C:F1} °C ({state.Temperature:F1} K)"
|
||||
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
|
||||
|
||||
// Begin DeltaV - Health Analyzer Plus
|
||||
/*
|
||||
BloodLabel.Text = !float.IsNaN(state.BloodLevel)
|
||||
? $"{state.BloodLevel * 100:F1} %"
|
||||
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
|
||||
*/
|
||||
// End DeltaV - Health Analyzer Plus
|
||||
|
||||
StatusLabel.Text =
|
||||
_entityManager.TryGetComponent<MobStateComponent>(target.Value, out var mobStateComponent)
|
||||
@@ -172,7 +149,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
|
||||
// Total Damage
|
||||
|
||||
// DamageLabel.Text = _damageable.GetTotalDamage(target.Value).ToString(); // DeltaV - Health Analyzer Plus
|
||||
DamageLabel.Text = _damageable.GetTotalDamage(target.Value).ToString();
|
||||
|
||||
// Alerts
|
||||
// DeltaV traits - This is going to be horrid if we just keep adding things like this.
|
||||
@@ -239,7 +216,6 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
var damagePerType = _damageable.GetAllDamage(target.Value).DamageDict;
|
||||
|
||||
DrawDiagnosticGroups(damageSortedGroups, damagePerType);
|
||||
DrawBloodstreamInfo(target.Value, state.BloodSolution, state.BloodLevel); // End DeltaV - Health Analyzer Plus
|
||||
|
||||
// Begin DeltaV - Medical Records
|
||||
if (state.MedicalRecord is not { } records)
|
||||
@@ -278,15 +254,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
Dictionary<ProtoId<DamageGroupPrototype>, FixedPoint2> groups,
|
||||
IReadOnlyDictionary<ProtoId<DamageTypePrototype>, FixedPoint2> damageDict)
|
||||
{
|
||||
// Begin DeltaV - Health Analyzer Plus
|
||||
// GroupsContainer.RemoveAllChildren();
|
||||
DamageGroupsContainer.RemoveAllChildren();
|
||||
|
||||
// Begin DeltaV - Health Analyzer Plus
|
||||
var totalDamage = damageDict.Sum(x => x.Value.Double());
|
||||
TotalDamageLabel.Text = Loc.GetString("health-analyzer-plus-window-entity-total-damage-text", ("amount", Math.Round(totalDamage, 2)));
|
||||
NoDamageLabel.Visible = totalDamage == 0;
|
||||
// End DeltaV - Health Analyzer Plus
|
||||
GroupsContainer.RemoveAllChildren();
|
||||
|
||||
foreach (var (damageGroupId, damageAmount) in groups)
|
||||
{
|
||||
@@ -307,8 +275,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
|
||||
groupContainer.AddChild(CreateDiagnosticGroupTitle(groupTitleText, damageGroupId));
|
||||
|
||||
// GroupsContainer.AddChild(groupContainer); // DeltaV - Health Analyzer Plus
|
||||
DamageGroupsContainer.AddChild(groupContainer); // DeltaV - Health Analyzer Plus
|
||||
GroupsContainer.AddChild(groupContainer);
|
||||
|
||||
// Show the damage for each type in that group.
|
||||
var group = _prototypes.Index(damageGroupId);
|
||||
@@ -329,116 +296,6 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
||||
}
|
||||
}
|
||||
|
||||
// Begin DeltaV - Health Analyzer Plus
|
||||
private void DrawBloodstreamInfo(EntityUid target, Solution? bloodSolution, float bloodlevel)
|
||||
{
|
||||
BloodstreamReagentListContainer.RemoveAllChildren();
|
||||
|
||||
List<ReagentQuantity> bloodstream = new();
|
||||
double totalReagentQuantity = 0;
|
||||
double unknownReagents = 0;
|
||||
// Make sure we can access the bloodtype and reagents before trying to use them
|
||||
if (bloodSolution is not null)
|
||||
{
|
||||
if (!_entityManager.TryGetComponent<BloodstreamComponent>(target, out var bloodstreamComp) ||
|
||||
!_solutionContainer.ResolveSolution(target, bloodstreamComp.BloodSolutionName, ref bloodstreamComp.BloodSolution, out var bloodReagentSolution))
|
||||
return;
|
||||
|
||||
// Get the blood reagent IDs to ignore in the scan
|
||||
var bloodReagentIds = bloodstreamComp.BloodReferenceSolution.Select(b => b.Reagent);
|
||||
|
||||
// Get all of the medicines in the bloodstream
|
||||
foreach (var reagent in bloodSolution!.Contents)
|
||||
{
|
||||
if (bloodReagentIds.Contains(reagent.Reagent))
|
||||
continue;
|
||||
|
||||
if (_prototypes.Index<ReagentPrototype>(reagent.Reagent.Prototype).Group == REAGENT_GROUP_MEDICINE)
|
||||
{
|
||||
bloodstream.Add(reagent);
|
||||
totalReagentQuantity += reagent.Quantity.Double();
|
||||
}
|
||||
else
|
||||
{
|
||||
unknownReagents += reagent.Quantity.Double();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var bloodQuantityPercent = !float.IsNaN(bloodlevel)
|
||||
? $"{bloodlevel * 100:F1} %"
|
||||
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
|
||||
|
||||
// Display the percent and amount of blood in the system
|
||||
// Normal health scanner is percent only, this one adds the actual units too
|
||||
BloodLevelLabel.Text = Loc.GetString(
|
||||
"health-analyzer-plus-window-entity-blood-level-quantity-text",
|
||||
("percent", bloodQuantityPercent)
|
||||
);
|
||||
|
||||
// Display the total amount of reagents in the bloodstream, 0 is valid
|
||||
TotalReagentQuantityLabel.Text = Loc.GetString(
|
||||
"health-analyzer-plus-window-entity-total-reagents-text",
|
||||
("amount", Math.Round(totalReagentQuantity, 1).ToString("0.0"))
|
||||
);
|
||||
|
||||
// If the bloodstream was empty, display a message instead to fill the space with something
|
||||
NoReagentsLabel.Visible = bloodstream.Count == 0 && unknownReagents == 0;
|
||||
|
||||
// For each of the reagents in the bloodstream, add them to the list of reagents
|
||||
// If there are none, this loop will simply do nothing
|
||||
foreach (var (reagentID, reagentQuantity) in bloodstream)
|
||||
{
|
||||
var reagentPrototype = _prototypes.Index<ReagentPrototype>(reagentID.Prototype);
|
||||
|
||||
// Make a new container for each reagent we add to the list
|
||||
var reagentContainer = new BoxContainer
|
||||
{
|
||||
Align = AlignMode.Begin,
|
||||
Orientation = LayoutOrientation.Vertical
|
||||
};
|
||||
|
||||
// Add the string "[] <reagent_name>: <reagent_amount>u" for the current reagent
|
||||
// The [] is a unicode block character, and is colored with the reagent color
|
||||
// to make it easier to identify
|
||||
reagentContainer.AddChild(
|
||||
new RichTextLabel
|
||||
{
|
||||
Text = Loc.GetString("health-analyzer-plus-window-reagent-text",
|
||||
("reagentColor", reagentPrototype.SubstanceColor),
|
||||
("reagentName", reagentPrototype.LocalizedName),
|
||||
("amount", Math.Round(reagentQuantity.Double(), 1).ToString("0.0"))
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
BloodstreamReagentListContainer.AddChild(reagentContainer);
|
||||
}
|
||||
|
||||
// Add unknown reagents (if any)
|
||||
if (unknownReagents > 0)
|
||||
{
|
||||
var unknownReagentContainer = new BoxContainer
|
||||
{
|
||||
Align = AlignMode.Begin,
|
||||
Orientation = LayoutOrientation.Vertical
|
||||
};
|
||||
|
||||
unknownReagentContainer.AddChild(
|
||||
new RichTextLabel
|
||||
{
|
||||
Text = Loc.GetString("health-analyzer-plus-window-unknown-reagents-text",
|
||||
("amount", Math.Round(unknownReagents, 1).ToString("0.0"))
|
||||
)
|
||||
}
|
||||
);
|
||||
BloodstreamReagentListContainer.AddChild(unknownReagentContainer);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
// End DeltaV - Health Analyzer Plus
|
||||
|
||||
private Texture GetTexture(string texture)
|
||||
{
|
||||
var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi");
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
<ScrollContainer
|
||||
Margin="5 5 5 5"
|
||||
ReturnMeasure="True"
|
||||
VerticalExpand="True"
|
||||
VScrollBarHidden="True"
|
||||
HScrollBarHidden="True"> <!-- DeltaV - Hide the scroll bars -->
|
||||
VerticalExpand="True">
|
||||
|
||||
<ui:HealthAnalyzerControl
|
||||
Name="HealthAnalyzer"
|
||||
|
||||
@@ -34,9 +34,6 @@ namespace Content.Client.Input
|
||||
common.AddFunction(ContentKeyFunctions.RotateStoredItem);
|
||||
common.AddFunction(ContentKeyFunctions.SaveItemLocation);
|
||||
common.AddFunction(ContentKeyFunctions.Point);
|
||||
// Floofstation section
|
||||
common.AddFunction(ContentKeyFunctions.OfferItem);
|
||||
// Floofstation section end
|
||||
common.AddFunction(ContentKeyFunctions.ZoomOut);
|
||||
common.AddFunction(ContentKeyFunctions.ZoomIn);
|
||||
common.AddFunction(ContentKeyFunctions.ResetZoom);
|
||||
|
||||
@@ -9,8 +9,6 @@ using Content.Shared.Preferences;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Client._CD.Records.UI; // DeltaV
|
||||
using Content.Shared._DV.Body.Systems; // DeltaV
|
||||
|
||||
namespace Content.Client.Lobby.UI;
|
||||
|
||||
@@ -195,7 +193,6 @@ public sealed partial class HumanoidProfileEditor
|
||||
RefreshLoadouts();
|
||||
UpdateSexControls(); // update sex for new species
|
||||
UpdateSpeciesGuidebookIcon();
|
||||
UpdateHeightControls(); // DeltaV
|
||||
ReloadPreview();
|
||||
}
|
||||
|
||||
@@ -207,22 +204,23 @@ public sealed partial class HumanoidProfileEditor
|
||||
ReloadProfilePreview();
|
||||
}
|
||||
|
||||
|
||||
private void UpdateHeightControls()
|
||||
{
|
||||
if (Profile == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var prototype = _prototypeManager.Index(Profile.Species);
|
||||
_defaultHeight = prototype.DefaultHeight;
|
||||
var species = _species.Find(x => x.ID == Profile.Species);
|
||||
if (species != null)
|
||||
_defaultHeight = species.DefaultHeight;
|
||||
|
||||
var prototype = _prototypeManager.Index<SpeciesPrototype>(Profile.Species);
|
||||
var sliderPercent = (Profile.Height - prototype.MinHeight) /
|
||||
(prototype.MaxHeight - prototype.MinHeight);
|
||||
CDHeightSlider.Value = sliderPercent;
|
||||
|
||||
var scaleReference = _defaultHeight * prototype.BaseScale.Y;
|
||||
var newHeight = MathF.Round(MathHelper.Lerp(prototype.MinHeight, prototype.MaxHeight, sliderPercent), 2);
|
||||
CDHeightLabel.Text = UnitConversion.GetMetricAndImperialDisplayFromScale(scaleReference * newHeight);
|
||||
CDPullSpeedReductionLabel.Text = SmallCharacterSystem.GetPullSpeedPenaltyDisplayFromScale(newHeight);
|
||||
CDHeight.Text = Profile.Height.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
// End CD - Character Records
|
||||
|
||||
|
||||
@@ -73,13 +73,9 @@
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Text="{Loc 'humanoid-profile-editor-height-label'}" />
|
||||
<Control HorizontalExpand="True" />
|
||||
<Label Name="CDHeightLabel" />
|
||||
<Slider Name="CDHeightSlider" HorizontalAlignment="Right" SetWidth="300" MinValue="0.0" MaxValue="1.0"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Text="{Loc 'humanoid-profile-editor-height-pull-speed-penalty-label'}" />
|
||||
<Control HorizontalExpand="True" />
|
||||
<Label Name="CDPullSpeedReductionLabel" />
|
||||
<LineEdit HorizontalAlignment="Right" Name="CDHeight" MinSize="60 0" Text="1.0" />
|
||||
<Button Name="CDHeightReset" Text="{Loc 'humanoid-profile-editor-reset-height-button'}" HorizontalAlignment="Right"/>
|
||||
</BoxContainer>
|
||||
<!-- End CD - Character Records -->
|
||||
<!-- Sex -->
|
||||
|
||||
@@ -2,6 +2,9 @@ using Content.Client.Humanoid;
|
||||
using Content.Client.Message;
|
||||
using Content.Client.Players.PlayTimeTracking;
|
||||
using Content.Client.Sprite;
|
||||
using Content.Client.UserInterface.Systems.Guidebook;
|
||||
using Content.Shared._DV.Species; // DeltaV - Species hider
|
||||
using Content.Shared.Body;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Humanoid;
|
||||
@@ -19,8 +22,13 @@ using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
using Content.Client._CD.Records.UI; // CD - Character Records
|
||||
using Content.Shared._DV.Body.Systems; // DV - Traits
|
||||
// Begin CD - Character Records
|
||||
using System.Globalization;
|
||||
using Content.Client._CD.Records.UI;
|
||||
using Content.Shared._CD.Records;
|
||||
// End CD - Character Records
|
||||
using Content.Shared._DV.Traits;
|
||||
using Content.Shared.Humanoid.Prototypes; // DV - Traits
|
||||
|
||||
namespace Content.Client.Lobby.UI
|
||||
{
|
||||
@@ -213,18 +221,34 @@ namespace Content.Client.Lobby.UI
|
||||
// Begin CD - Character Records
|
||||
#region CDHeight
|
||||
|
||||
CDHeight.OnTextChanged += args =>
|
||||
{
|
||||
if (Profile is null || !float.TryParse(args.Text, out var newHeight))
|
||||
return;
|
||||
|
||||
var prototype = _prototypeManager.Index<SpeciesPrototype>(Profile.Species);
|
||||
newHeight = MathF.Round(Math.Clamp(newHeight, prototype.MinHeight, prototype.MaxHeight), 2);
|
||||
|
||||
// The percentage between the start and end numbers, aka "inverse lerp"
|
||||
var sliderPercent = (newHeight - prototype.MinHeight) /
|
||||
(prototype.MaxHeight - prototype.MinHeight);
|
||||
CDHeightSlider.Value = sliderPercent;
|
||||
|
||||
SetProfileHeight(newHeight);
|
||||
};
|
||||
|
||||
CDHeightReset.OnPressed += _ =>
|
||||
{
|
||||
CDHeight.SetText(_defaultHeight.ToString(CultureInfo.InvariantCulture), true);
|
||||
};
|
||||
|
||||
CDHeightSlider.OnValueChanged += _ =>
|
||||
{
|
||||
if (Profile is null)
|
||||
return;
|
||||
|
||||
var prototype = _prototypeManager.Index(Profile.Species);
|
||||
var prototype = _prototypeManager.Index<SpeciesPrototype>(Profile.Species);
|
||||
var newHeight = MathF.Round(MathHelper.Lerp(prototype.MinHeight, prototype.MaxHeight, CDHeightSlider.Value), 2);
|
||||
|
||||
var speciesScale = prototype.BaseScale.Y;
|
||||
|
||||
CDHeightLabel.Text = UnitConversion.GetMetricAndImperialDisplayFromScale(newHeight * speciesScale);
|
||||
CDPullSpeedReductionLabel.Text = SmallCharacterSystem.GetPullSpeedPenaltyDisplayFromScale(newHeight);
|
||||
CDHeight.Text = newHeight.ToString(CultureInfo.InvariantCulture);
|
||||
SetProfileHeight(newHeight);
|
||||
};
|
||||
|
||||
|
||||
@@ -75,11 +75,9 @@ public sealed partial class CrewMonitoringNavMapControl : NavMapControl
|
||||
if (!LocalizedNames.TryGetValue(netEntity, out var name))
|
||||
name = Loc.GetString("navmap-unknown-entity");
|
||||
|
||||
var pos = _xform.ToMapCoordinates(blip.Coordinates); // DeltaV - map-coordinates
|
||||
|
||||
var message = name + "\n" + Loc.GetString("navmap-location",
|
||||
("x", MathF.Round(pos.X)), // DeltaV - map-coordinates
|
||||
("y", MathF.Round(pos.Y))); // DeltaV - map-coordinates
|
||||
("x", MathF.Round(blip.Coordinates.X)),
|
||||
("y", MathF.Round(blip.Coordinates.Y)));
|
||||
|
||||
_trackedEntityLabel.Text = message;
|
||||
_trackedEntityPanel.Visible = true;
|
||||
|
||||
@@ -88,9 +88,9 @@ public sealed partial class CryoPodWindow : FancyWindow
|
||||
// Health analyzer
|
||||
var maybePatient = _entityManager.GetEntity(msg.Health.TargetEntity);
|
||||
var hasPatient = msg.Health.TargetEntity.HasValue;
|
||||
// var hasDamage = hasPatient && msg.HasDamage; // DeltaV - Health Analyzer Plus
|
||||
var hasDamage = hasPatient && msg.HasDamage;
|
||||
|
||||
NoDamageText.Visible = false; //(hasPatient && !hasDamage); // DeltaV - Health Analyzer Plus
|
||||
NoDamageText.Visible = (hasPatient && !hasDamage);
|
||||
HealthSection.Visible = hasPatient;
|
||||
EjectPatientButton.Disabled = !hasPatient;
|
||||
|
||||
|
||||
@@ -208,7 +208,6 @@ namespace Content.Client.Options.UI.Tabs
|
||||
AddButton(ContentKeyFunctions.MovePulledObject);
|
||||
AddButton(ContentKeyFunctions.ReleasePulledObject);
|
||||
AddButton(ContentKeyFunctions.Point);
|
||||
AddButton(ContentKeyFunctions.OfferItem); // Floofstation
|
||||
AddButton(ContentKeyFunctions.RotateObjectClockwise);
|
||||
AddButton(ContentKeyFunctions.RotateObjectCounterclockwise);
|
||||
AddButton(ContentKeyFunctions.FlipObject);
|
||||
|
||||
@@ -11,7 +11,6 @@ using Content.Shared.StatusIcon;
|
||||
using Content.Shared.StatusIcon.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player; // DeltaV
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
using static Robust.Shared.Maths.Color;
|
||||
@@ -23,7 +22,6 @@ namespace Content.Client.Overlays;
|
||||
/// </summary>
|
||||
public sealed class EntityHealthBarOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!; // DeltaV
|
||||
private readonly IEntityManager _entManager;
|
||||
private readonly IPrototypeManager _prototype;
|
||||
|
||||
@@ -42,8 +40,6 @@ public sealed class EntityHealthBarOverlay : Overlay
|
||||
|
||||
public EntityHealthBarOverlay(IEntityManager entManager, IPrototypeManager prototype)
|
||||
{
|
||||
IoCManager.InjectDependencies(this); // DeltaV
|
||||
|
||||
_entManager = entManager;
|
||||
_prototype = prototype;
|
||||
_transform = _entManager.System<SharedTransformSystem>();
|
||||
@@ -73,11 +69,6 @@ public sealed class EntityHealthBarOverlay : Overlay
|
||||
out var damageableComponent,
|
||||
out var spriteComponent))
|
||||
{
|
||||
// BEGIN DeltaV - You can't see your own bar :godo:
|
||||
if (_player.LocalEntity is { } player && player.Id == uid.Id)
|
||||
continue;
|
||||
// END DeltaV
|
||||
|
||||
if (statusIcon != null && !_statusIconSystem.IsVisible((uid, _entManager.GetComponent<MetaDataComponent>(uid)), statusIcon))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:chassisSpriteControls="clr-namespace:Content.Client._CD.Silicons.Borgs.UI"
|
||||
Title="{Loc 'borg-select-type-menu-title'}"
|
||||
SetSize="550 300">
|
||||
SetSize="600 480">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Orientation="Horizontal" VerticalExpand="True">
|
||||
<!-- Left pane: selection of borg type -->
|
||||
@@ -29,6 +30,9 @@
|
||||
<RichTextLabel Name="DescriptionLabel" VerticalExpand="True" VerticalAlignment="Top" />
|
||||
</BoxContainer>
|
||||
</Control>
|
||||
|
||||
<chassisSpriteControls:ChassisSpriteSelection Name="ChassisSpriteSelection"/> <!-- CD change -->
|
||||
|
||||
<controls:ConfirmButton Name="ConfirmTypeButton" Text="{Loc 'borg-select-type-menu-confirm'}"
|
||||
Disabled="True" HorizontalAlignment="Right"
|
||||
MinWidth="200" />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Linq;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.UserInterface.Systems.Guidebook;
|
||||
using Content.Shared._CD.Silicons; // CosmicDrift
|
||||
using Content.Shared.Guidebook;
|
||||
using Content.Shared.Silicons.Borgs;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
@@ -29,6 +30,7 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
|
||||
private BorgTypePrototype? _selectedBorgType;
|
||||
|
||||
public event Action<ProtoId<BorgTypePrototype>>? ConfirmedBorgType;
|
||||
public event Action<EntityPrototype?>? ConfirmedBorgSubtype; // CosmicDrift event - borg subtypes
|
||||
|
||||
private static readonly List<ProtoId<GuideEntryPrototype>> GuidebookEntries = new() { "Cyborgs", "Robotics" };
|
||||
|
||||
@@ -56,6 +58,13 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
|
||||
|
||||
ConfirmTypeButton.OnPressed += ConfirmButtonPressed;
|
||||
HelpGuidebookIds = GuidebookEntries;
|
||||
|
||||
// Start CosmicDrift Changes - borg subtypes
|
||||
ChassisSpriteSelection.SubtypeSelected += () =>
|
||||
{
|
||||
ConfirmTypeButton.Disabled = false;
|
||||
};
|
||||
// End CosmicDrift Changes - borg subtypes
|
||||
}
|
||||
|
||||
private void UpdateInformation(BorgTypePrototype prototype)
|
||||
@@ -87,6 +96,14 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
|
||||
NameLabel.Text = PrototypeName(prototype);
|
||||
DescriptionLabel.Text = Loc.GetString($"borg-type-{prototype.ID}-desc");
|
||||
ChassisView.SetPrototype(prototype.DummyPrototype);
|
||||
|
||||
// Start CosmicDrift Changes - borg subtypes
|
||||
if (_selectedBorgType != null)
|
||||
{
|
||||
ConfirmTypeButton.Disabled = true;
|
||||
ChassisSpriteSelection.Update(_selectedBorgType);
|
||||
}
|
||||
// End CosmicDrift Changes - borg subtypes
|
||||
}
|
||||
|
||||
private void ConfirmButtonPressed(BaseButton.ButtonEventArgs obj)
|
||||
@@ -94,6 +111,7 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
|
||||
if (_selectedBorgType == null)
|
||||
return;
|
||||
|
||||
ConfirmedBorgSubtype?.Invoke(ChassisSpriteSelection.SubtypePrototype); // CosmicDrift
|
||||
ConfirmedBorgType?.Invoke(_selectedBorgType);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Content.Shared._CD.Silicons; // CosmicDrift
|
||||
using Content.Shared._CD.Silicons.Borgs; // CosmicDrift
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
@@ -26,5 +28,6 @@ public sealed class BorgSelectTypeUserInterface : BoundUserInterface
|
||||
|
||||
_menu = this.CreateWindow<BorgSelectTypeMenu>();
|
||||
_menu.ConfirmedBorgType += prototype => SendPredictedMessage(new BorgSelectTypeMessage(prototype));
|
||||
_menu.ConfirmedBorgSubtype += subtypePrototype => SendPredictedMessage(new BorgSelectSubtypeMessage(subtypePrototype?.ID)); // CosmicDrift - borg subtypes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using Content.Client.PDA; // DeltaV
|
||||
using Content.Client.PDA; // DeltaV
|
||||
using Content.Shared._CD.Silicons.Borgs; // CosmicDrift
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Silicons.Borgs;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Serialization; // DeltaV
|
||||
using Robust.Client.ResourceManagement; // CosmicDrift
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations; // CosmicDrift
|
||||
using Robust.Shared.Timing; // CosmicDrift
|
||||
|
||||
namespace Content.Client.Silicons.Borgs;
|
||||
|
||||
@@ -17,6 +20,7 @@ public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeS
|
||||
[Dependency] private readonly BorgSystem _borgSystem = default!;
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!; // CosmicDrift - borg subtypes
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -40,15 +44,20 @@ public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeS
|
||||
Entity<BorgSwitchableTypeComponent> entity,
|
||||
BorgTypePrototype prototype)
|
||||
{
|
||||
// Begin DeltaV Additions
|
||||
if (prototype.ClientComponents is {} add)
|
||||
EntityManager.AddComponents(entity, add);
|
||||
// End DeltaV Additions
|
||||
// Begin Afterlight Addition - added checks to stop sprite state errors
|
||||
if (!_timing.IsFirstTimePredicted)
|
||||
return;
|
||||
|
||||
if (TryComp<BorgSwitchableSubtypeComponent>(entity, out var subtype) &&
|
||||
subtype.BorgSubtype != null)
|
||||
{
|
||||
var ev = new TypeTryingToUpdateVisualsEvent();
|
||||
RaiseLocalEvent(entity, ref ev);
|
||||
return;
|
||||
}
|
||||
// End Afterlight Additions - added checks to stop sprite state errors
|
||||
if (TryComp(entity, out SpriteComponent? sprite))
|
||||
{
|
||||
// Begin DeltaV Additions - work around engine bug with AddComponents
|
||||
((ISerializationHooks) sprite).AfterDeserialization();
|
||||
// End DeltaV Additions
|
||||
_sprite.LayerSetRsiState((entity, sprite), BorgVisualLayers.Body, prototype.SpriteBodyState);
|
||||
_sprite.LayerSetRsiState((entity, sprite), BorgVisualLayers.LightStatus, prototype.SpriteToggleLightState);
|
||||
}
|
||||
@@ -76,6 +85,26 @@ public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeS
|
||||
}
|
||||
// DeltaV - borg pdas
|
||||
|
||||
// Start CosmicDrift Changes - borg subtypes
|
||||
if (prototype.SpriteBodyMovementState is { } movementState)
|
||||
{
|
||||
var spriteMovement = EnsureComp<SpriteMovementComponent>(entity);
|
||||
spriteMovement.NoMovementLayers.Clear();
|
||||
spriteMovement.NoMovementLayers["movement"] = new PrototypeLayerData
|
||||
{
|
||||
State = prototype.SpriteBodyState,
|
||||
};
|
||||
spriteMovement.MovementLayers.Clear();
|
||||
spriteMovement.MovementLayers["movement"] = new PrototypeLayerData
|
||||
{
|
||||
State = movementState,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
RemComp<SpriteMovementComponent>(entity);
|
||||
}
|
||||
// End CosmicDrift Changes - borg subtypes
|
||||
base.UpdateEntityAppearance(entity, prototype);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,11 @@
|
||||
<Control HorizontalExpand="True" />
|
||||
<Label Name="RecordContainerSpecies" Align="Right" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label Text="{Loc 'humanoid-profile-editor-cd-records-height'}"/>
|
||||
<Control HorizontalExpand="True" />
|
||||
<Label Name="RecordContainerHeight" Align="Right" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label Text="{Loc 'humanoid-profile-editor-cd-records-weight'}"/>
|
||||
<Control HorizontalExpand="True" />
|
||||
|
||||
@@ -325,7 +325,8 @@ public sealed partial class CharacterRecordViewer : FancyWindow
|
||||
RecordContainerJob.Text = record.JobTitle; /* At some point in the future we might want to display the icon */
|
||||
RecordContainerGender.Text = record.Gender.ToString();
|
||||
RecordContainerSpecies.Text = record.Species;
|
||||
RecordContainerWeight.Text = $"{cr.Weight} ({UnitConversion.GetImperialDisplayMass(cr.Weight)})";
|
||||
RecordContainerHeight.Text = cr.Height + " " + UnitConversion.GetImperialDisplayLength(cr.Height);
|
||||
RecordContainerWeight.Text = cr.Weight + " " + UnitConversion.GetImperialDisplayMass(cr.Weight);
|
||||
RecordContainerContactName.SetValue(cr.EmergencyContactName);
|
||||
|
||||
RecordContainerEmployment.Visible = false;
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="10">
|
||||
<!-- Height, Weight -->
|
||||
<GridContainer Columns="2">
|
||||
<BoxContainer HorizontalExpand="True" SeparationOverride="2">
|
||||
<Label Text="{Loc 'humanoid-profile-editor-cd-records-height'}" />
|
||||
<Control HorizontalExpand="True" MinSize="5 0" />
|
||||
<LineEdit Name="HeightEdit" HorizontalAlignment="Right" MinSize="60 0" />
|
||||
<Label Name="HeightImperialLabel" MinWidth="60" />
|
||||
</BoxContainer>
|
||||
<BoxContainer HorizontalExpand="True" SeparationOverride="2">
|
||||
<Label Text="{Loc 'humanoid-profile-editor-cd-records-weight'}" />
|
||||
<Control HorizontalExpand="True" MinSize="5 0" />
|
||||
|
||||
@@ -25,6 +25,14 @@ public sealed partial class RecordEditorGui : Control
|
||||
|
||||
#region General
|
||||
|
||||
HeightEdit.OnTextChanged += args =>
|
||||
{
|
||||
if (!int.TryParse(args.Text, out var newHeight))
|
||||
return;
|
||||
UpdateImperialHeight(newHeight);
|
||||
UpdateRecords(_records.WithHeight(newHeight));
|
||||
};
|
||||
|
||||
WeightEdit.OnTextChanged += args =>
|
||||
{
|
||||
if (!int.TryParse(args.Text, out var newWeight))
|
||||
@@ -120,6 +128,8 @@ public sealed partial class RecordEditorGui : Control
|
||||
|
||||
private void UpdateWidgets()
|
||||
{
|
||||
HeightEdit.SetText(_records.Height.ToString());
|
||||
UpdateImperialHeight(_records.Height);
|
||||
WeightEdit.SetText(_records.Weight.ToString());
|
||||
UpdateImperialWeight(_records.Weight);
|
||||
ContactNameEdit.SetText(_records.EmergencyContactName);
|
||||
@@ -133,8 +143,13 @@ public sealed partial class RecordEditorGui : Control
|
||||
PostmortemEdit.SetText(_records.PostmortemInstructions);
|
||||
}
|
||||
|
||||
private void UpdateImperialHeight(int newHeight)
|
||||
{
|
||||
HeightImperialLabel.Text = UnitConversion.GetImperialDisplayLength(newHeight);
|
||||
}
|
||||
|
||||
private void UpdateImperialWeight(int newWeight)
|
||||
{
|
||||
WeightImperialLabel.Text = $"({UnitConversion.GetImperialDisplayMass(newWeight)})";
|
||||
WeightImperialLabel.Text = UnitConversion.GetImperialDisplayMass(newWeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,47 +2,15 @@ namespace Content.Client._CD.Records.UI;
|
||||
|
||||
public static class UnitConversion
|
||||
{
|
||||
/// <summary>
|
||||
/// DeltaV - The average height of a human in centimeters. According to the US CDC, its
|
||||
/// 171 for men and 160 for women. So average of that is ~165cm.
|
||||
///
|
||||
/// Just kidding, we're going with EE's arbitrary standard of 175cm.
|
||||
/// </summary>
|
||||
private const int AVERAGE_HEIGHT_CM = 175;
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - 1.0 scale is considered average for humans, so a scale of 1 will be 175cm.
|
||||
/// Ensure that scale also includes the base species height AND the user-defined height.
|
||||
/// </summary>
|
||||
/// <param name="scale"></param>
|
||||
/// <returns></returns>
|
||||
private static int GetMetricHeightFromScale(float scale = 1)
|
||||
{
|
||||
// cast as int because we don't care about decimal
|
||||
return (int)Math.Max(scale * AVERAGE_HEIGHT_CM, 1); // can't be shorter than 1cm I guess
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - Gets nicely formatted string that contains both metric and imperial measurements.
|
||||
/// With a scale of 1, it should look like... 175cm (5' 9")
|
||||
/// </summary>
|
||||
/// <param name="scale"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetMetricAndImperialDisplayFromScale(float scale = 1)
|
||||
{
|
||||
var metricHeight = GetMetricHeightFromScale(scale);
|
||||
return $"{metricHeight}cm ({GetImperialDisplayLength(metricHeight)})";
|
||||
}
|
||||
|
||||
public static string GetImperialDisplayLength(int lengthCm)
|
||||
{
|
||||
var heightIn = (int)Math.Round(lengthCm * 0.3937007874 /* cm to in*/);
|
||||
return $"{heightIn / 12}'{heightIn % 12}\"";
|
||||
var heightIn = (int) Math.Round(lengthCm * 0.3937007874 /* cm to in*/);
|
||||
return $"({heightIn / 12}'{heightIn % 12}'')";
|
||||
}
|
||||
|
||||
public static string GetImperialDisplayMass(int massKg)
|
||||
{
|
||||
var weightLbs = (int)Math.Round(massKg * 2.2046226218 /* kg to lbs */);
|
||||
return $"{weightLbs} lbs";
|
||||
var weightLbs = (int) Math.Round(massKg * 2.2046226218 /* kg to lbs */);
|
||||
return $"({weightLbs} lbs)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
using System.Linq;
|
||||
using Content.Client.Silicons.Borgs;
|
||||
using Content.Shared._CD.Silicons.Borgs;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._CD.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Primarily handles the appearance aspects of the borg subtype.
|
||||
/// </summary>
|
||||
public sealed class BorgSwitchableSubtypeSystem : SharedBorgSwitchableSubtypeSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly BorgSystem _borg = default!;
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<BorgSwitchableSubtypeComponent, ComponentStartup>(OnComponentStartup);
|
||||
SubscribeLocalEvent<BorgSwitchableSubtypeComponent, AfterAutoHandleStateEvent>(OnAutoHandleEvent);
|
||||
}
|
||||
|
||||
private void OnAutoHandleEvent(Entity<BorgSwitchableSubtypeComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
SelectBorgSubtype(ent);
|
||||
}
|
||||
|
||||
private void OnComponentStartup(Entity<BorgSwitchableSubtypeComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
SelectBorgSubtype(ent);
|
||||
}
|
||||
|
||||
protected override void UpdateEntityAppearance(Entity<BorgSwitchableSubtypeComponent> entity, EntityPrototype borgSubtypePrototype)
|
||||
{
|
||||
// LOT of copy pasted code from BorgSwitchableTypeSystem, but is probably necessary unless the upstream code
|
||||
// is refactored
|
||||
|
||||
if (!borgSubtypePrototype.TryGetComponent<BorgSubtypeDefinitionComponent>(out var borgSubtype, ComponentFactory))
|
||||
return;
|
||||
|
||||
// get our required components
|
||||
var (owner, _) = entity;
|
||||
if (!TryComp<SpriteComponent>(entity, out var chassisSprite))
|
||||
return;
|
||||
|
||||
// remove all existing layers
|
||||
for (int i = chassisSprite.AllLayers.Count() - 1; i >= 0; i--)
|
||||
{
|
||||
_sprite.RemoveLayer((entity, chassisSprite), i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < borgSubtype.LayerData.Length; i++)
|
||||
{
|
||||
var layerData = borgSubtype.LayerData[i];
|
||||
|
||||
layerData.RsiPath = borgSubtype.SpritePath?.ToString();
|
||||
if (borgSubtype.Offset != null)
|
||||
layerData.Offset = borgSubtype.Offset;
|
||||
_sprite.AddLayer((owner, chassisSprite), layerData, i);
|
||||
}
|
||||
|
||||
if (TryComp<BorgChassisComponent>(entity, out var chassis))
|
||||
{
|
||||
_borg.SetMindStates(
|
||||
(entity.Owner, chassis),
|
||||
borgSubtype.SpriteHasMindState,
|
||||
borgSubtype.SpriteNoMindState);
|
||||
|
||||
if (TryComp(entity, out AppearanceComponent? appearance))
|
||||
{
|
||||
// Queue update so state changes apply.
|
||||
_appearance.QueueUpdate(entity, appearance);
|
||||
}
|
||||
}
|
||||
|
||||
if (borgSubtype.SpriteBodyMovementState is { } movementState)
|
||||
{
|
||||
var spriteMovement = EnsureComp<SpriteMovementComponent>(entity);
|
||||
spriteMovement.NoMovementLayers.Clear();
|
||||
spriteMovement.NoMovementLayers["movement"] = new PrototypeLayerData
|
||||
{
|
||||
State = borgSubtype.SpriteBodyState,
|
||||
};
|
||||
spriteMovement.MovementLayers.Clear();
|
||||
spriteMovement.MovementLayers["movement"] = new PrototypeLayerData
|
||||
{
|
||||
State = movementState,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
RemComp<SpriteMovementComponent>(entity);
|
||||
}
|
||||
|
||||
base.UpdateEntityAppearance(entity, borgSubtypePrototype);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<Control xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls">
|
||||
<BoxContainer Name="MainContainer"
|
||||
Orientation="Vertical"
|
||||
SeparationOverride="4"
|
||||
Visible="False">
|
||||
<controls:StripeBack>
|
||||
<Label Text="{Loc 'cd-borg-select-subtype-flavour-text'}"
|
||||
StyleClasses="LabelSubText"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0 12"/>
|
||||
</controls:StripeBack>
|
||||
<ScrollContainer Name="OptionsScrollContainer"
|
||||
HScrollEnabled="True"
|
||||
VScrollEnabled="False"
|
||||
MinHeight="96">
|
||||
<BoxContainer Name="OptionsContainer"
|
||||
Orientation="Horizontal"
|
||||
SeparationOverride="4"/>
|
||||
</ScrollContainer>
|
||||
|
||||
</BoxContainer>
|
||||
</Control>
|
||||
@@ -0,0 +1,99 @@
|
||||
using Content.Shared.Silicons.Borgs;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._CD.Silicons.Borgs.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ChassisSpriteSelection : Control
|
||||
{
|
||||
[Dependency] private readonly IComponentFactory _componentFactory = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
public EntityPrototype? SubtypePrototype;
|
||||
public event Action? SubtypeSelected;
|
||||
|
||||
private const int PrototypeViewSize = 2;
|
||||
private static readonly ProtoId<EntityCategoryPrototype> _borgSubtypeCategory = "BorgSubtype";
|
||||
|
||||
public ChassisSpriteSelection()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
public void Update(BorgTypePrototype borgTypePrototype)
|
||||
{
|
||||
MainContainer.Visible = true;
|
||||
|
||||
OptionsContainer.RemoveAllChildren();
|
||||
|
||||
var buttonGroup = new ButtonGroup();
|
||||
List<Button> buttons = new List<Button>();
|
||||
buttons.Add(CreateDefaultSubtypeButton(borgTypePrototype, buttonGroup));
|
||||
|
||||
foreach (var ent in _prototype.Categories.GetValueRefOrNullRef(_borgSubtypeCategory))
|
||||
{
|
||||
if (!ent.TryGetComponent<Shared._CD.Silicons.Borgs.BorgSubtypeDefinitionComponent>(out var subtype, _componentFactory))
|
||||
continue;
|
||||
|
||||
// Only add subtypes of the current selected 'main' borg type (engineering, medical, etc.)
|
||||
if (subtype.ParentType != borgTypePrototype.ID)
|
||||
continue;
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
ToolTip = Loc.GetString($"al-borg-{borgTypePrototype.ID}-subtype-{ent.Name.Replace(' ', '-').ToLower()}-name"),
|
||||
Group = buttonGroup,
|
||||
MinHeight = 32,
|
||||
};
|
||||
|
||||
button.OnPressed += _ =>
|
||||
{
|
||||
SubtypePrototype = ent;
|
||||
SubtypeSelected?.Invoke();
|
||||
};
|
||||
|
||||
button.AddChild(CreateEntityPrototypeView(subtype.DummyPrototype));
|
||||
buttons.Add(button);
|
||||
}
|
||||
|
||||
foreach (var button in buttons)
|
||||
{
|
||||
OptionsContainer.AddChild(button);
|
||||
}
|
||||
}
|
||||
|
||||
private Button CreateDefaultSubtypeButton(BorgTypePrototype borgTypePrototype, ButtonGroup group)
|
||||
{
|
||||
var button = new Button
|
||||
{
|
||||
ToolTip = "default",
|
||||
Group = group,
|
||||
MinHeight = 32,
|
||||
};
|
||||
|
||||
button.OnPressed += _ =>
|
||||
{
|
||||
SubtypePrototype = null;
|
||||
SubtypeSelected?.Invoke();
|
||||
};
|
||||
|
||||
button.AddChild(CreateEntityPrototypeView(borgTypePrototype.DummyPrototype));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private EntityPrototypeView CreateEntityPrototypeView(EntProtoId entProtoId)
|
||||
{
|
||||
var entPrototypeView = new EntityPrototypeView();
|
||||
|
||||
entPrototypeView.SetPrototype(entProtoId);
|
||||
entPrototypeView.Scale *= PrototypeViewSize;
|
||||
|
||||
return entPrototypeView;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
using System.Linq;
|
||||
using Content.Shared._DV.Forensics;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._DV.Forensics;
|
||||
|
||||
public sealed class DVItemSlotVisualsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
|
||||
private static readonly ResPath TextureRoot = new("/Textures");
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DVItemSlotVisualsComponent, EntInsertedIntoContainerMessage>(OnInsertedIntoContainer);
|
||||
SubscribeLocalEvent<DVItemSlotVisualsComponent, EntRemovedFromContainerMessage>(OnRemovedFromContainer);
|
||||
}
|
||||
|
||||
private void RefreshVisuals(Entity<DVItemSlotVisualsComponent> ent)
|
||||
{
|
||||
var slot = _container.EnsureContainer<ContainerSlot>(ent, ent.Comp.ItemSlot);
|
||||
if (slot.ContainedEntity is { } contained)
|
||||
{
|
||||
_sprite.CopySprite(contained, ent.Owner);
|
||||
_sprite.AddLayer(ent.Owner, ent.Comp.FilledSprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sprite = Comp<SpriteComponent>(ent);
|
||||
var count = sprite.AllLayers.Count();
|
||||
for (var i = count - 1; i >= 0; i--)
|
||||
{
|
||||
_sprite.RemoveLayer((ent, sprite), i);
|
||||
}
|
||||
|
||||
if (ent.Comp.UnfilledSprite is not SpriteSpecifier.Rsi rsi)
|
||||
{
|
||||
throw new InvalidOperationException($"{ToPrettyString(ent)} has an unfilled sprite that's not an RSI");
|
||||
}
|
||||
|
||||
if (!_resourceCache.TryGetResource<RSIResource>(TextureRoot / rsi.RsiPath, out var res))
|
||||
{
|
||||
throw new InvalidOperationException($"{ToPrettyString(ent)} has invalid RSI: {TextureRoot / rsi.RsiPath}");
|
||||
}
|
||||
|
||||
_sprite.SetBaseRsi(ent.Owner, res.RSI);
|
||||
_sprite.AddLayer(ent.Owner, ent.Comp.UnfilledSprite);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInsertedIntoContainer(Entity<DVItemSlotVisualsComponent> ent, ref EntInsertedIntoContainerMessage args)
|
||||
{
|
||||
if (args.Container.ID != ent.Comp.ItemSlot)
|
||||
return;
|
||||
|
||||
RefreshVisuals(ent);
|
||||
}
|
||||
|
||||
private void OnRemovedFromContainer(Entity<DVItemSlotVisualsComponent> ent, ref EntRemovedFromContainerMessage args)
|
||||
{
|
||||
if (args.Container.ID != ent.Comp.ItemSlot)
|
||||
return;
|
||||
|
||||
RefreshVisuals(ent);
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
using System.Numerics;
|
||||
using Content.Client.Graphics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._DV.Overlays;
|
||||
|
||||
/// <summary>
|
||||
/// Makes darkness visible, and bright lights painfully visible
|
||||
/// Tweakable. Algo is max((light*gain)^exp, lightFloor)
|
||||
/// </summary>
|
||||
public sealed class DarkVisionOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IClyde _clyde = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowWorld;
|
||||
|
||||
private readonly ProtoId<ShaderPrototype> _shaderProto = "DarkVision";
|
||||
|
||||
public float LightFloor = 0.5f;
|
||||
public float LightGain = 2f;
|
||||
public float LightExp = 1f;
|
||||
|
||||
private readonly ShaderInstance _copyShader;
|
||||
private readonly ShaderInstance _remapShader;
|
||||
private readonly OverlayResourceCache<CachedResources> _resources = new();
|
||||
|
||||
public DarkVisionOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
var proto = _prototype.Index<ShaderPrototype>(_shaderProto);
|
||||
_remapShader = proto.InstanceUnique();
|
||||
// With floor 0, gain 1, exp 1 the shader is an exact blend-mode-none copy.
|
||||
_copyShader = proto.InstanceUnique();
|
||||
_copyShader.SetParameter("lightFloor", 0f);
|
||||
_copyShader.SetParameter("lightGain", 1f);
|
||||
_copyShader.SetParameter("lightExp", 1f);
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
var viewport = args.Viewport;
|
||||
var worldHandle = args.WorldHandle;
|
||||
|
||||
if (viewport.Eye == null)
|
||||
return;
|
||||
|
||||
var lightTarget = viewport.LightRenderTarget;
|
||||
var res = _resources.GetForViewport(viewport, static _ => new CachedResources());
|
||||
|
||||
if (res.ScratchTarget?.Size != lightTarget.Size)
|
||||
{
|
||||
res.ScratchTarget?.Dispose();
|
||||
res.ScratchTarget = _clyde.CreateLightRenderTarget(lightTarget.Size, "darkvision-scratch", depthStencil: false);
|
||||
}
|
||||
|
||||
var bounds = args.WorldBounds;
|
||||
var lightScale = lightTarget.Size / (Vector2) viewport.Size;
|
||||
var scale = viewport.RenderScale / (Vector2.One / lightScale);
|
||||
var localMatrix = lightTarget.GetWorldToLocalMatrix(viewport.Eye, scale);
|
||||
|
||||
// Copy the light buffer aside first: a texture can't be sampled while it is also the
|
||||
// render target being drawn into.
|
||||
worldHandle.RenderInRenderTarget(res.ScratchTarget, () =>
|
||||
{
|
||||
worldHandle.UseShader(_copyShader);
|
||||
worldHandle.SetTransform(localMatrix);
|
||||
worldHandle.DrawTextureRect(lightTarget.Texture, bounds);
|
||||
worldHandle.UseShader(null);
|
||||
}, Color.Black);
|
||||
|
||||
// Then write it back through the remap.
|
||||
_remapShader.SetParameter("lightFloor", LightFloor);
|
||||
_remapShader.SetParameter("lightGain", LightGain);
|
||||
_remapShader.SetParameter("lightExp", LightExp);
|
||||
worldHandle.RenderInRenderTarget(lightTarget, () =>
|
||||
{
|
||||
worldHandle.UseShader(_remapShader);
|
||||
worldHandle.SetTransform(localMatrix);
|
||||
worldHandle.DrawTextureRect(res.ScratchTarget.Texture, bounds);
|
||||
worldHandle.UseShader(null);
|
||||
}, null);
|
||||
}
|
||||
|
||||
protected override void DisposeBehavior()
|
||||
{
|
||||
_resources.Dispose();
|
||||
|
||||
base.DisposeBehavior();
|
||||
}
|
||||
|
||||
private sealed class CachedResources : IDisposable
|
||||
{
|
||||
public IRenderTexture? ScratchTarget;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ScratchTarget?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
using Content.Shared._DV.Overlays.Components;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Client._DV.Overlays;
|
||||
|
||||
public sealed class DarkVisionSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||
[Dependency] private readonly ISharedPlayerManager _playerMan = default!;
|
||||
|
||||
private DarkVisionOverlay _overlay = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DarkVisionComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<DarkVisionComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<DarkVisionComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
|
||||
SubscribeLocalEvent<DarkVisionComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
|
||||
|
||||
_overlay = new();
|
||||
}
|
||||
|
||||
private void OnInit(Entity<DarkVisionComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
if (ent.Owner == _playerMan.LocalEntity)
|
||||
EnableOverlay(ent.Comp);
|
||||
}
|
||||
|
||||
private void OnShutdown(Entity<DarkVisionComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
if (ent.Owner == _playerMan.LocalEntity)
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void OnPlayerAttached(Entity<DarkVisionComponent> ent, ref LocalPlayerAttachedEvent args)
|
||||
{
|
||||
EnableOverlay(ent.Comp);
|
||||
}
|
||||
|
||||
private void OnPlayerDetached(Entity<DarkVisionComponent> ent, ref LocalPlayerDetachedEvent args)
|
||||
{
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void EnableOverlay(DarkVisionComponent comp)
|
||||
{
|
||||
_overlay.LightFloor = comp.LightFloor;
|
||||
_overlay.LightGain = comp.LightGain;
|
||||
_overlay.LightExp = comp.LightExp;
|
||||
if (!_overlayMan.HasOverlay<DarkVisionOverlay>())
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
using Content.Shared._DV.Silicons;
|
||||
|
||||
namespace Content.Client._DV.Silicons;
|
||||
|
||||
public sealed class SiliconEmpSystem : SharedSiliconEmpSystem;
|
||||
@@ -1,71 +0,0 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._Floof.OfferItem;
|
||||
|
||||
public sealed class OfferItemIndicatorsOverlay : Overlay
|
||||
{
|
||||
private readonly IInputManager _inputManager;
|
||||
private readonly IEntityManager _entMan;
|
||||
private readonly IEyeManager _eye;
|
||||
private readonly OfferItemSystem _offer;
|
||||
|
||||
private readonly Texture _sight;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
|
||||
|
||||
private readonly Color _mainColor = Color.White.WithAlpha(0.3f);
|
||||
private readonly Color _strokeColor = Color.Black.WithAlpha(0.5f);
|
||||
private readonly float _scale = 0.6f; // 1 is a little big
|
||||
|
||||
public OfferItemIndicatorsOverlay(IInputManager input, IEntityManager entMan,
|
||||
IEyeManager eye, OfferItemSystem offerSys)
|
||||
{
|
||||
_inputManager = input;
|
||||
_entMan = entMan;
|
||||
_eye = eye;
|
||||
_offer = offerSys;
|
||||
|
||||
var spriteSys = _entMan.EntitySysManager.GetEntitySystem<SpriteSystem>();
|
||||
_sight = spriteSys.Frame0(new SpriteSpecifier.Rsi(new("/Textures/_Floof/Interface/Misc/give_item.rsi"), "give_item"));
|
||||
}
|
||||
|
||||
protected override bool BeforeDraw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (!_offer.IsInOfferMode())
|
||||
return false;
|
||||
|
||||
return base.BeforeDraw(in args);
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
var mouseScreenPosition = _inputManager.MouseScreenPosition;
|
||||
var mousePosMap = _eye.PixelToMap(mouseScreenPosition);
|
||||
if (mousePosMap.MapId != args.MapId)
|
||||
return;
|
||||
|
||||
|
||||
var mousePos = mouseScreenPosition.Position;
|
||||
var uiScale = (args.ViewportControl as Control)?.UIScale ?? 1f;
|
||||
var limitedScale = uiScale > 1.25f ? 1.25f : uiScale;
|
||||
|
||||
DrawSight(_sight, args.ScreenHandle, mousePos, limitedScale * _scale);
|
||||
}
|
||||
|
||||
private void DrawSight(Texture sight, DrawingHandleScreen screen, Vector2 centerPos, float scale)
|
||||
{
|
||||
var sightSize = sight.Size * scale;
|
||||
var expandedSize = sightSize + new Vector2(7f, 7f);
|
||||
|
||||
screen.DrawTextureRect(sight,
|
||||
UIBox2.FromDimensions(centerPos - sightSize * 0.5f, sightSize), _strokeColor);
|
||||
screen.DrawTextureRect(sight,
|
||||
UIBox2.FromDimensions(centerPos - expandedSize * 0.5f, expandedSize), _mainColor);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using Content.Shared._Floof.OfferItem;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Player;
|
||||
|
||||
namespace Content.Client._Floof.OfferItem;
|
||||
|
||||
public sealed class OfferItemSystem : SharedOfferItemSystem
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||
[Dependency] private readonly IEyeManager _eye = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_overlayManager.AddOverlay(new OfferItemIndicatorsOverlay(
|
||||
_inputManager,
|
||||
EntityManager,
|
||||
_eye,
|
||||
this));
|
||||
}
|
||||
public override void Shutdown()
|
||||
{
|
||||
_overlayManager.RemoveOverlay<OfferItemIndicatorsOverlay>();
|
||||
base.Shutdown();
|
||||
}
|
||||
|
||||
public bool IsInOfferMode()
|
||||
{
|
||||
var entity = _playerManager.LocalEntity;
|
||||
|
||||
if (entity == null)
|
||||
return false;
|
||||
|
||||
return IsInOfferMode(entity.Value);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Shared._DV.Administration.Components; // DeltaV - Unorbitable
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -7,7 +6,7 @@ using Robust.Shared.Utility;
|
||||
namespace Content.Server.Administration.Commands;
|
||||
|
||||
[AdminCommand(AdminFlags.Stealth)]
|
||||
public sealed class StealthminCommand : LocalizedEntityCommands // DeltaV - Unorbitable, LocalizedCommands to LocalizedEntityCommands
|
||||
public sealed class StealthminCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
|
||||
@@ -27,20 +26,8 @@ public sealed class StealthminCommand : LocalizedEntityCommands // DeltaV - Unor
|
||||
DebugTools.AssertNotNull(adminData);
|
||||
|
||||
if (!adminData!.Stealth)
|
||||
{
|
||||
_adminManager.Stealth(player);
|
||||
// DeltaV - Unorbitable START
|
||||
if (player.AttachedEntity is { } attachedEntity)
|
||||
EntityManager.EnsureComponent<UnorbitableComponent>(attachedEntity);
|
||||
// DeltaV END
|
||||
}
|
||||
else
|
||||
{
|
||||
_adminManager.UnStealth(player);
|
||||
// DeltaV - Unorbitable START
|
||||
if (player.AttachedEntity is { } attachedEntity)
|
||||
EntityManager.RemoveComponent<UnorbitableComponent>(attachedEntity);
|
||||
// DeltaV END
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Server.Access.Systems; // DeltaV
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.NameIdentifier;
|
||||
using Content.Shared.Access.Components;
|
||||
@@ -21,7 +20,6 @@ using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Shared._DV.Cargo.Components; // DeltaV: Bounty claim messages
|
||||
|
||||
namespace Content.Server.Cargo.Systems;
|
||||
|
||||
@@ -30,7 +28,6 @@ public sealed partial class CargoSystem
|
||||
[Dependency] private readonly ContainerSystem _container = default!;
|
||||
[Dependency] private readonly NameIdentifierSystem _nameIdentifier = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSys = default!;
|
||||
[Dependency] private readonly IdCardSystem _idCard = default!; // DeltaV
|
||||
|
||||
private static readonly ProtoId<NameIdentifierGroupPrototype> BountyNameIdentifierGroup = "Bounty";
|
||||
|
||||
@@ -43,8 +40,6 @@ public sealed partial class CargoSystem
|
||||
SubscribeLocalEvent<CargoBountyConsoleComponent, BoundUIOpenedEvent>(OnBountyConsoleOpened);
|
||||
SubscribeLocalEvent<CargoBountyConsoleComponent, BountyPrintLabelMessage>(OnPrintLabelMessage);
|
||||
SubscribeLocalEvent<CargoBountyConsoleComponent, BountySkipMessage>(OnSkipBountyMessage);
|
||||
SubscribeLocalEvent<CargoBountyConsoleComponent, BountyClaimedMessage>(OnBountyClaimedMessage); // DeltaV
|
||||
SubscribeLocalEvent<CargoBountyConsoleComponent, BountySetStatusMessage>(OnSetBountyStatusMessage); // DeltaV
|
||||
SubscribeLocalEvent<CargoBountyLabelComponent, PriceCalculationEvent>(OnGetBountyPrice);
|
||||
SubscribeLocalEvent<EntitySoldEvent>(OnSold);
|
||||
SubscribeLocalEvent<StationCargoBountyDatabaseComponent, MapInitEvent>(OnMapInit);
|
||||
@@ -116,72 +111,6 @@ public sealed partial class CargoSystem
|
||||
_audio.PlayPvs(component.SkipSound, uid);
|
||||
}
|
||||
|
||||
// Begin DeltaV bounty claim system
|
||||
private void OnSetBountyStatusMessage(Entity<CargoBountyConsoleComponent> ent, ref BountySetStatusMessage args)
|
||||
{
|
||||
if (_station.GetOwningStation(ent.Owner) is not { } station || !TryComp<StationCargoBountyDatabaseComponent>(station, out var bountyDbComp))
|
||||
return;
|
||||
|
||||
for (var i = 0; i < bountyDbComp.Bounties.Count; i++)
|
||||
{
|
||||
var bounty = bountyDbComp.Bounties[i];
|
||||
|
||||
if (bounty.Id != args.BountyId)
|
||||
continue;
|
||||
|
||||
var newData = new CargoBountyData
|
||||
{
|
||||
Id = bounty.Id,
|
||||
Bounty = bounty.Bounty,
|
||||
ClaimedBy = bounty.ClaimedBy,
|
||||
Status = (CargoBountyStatus)args.Status,
|
||||
};
|
||||
|
||||
bountyDbComp.Bounties[i] = newData;
|
||||
}
|
||||
|
||||
var untilNextSkip = bountyDbComp.NextSkipTime - Timing.CurTime;
|
||||
_uiSystem.SetUiState(ent.Owner, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(bountyDbComp.Bounties, bountyDbComp.History, untilNextSkip));
|
||||
}
|
||||
|
||||
private void OnBountyClaimedMessage(Entity<CargoBountyConsoleComponent> ent, ref BountyClaimedMessage args)
|
||||
{
|
||||
if (_station.GetOwningStation(ent.Owner) is not { } station || !TryComp<StationCargoBountyDatabaseComponent>(station, out var bountyDbComp))
|
||||
return;
|
||||
|
||||
for (var i = 0; i < bountyDbComp.Bounties.Count; i++)
|
||||
{
|
||||
var bounty = bountyDbComp.Bounties[i];
|
||||
|
||||
if (bounty.Id != args.BountyId)
|
||||
continue;
|
||||
|
||||
string name;
|
||||
if (_idCard.TryFindIdCard(args.Actor, out var idCard) && idCard.Comp.FullName != null)
|
||||
{
|
||||
name = idCard.Comp.FullName;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = Loc.GetString("bounty-console-claimed-by-unknown");
|
||||
}
|
||||
|
||||
var newData = new CargoBountyData
|
||||
{
|
||||
Id = bounty.Id,
|
||||
Bounty = bounty.Bounty,
|
||||
ClaimedBy = name.Equals(bounty.ClaimedBy) ? string.Empty : name,
|
||||
Status = bounty.Status,
|
||||
};
|
||||
|
||||
bountyDbComp.Bounties[i] = newData;
|
||||
}
|
||||
|
||||
var untilNextSkip = bountyDbComp.NextSkipTime - Timing.CurTime;
|
||||
_uiSystem.SetUiState(ent.Owner, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(bountyDbComp.Bounties, bountyDbComp.History, untilNextSkip));
|
||||
}
|
||||
// End DeltaV bounty claim system
|
||||
|
||||
public void SetupBountyLabel(EntityUid uid, EntityUid stationId, CargoBountyData bounty, PaperComponent? paper = null, CargoBountyLabelComponent? label = null)
|
||||
{
|
||||
if (!Resolve(uid, ref paper, ref label) || !_protoMan.Resolve<CargoBountyPrototype>(bounty.Bounty, out var prototype))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.Explosion.EntitySystems;
|
||||
using Content.Shared.Damage; // DeltaV - EMP damage
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Radio;
|
||||
using Content.Server.SurveillanceCamera;
|
||||
|
||||
@@ -23,7 +23,6 @@ using Robust.Shared.Timing;
|
||||
using System.Linq;
|
||||
using Content.Shared.EntityEffects.Effects.Solution;
|
||||
using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent;
|
||||
using Content.Server.Body.Components; // Delta V
|
||||
|
||||
namespace Content.Server.Fluids.EntitySystems;
|
||||
|
||||
@@ -268,8 +267,7 @@ public sealed class SmokeSystem : EntitySystem
|
||||
if (!_solutionContainerSystem.ResolveSolution(entity, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution) || bloodSolution.AvailableVolume <= 0)
|
||||
return;
|
||||
|
||||
var blockIngestion = _internals.AreInternalsWorking(entity)
|
||||
|| !HasComp<RespiratorComponent>(entity); // Starlight - Shadekin does not breathe and "AreInternalsWorking" does not check for that
|
||||
var blockIngestion = _internals.AreInternalsWorking(entity);
|
||||
|
||||
var cloneSolution = solution.Clone();
|
||||
var availableTransfer = FixedPoint2.Min(cloneSolution.Volume, component.TransferRate);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Server.RoundEnd; // DeltaV
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules.Components;
|
||||
@@ -44,16 +43,4 @@ public sealed partial class XenoborgsRuleComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool XenoborgShuttleCalled = false;
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - The behavior of the round if the mothership core is deleted.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public RoundEndBehavior XenoborgRoundEndBehavior = RoundEndBehavior.BecomeSurvival;
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - The amount of time before the evac shuttle will arrive if the XenoborgRoundEndBehavior is set to ShuttleCall.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan XenoborgShuttleDelay = TimeSpan.FromMinutes(10);
|
||||
}
|
||||
|
||||
@@ -30,20 +30,10 @@ public sealed partial class ZombieRuleComponent : Component
|
||||
/// <summary>
|
||||
/// DeltaV - The behavior of the round if all zombies are defeated.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public RoundEndBehavior ZombieRoundEndBehavior = RoundEndBehavior.BecomeSurvival;
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - The amount of time before the evac shuttle will arrive if the ZombieRoundEndBehavior is set to ShuttleCall.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan ZombieShuttleDelay = TimeSpan.FromMinutes(10);
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - If true, ZombieRuleSystem will do the ZombieRoundEndBehavior if zombies are defeated.
|
||||
/// This is needed because ZombieOutbreak uses the ZombieRuleComponent but the system won't know if
|
||||
/// it was roundstart or not.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool IsRoundStartZombies = false;
|
||||
}
|
||||
|
||||
@@ -520,17 +520,18 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
|
||||
// BEGIN DeltaV - Detect Nukie Failure Better
|
||||
// We need to use a EntityQueryEnumerator instead of a EntityQuery, because we need the uid to check for cuffs
|
||||
var operatives = new List<Entity<NukeOperativeComponent, MobStateComponent>>();
|
||||
var operativesEnumerator = EntityQueryEnumerator<NukeOperativeComponent, MobStateComponent>();
|
||||
while (operativesEnumerator.MoveNext(out var uid, out var nukeOp, out var mobState))
|
||||
var operatives = new List<Entity<NukeOperativeComponent, MobStateComponent, TransformComponent>>();
|
||||
var operativesEnumerator = EntityQueryEnumerator<NukeOperativeComponent, MobStateComponent, TransformComponent>();
|
||||
while (operativesEnumerator.MoveNext(out var uid, out var nukeOp, out var mobState, out var transform))
|
||||
{
|
||||
operatives.Add((uid, nukeOp, mobState));
|
||||
operatives.Add((uid, nukeOp, mobState, transform));
|
||||
}
|
||||
|
||||
var operativesAlive = operatives
|
||||
.Any(op => op.Comp1.Running
|
||||
&& op.Comp2.CurrentState == MobState.Alive
|
||||
&& TryComp<CuffableComponent>(op, out var cuffable) && cuffable.CuffedHandCount == 0); // in the case the crew keeps one alive
|
||||
.Where(op => op.Comp3.MapID == shuttleMapId
|
||||
|| op.Comp3.MapID == targetStationMap)
|
||||
.Any(op => op.Comp2.CurrentState == MobState.Alive && op.Comp1.Running &&
|
||||
!TryComp<CuffableComponent>(op, out _)); // in the case the crew keeps one alive
|
||||
// END DeltaV
|
||||
|
||||
if (operativesAlive)
|
||||
|
||||
@@ -42,14 +42,6 @@ public sealed class XenoborgsRuleSystem : GameRuleSystem<XenoborgsRuleComponent>
|
||||
colorOverride: AnnouncmentColor);
|
||||
|
||||
ent.Comp.MothershipCoreDeathAnnouncmentSent = true;
|
||||
|
||||
// BEGIN DeltaV - Convert to Survival
|
||||
if (ent.Comp.XenoborgRoundEndBehavior != RoundEndBehavior.Nothing)
|
||||
{
|
||||
_roundEnd.DoRoundEndBehavior(ent.Comp.XenoborgRoundEndBehavior, ent.Comp.XenoborgShuttleDelay);
|
||||
ent.Comp.XenoborgRoundEndBehavior = RoundEndBehavior.Nothing;
|
||||
}
|
||||
// END DeltaV
|
||||
}
|
||||
|
||||
// TODO: Refactor the end of round text
|
||||
|
||||
@@ -18,7 +18,6 @@ using Content.Shared.Zombies;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
using System.Globalization;
|
||||
using System.Linq; // DeltaV
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
@@ -115,34 +114,27 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
|
||||
/// </summary>
|
||||
private void CheckRoundEnd(ZombieRuleComponent zombieRuleComponent)
|
||||
{
|
||||
// BEGIN DeltaV - Change mode to survival if zombies die
|
||||
// Zombies have failed to launch and the mode has been switched to survival
|
||||
if (zombieRuleComponent.ZombieRoundEndBehavior == RoundEndBehavior.Nothing)
|
||||
return;
|
||||
// END DeltaV
|
||||
|
||||
var healthy = GetHealthyHumans();
|
||||
if (healthy.Count == 1) // Only one human left. spooky
|
||||
_popup.PopupEntity(Loc.GetString("zombie-alone"), healthy[0], healthy[0]);
|
||||
|
||||
|
||||
// BEGIN DeltaV - Change mode to survival if zombies die
|
||||
if (zombieRuleComponent.IsRoundStartZombies)
|
||||
var infectedPercent = GetInfectedFraction(false);
|
||||
if (Math.Round(infectedPercent, 0) == 0) // All zombies defeated
|
||||
{
|
||||
// Zombies have failed to launch and the mode has been switched to survival
|
||||
if (zombieRuleComponent.ZombieRoundEndBehavior == RoundEndBehavior.Nothing)
|
||||
return;
|
||||
|
||||
// BEGIN DeltaV - Change mode to survival if zombies die
|
||||
var anyInitialInfectedAlive = EntityQuery<InitialInfectedComponent, MobStateComponent>(false)
|
||||
.Any(x => x.Item2.CurrentState != MobState.Dead);
|
||||
var anyLivingZombies = EntityQuery<ZombieComponent, MobStateComponent>(false)
|
||||
.Any(x => x.Item2.CurrentState != MobState.Dead);
|
||||
var anyPendingZombies = EntityQuery<PendingZombieComponent>(false).Any();
|
||||
|
||||
// All II turned/dead, all entities that have turned are dead, and there are no more pending zombies
|
||||
if (!anyInitialInfectedAlive && !anyLivingZombies && !anyPendingZombies)
|
||||
{
|
||||
_roundEnd.DoRoundEndBehavior(zombieRuleComponent.ZombieRoundEndBehavior, zombieRuleComponent.ZombieShuttleDelay);
|
||||
zombieRuleComponent.ZombieRoundEndBehavior = RoundEndBehavior.Nothing; // stop this check in the future
|
||||
}
|
||||
_roundEnd.DoRoundEndBehavior(zombieRuleComponent.ZombieRoundEndBehavior, zombieRuleComponent.ZombieShuttleDelay);
|
||||
zombieRuleComponent.ZombieRoundEndBehavior = RoundEndBehavior.Nothing; // stop this check in the future
|
||||
}
|
||||
// END DeltaV
|
||||
|
||||
if (GetInfectedFraction(false) > zombieRuleComponent.ZombieShuttleCallPercentage && !_roundEnd.IsRoundEndRequested())
|
||||
if (infectedPercent > zombieRuleComponent.ZombieShuttleCallPercentage && !_roundEnd.IsRoundEndRequested()) // DeltaV - Move GetInfectedFraction to var
|
||||
{
|
||||
foreach (var station in _station.GetStations())
|
||||
{
|
||||
|
||||
@@ -29,7 +29,6 @@ using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.NameModifier.EntitySystems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Server.Preferences.Managers; // DeltaV
|
||||
using Content.Shared._DV.Administration.EntitySystems; // DeltaV - Unorbitable
|
||||
using Content.Shared.Storage.Components;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Warps;
|
||||
@@ -42,7 +41,6 @@ using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Server.Mobs; // Starlight
|
||||
|
||||
namespace Content.Server.Ghost
|
||||
{
|
||||
@@ -76,7 +74,6 @@ namespace Content.Server.Ghost
|
||||
[Dependency] private readonly GhostSpriteStateSystem _ghostState = default!;
|
||||
[Dependency] private readonly IServerPreferencesManager _preferencesManager = default!; // DeltaV
|
||||
[Dependency] private readonly IAdminManager _admin = default!; // DeltaV
|
||||
[Dependency] private readonly UnorbitableSystem _unorbitable = default!; // DeltaV - Unorbitable
|
||||
|
||||
private EntityQuery<GhostComponent> _ghostQuery;
|
||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||
@@ -343,11 +340,6 @@ namespace Content.Server.Ghost
|
||||
return;
|
||||
}
|
||||
|
||||
// DeltaV - Unorbitable START
|
||||
if (!_unorbitable.CanFollow(attached, realTarget))
|
||||
return;
|
||||
// DeltaV END
|
||||
|
||||
WarpTo(attached, realTarget);
|
||||
}
|
||||
|
||||
@@ -627,15 +619,7 @@ namespace Content.Server.Ghost
|
||||
_damageable.GetTotalDamage((playerEntity.Value, damageable));
|
||||
}
|
||||
|
||||
// Starlight - Start
|
||||
//DamageSpecifier damage = new(_prototypeManager.Index(AsphyxiationDamageType), dealtDamage);
|
||||
|
||||
var damageType = _prototypeManager.Index(AsphyxiationDamageType);
|
||||
if (TryComp<DeathgaspComponent>(playerEntity, out var deathgasp))
|
||||
damageType = _prototypeManager.Index(deathgasp.DamageType);
|
||||
|
||||
DamageSpecifier damage = new(damageType, dealtDamage);
|
||||
// Starlight - End
|
||||
DamageSpecifier damage = new(_prototypeManager.Index(AsphyxiationDamageType), dealtDamage);
|
||||
|
||||
_damageable.ChangeDamage(playerEntity.Value, damage, true);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ using Content.Server.Body.Systems;
|
||||
// Begin DeltaV
|
||||
using Content.Server._DV.MedicalRecords;
|
||||
using Content.Shared._DV.MedicalRecords;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
// End DeltaV
|
||||
|
||||
namespace Content.Server.Medical;
|
||||
@@ -270,11 +269,9 @@ public sealed partial class HealthAnalyzerSystem : EntitySystem // DeltaV - Made
|
||||
var bleeding = false;
|
||||
var unrevivable = false;
|
||||
|
||||
Solution? bloodSolution = null; // DeltaV - Health Analyzer Plus
|
||||
|
||||
if (TryComp<BloodstreamComponent>(entity, out var bloodstream) &&
|
||||
_solutionContainerSystem.ResolveSolution(entity, bloodstream.BloodSolutionName,
|
||||
ref bloodstream.BloodSolution, out bloodSolution)) // DeltaV - Health Analyzer Plus
|
||||
ref bloodstream.BloodSolution, out var bloodSolution))
|
||||
{
|
||||
bloodAmount = _bloodstreamSystem.GetBloodLevel(entity);
|
||||
bleeding = bloodstream.BleedAmount > 0;
|
||||
@@ -290,7 +287,6 @@ public sealed partial class HealthAnalyzerSystem : EntitySystem // DeltaV - Made
|
||||
null,
|
||||
bleeding,
|
||||
unrevivable,
|
||||
bloodSolution, // DeltaV - Health Analyzer Plus
|
||||
_medicalRecords.GetMedicalRecords(entity) // DeltaV - Medical Records
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Content.Shared.Chat.Prototypes; // Starlight
|
||||
using Content.Shared.Damage.Prototypes; // Starlight
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.Chat.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Server.Mobs;
|
||||
@@ -23,10 +21,4 @@ public sealed partial class DeathgaspComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool NeedsCritical = true;
|
||||
|
||||
/// <summary>
|
||||
/// Starlight - The damage that is taken when succumbing
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<DamageTypePrototype> DamageType = "Asphyxiation";
|
||||
}
|
||||
|
||||
@@ -55,13 +55,9 @@ public sealed class PseudoItemSystem : SharedPseudoItemSystem
|
||||
|
||||
protected override void OnGettingPickedUpAttempt(EntityUid uid, PseudoItemComponent component, GettingPickedUpAttemptEvent args)
|
||||
{
|
||||
// Floof - changed this a bit to actually start a do-after
|
||||
// Try to pick the entity up instead first
|
||||
if (args.User != args.Item
|
||||
&& TryComp<CarriableComponent>(uid, out var carriable)
|
||||
&& _carrying.CanCarry(args.User, (uid, carriable)))
|
||||
if (args.User != args.Item && _carrying.TryCarry(args.User, uid))
|
||||
{
|
||||
_carrying.StartCarryDoAfter(args.User, (uid, carriable));
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -209,24 +209,20 @@ namespace Content.Server.Psionics.Glimmer
|
||||
|
||||
private void OnDestroyed(EntityUid uid, SharedGlimmerReactiveComponent component, DestructionEventArgs args)
|
||||
{
|
||||
var proberCoords = Transform(uid).Coordinates;
|
||||
Spawn("MaterialBluespace1", Transform(uid).Coordinates);
|
||||
|
||||
var tier = _glimmerSystem.GetGlimmerTier();
|
||||
if (tier < GlimmerTier.High)
|
||||
return;
|
||||
|
||||
var explosionMultiplier = 2;
|
||||
if (_glimmerSystem.GetGlimmerTier() == GlimmerTier.Critical) // YOU DONE FUCKED UP
|
||||
explosionMultiplier = 3;
|
||||
var totalIntensity = (float) (_glimmerSystem.Glimmer * 2);
|
||||
var slope = (float) (11 - _glimmerSystem.Glimmer / 100);
|
||||
var maxIntensity = 20;
|
||||
|
||||
var totalIntensity = (float)(_glimmerSystem.Glimmer * explosionMultiplier);
|
||||
var slope = (float)(11 - _glimmerSystem.Glimmer / 100);
|
||||
var maxIntensity = 75; // Same as syndicate bomb
|
||||
|
||||
var removed = _glimmerSystem.Glimmer * _random.NextFloat(0.06f, 0.08f);
|
||||
_glimmerSystem.Glimmer -= (int)removed;
|
||||
var removed = (float) _glimmerSystem.Glimmer * _random.NextFloat(0.06f, 0.08f);
|
||||
_glimmerSystem.Glimmer -= (int) removed;
|
||||
BeamRandomNearProber(uid, _glimmerSystem.Glimmer / 350, _glimmerSystem.Glimmer / 50);
|
||||
_explosionSystem.QueueExplosion(uid, "Default", totalIntensity, slope, maxIntensity, addLog: true);
|
||||
Spawn("MaterialBluespace1", proberCoords); // Congrats on your bluespace!
|
||||
_explosionSystem.QueueExplosion(uid, "Default", totalIntensity, slope, maxIntensity);
|
||||
}
|
||||
|
||||
private void OnUnanchorAttempt(EntityUid uid, SharedGlimmerReactiveComponent component, UnanchorAttemptEvent args)
|
||||
@@ -234,7 +230,7 @@ namespace Content.Server.Psionics.Glimmer
|
||||
if (component.Locked)
|
||||
{
|
||||
_sharedAudioSystem.PlayPvs(component.ShockNoises, args.User);
|
||||
_electrocutionSystem.TryDoElectrocution(args.User, uid, _glimmerSystem.Glimmer / 200, TimeSpan.FromSeconds((float) _glimmerSystem.Glimmer / 100), false);
|
||||
_electrocutionSystem.TryDoElectrocution(args.User, null, _glimmerSystem.Glimmer / 200, TimeSpan.FromSeconds((float) _glimmerSystem.Glimmer / 100), false);
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,8 +184,7 @@ public sealed class OracleSystem : EntitySystem
|
||||
|
||||
while (i != 0)
|
||||
{
|
||||
var entityToSpawn = _random.Next(0, 2) == 0 ? "MaterialBluespace1" : "CrystalNormality";
|
||||
Spawn(entityToSpawn, Transform(user).Coordinates);
|
||||
Spawn("MaterialBluespace1", Transform(user).Coordinates);
|
||||
i--;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,12 +125,12 @@ public sealed class ProjectileSystem : SharedProjectileSystem
|
||||
RaiseLocalEvent(projectile, ref pierceEv);
|
||||
|
||||
// If the object won't be destroyed, it "tanks" the penetration hit.
|
||||
if (damage.GetTotal() < damageRequired && !pierceEv.Pierced) // DeltaV - Addition of the NT-3
|
||||
if (damage.GetTotal() < damageRequired)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!projectile.Comp.ProjectileSpent && !pierceEv.Pierced) // DeltaV - Addition of the NT-3
|
||||
if (!projectile.Comp.ProjectileSpent)
|
||||
{
|
||||
projectile.Comp.PenetrationAmount += damageRequired;
|
||||
// The projectile has dealt enough damage to be spent.
|
||||
@@ -139,7 +139,7 @@ public sealed class ProjectileSystem : SharedProjectileSystem
|
||||
return false;
|
||||
}
|
||||
|
||||
if (projectile.Comp.ProjectileSpent)
|
||||
if (projectile.Comp.ProjectileSpent && pierceEv.Pierced) // DeltaV - Addition of the NT-3
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,8 +41,7 @@ namespace Content.Server.StationEvents
|
||||
if (TryComp<NextEventComponent>(uid, out var nextEventComponent)
|
||||
&& _event.TryGenerateRandomEvent(component.ScheduledGameRules, TimeSpan.FromSeconds(component.TimeUntilNextEvent)) is {} firstEvent)
|
||||
{
|
||||
var nextEventTime = GameTicker.RoundDuration() + TimeSpan.FromSeconds(component.TimeUntilNextEvent);
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", firstEvent), ("time", nextEventTime.ToString(@"hh\:mm\:ss"))));
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", firstEvent), ("seconds", (int)component.TimeUntilNextEvent)));
|
||||
_next.UpdateNextEvent(nextEventComponent, firstEvent, GameTicker.RoundDuration() + TimeSpan.FromSeconds(component.TimeUntilNextEvent));
|
||||
}
|
||||
// End DeltaV Additions
|
||||
@@ -82,7 +81,7 @@ namespace Content.Server.StationEvents
|
||||
if (_event.TryGenerateRandomEvent(eventScheduler.ScheduledGameRules, nextEventTime) is not {} generatedEvent)
|
||||
continue;
|
||||
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", generatedEvent), ("time", nextEventTime.ToString(@"hh\:mm\:ss"))));
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", generatedEvent), ("seconds", (int)eventScheduler.TimeUntilNextEvent)));
|
||||
// Cycle the stashed event with the new generated event and time.
|
||||
var storedEvent = _next.UpdateNextEvent(nextEventComponent, generatedEvent, nextEventTime);
|
||||
if (string.IsNullOrEmpty(storedEvent)) //If there was no stored event don't try to run it.
|
||||
|
||||
@@ -14,12 +14,9 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
||||
[Dependency] private readonly IChatManager _chatManager = default!; // DeltaV
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly EventManagerSystem _event = default!;
|
||||
#if DEBUG // DeltaV - Only used if built by Debug
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
#endif
|
||||
[Dependency] private readonly NextEventSystem _next = default!; // DeltaV
|
||||
[Dependency] private readonly IGameTiming _timing = default!; // DeltaV
|
||||
|
||||
|
||||
/* DeltaV
|
||||
/// <summary>
|
||||
/// Returns the ChaosModifier which increases as round time increases to a point.
|
||||
@@ -53,8 +50,7 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
||||
if (TryComp<NextEventComponent>(uid, out var nextEventComponent)
|
||||
&& _event.TryGenerateRandomEvent(component.ScheduledGameRules, TimeSpan.FromSeconds(component.TimeUntilNextEvent)) is {} firstEvent)
|
||||
{
|
||||
var nextEventTime = GameTicker.RoundDuration() + TimeSpan.FromSeconds(component.TimeUntilNextEvent);
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", firstEvent), ("time", nextEventTime.ToString(@"hh\:mm\:ss"))));
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", firstEvent), ("seconds", (int)component.TimeUntilNextEvent)));
|
||||
_next.UpdateNextEvent(nextEventComponent, firstEvent, GameTicker.RoundDuration() + TimeSpan.FromSeconds(component.TimeUntilNextEvent));
|
||||
}
|
||||
// End DeltaV Additions: init NextEventComp
|
||||
@@ -87,7 +83,7 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
||||
if (_event.TryGenerateRandomEvent(scheduler.ScheduledGameRules, nextEventTime) is not {} generatedEvent)
|
||||
continue;
|
||||
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", generatedEvent), ("time", nextEventTime.ToString(@"hh\:mm\:ss"))));
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", generatedEvent), ("seconds", (int)scheduler.TimeUntilNextEvent)));
|
||||
// Cycle the stashed event with the new generated event and time.
|
||||
string? storedEvent = _next.UpdateNextEvent(nextEventComponent, generatedEvent, nextEventTime);
|
||||
if (string.IsNullOrEmpty(storedEvent)) //If there was no stored event don't try to run it.
|
||||
@@ -118,28 +114,13 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
||||
// Begin DeltaV Additions
|
||||
var averageTimeUntilNextEvent = component.TimeKeyPoints[0].Y;
|
||||
var timeUntilNextEventDeviation = _random.NextFloat(-1f, 1f) * component.TimeDeviation;
|
||||
|
||||
var ruleActivated = TimeSpan.FromSeconds(0);
|
||||
if (TryComp<GameRuleComponent>(uid, out var gameRule))
|
||||
{
|
||||
ruleActivated = gameRule.ActivatedAt;
|
||||
}
|
||||
|
||||
var ruleTime = _timing.CurTime.Subtract(ruleActivated);
|
||||
|
||||
#if DEBUG
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-debug-round-time", ("time", _gameTicker.RoundDuration())));
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-debug-ramping-time", ("time", ruleActivated)));
|
||||
// This will be what the keypoint system looks at to determine where to start ramping
|
||||
_chatManager.SendAdminAlert(Loc.GetString("station-event-system-debug-keypoint-time", ("time", ruleTime)));
|
||||
_chatManager.SendAdminAlert("_______________"); // Easier to read
|
||||
#endif
|
||||
|
||||
var roundTime = (float)_gameTicker.RoundDuration().TotalMinutes;
|
||||
var absoluteTimePoint = 0f;
|
||||
|
||||
foreach (var point in component.TimeKeyPoints)
|
||||
{
|
||||
absoluteTimePoint += point.X;
|
||||
if (ruleTime.TotalMinutes >= absoluteTimePoint)
|
||||
if (roundTime >= absoluteTimePoint)
|
||||
averageTimeUntilNextEvent = point.Y;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using Content.Shared._CD.Silicons.Borgs;
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
namespace Content.Server._CD.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Server-side logic that shouldn't be exposed to the client.
|
||||
/// </summary>
|
||||
public sealed class BorgSwitchableSubstypeSystem : SharedBorgSwitchableSubtypeSystem
|
||||
{
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
|
||||
protected override void SelectBorgSubtype(Entity<BorgSwitchableSubtypeComponent> ent)
|
||||
{
|
||||
if (ent.Comp.BorgSubtype == null)
|
||||
return;
|
||||
|
||||
if (!Prototypes.Index(ent.Comp.BorgSubtype.Value)
|
||||
.TryGetComponent<BorgSubtypeDefinitionComponent>(out var borgSubtype, ComponentFactory))
|
||||
return;
|
||||
|
||||
// Configure special components
|
||||
if (Prototypes.TryIndex(ent.Comp.BorgSubtype, out var previousPrototype) &&
|
||||
previousPrototype.TryGetComponent<BorgSubtypeDefinitionComponent>(out var previousSubtype, ComponentFactory))
|
||||
{
|
||||
if (previousSubtype.AddComponents is { } removeComponents)
|
||||
EntityManager.RemoveComponents(ent, removeComponents);
|
||||
}
|
||||
|
||||
if (borgSubtype.AddComponents is { } addComponents)
|
||||
{
|
||||
EntityManager.AddComponents(ent, addComponents);
|
||||
}
|
||||
|
||||
// inventory template configuration (hats spacing)
|
||||
if (TryComp(ent, out InventoryComponent? inventory))
|
||||
{
|
||||
_inventorySystem.SetTemplateId((ent.Owner, inventory), borgSubtype.InventoryTemplateId);
|
||||
}
|
||||
|
||||
base.SelectBorgSubtype(ent);
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,8 @@ public sealed partial class CosmicFinaleComponent : Component
|
||||
{ "Blunt", 2.25},
|
||||
{ "Cold", 2.25},
|
||||
{ "Radiation", 2.25},
|
||||
{ "Asphyxiation", 2.25}
|
||||
{ "Asphyxiation", 2.25},
|
||||
{ "Ion", 2.25}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
|
||||
if (!EntityIsCultist(args.Equipee))
|
||||
{
|
||||
_statusEffects.TryAddStatusEffect<CosmicEntropyDebuffComponent>(args.Equipee, EntropicDegen, TimeSpan.FromDays(1), true); // TimeSpan.MaxValue causes a crash here, so we use FromDays(1) instead.
|
||||
if (TryComp<CosmicEntropyDebuffComponent>(args.Equipee, out var comp)) comp.Degen = new(){DamageDict = new(){{"Cold", 0.5}, {"Asphyxiation", 1.5}}};
|
||||
if (TryComp<CosmicEntropyDebuffComponent>(args.Equipee, out var comp)) comp.Degen = new(){DamageDict = new(){{"Cold", 0.5}, {"Asphyxiation", 1.5}, {"Ion", 1.5}}};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
|
||||
if (!EntityIsCultist(args.User))
|
||||
{
|
||||
_statusEffects.TryAddStatusEffect<CosmicEntropyDebuffComponent>(args.User, EntropicDegen, TimeSpan.FromDays(1), true);
|
||||
if (TryComp<CosmicEntropyDebuffComponent>(args.User, out var comp)) comp.Degen = new(){DamageDict = new(){{"Cold", 0.5}, {"Asphyxiation", 1.5}}};
|
||||
if (TryComp<CosmicEntropyDebuffComponent>(args.User, out var comp)) comp.Degen = new(){DamageDict = new(){{"Cold", 0.5}, {"Asphyxiation", 1.5}, {"Ion", 1.5}}};
|
||||
_popup.PopupEntity(Loc.GetString("cosmiccult-gear-pickup", ("ITEM", args.Equipped)), args.User, args.User, PopupType.MediumCaution);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,8 @@ public sealed class CosmicRiftSystem : EntitySystem
|
||||
if (TryComp<CosmicEntropyDebuffComponent>(mob, out var debuff)) debuff.Degen =
|
||||
new(){DamageDict = new(){
|
||||
{"Cold", 0.05 * damageMultiplier},
|
||||
{"Asphyxiation", 0.15 * damageMultiplier}
|
||||
{"Asphyxiation", 0.15 * damageMultiplier},
|
||||
{"Ion", 0.15 * damageMultiplier}
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public sealed partial class GameTicker
|
||||
public bool ConvertRoundToSurvival()
|
||||
{
|
||||
// Ramping scheduler is already added. Do nothing.
|
||||
if (IsGameRuleAdded(RampingSchedulerProto))
|
||||
if (IsGameRuleActive(RampingSchedulerProto))
|
||||
{
|
||||
_chatManager.SendAdminAlert("RampingStationEventScheduler detected. No rules added.");
|
||||
return true;
|
||||
@@ -44,7 +44,7 @@ public sealed partial class GameTicker
|
||||
var rampingSchedulerStart = _gameTiming.CurTime.Add(GracePeriod);
|
||||
EnsureComp<DelayedStartRuleComponent>(rampingScheduler).RuleStartTime = rampingSchedulerStart;
|
||||
|
||||
_chatManager.SendAdminAlert($"Major antag defeated. Converting to survival at {(RoundDuration() + GracePeriod).ToString(@"hh\:mm\:ss")}.");
|
||||
_chatManager.SendAdminAlert($"Major antag defeated. Converting to survival at {rampingSchedulerStart}.");
|
||||
|
||||
// End Basic Rules
|
||||
var basicRules = EntityQueryEnumerator<BasicStationEventSchedulerComponent>();
|
||||
|
||||
@@ -8,7 +8,6 @@ using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Shared._DV.NodeCrawl;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.NodeContainer;
|
||||
using Content.Shared.Polymorph;
|
||||
using Content.Shared.Zombies;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -31,7 +30,6 @@ public sealed class NodeCrawlSystem : SharedNodeCrawlSystem
|
||||
SubscribeLocalEvent<NodeCrawlerComponent, InhaleLocationEvent>(OnInhaleLocation);
|
||||
SubscribeLocalEvent<NodeCrawlerComponent, ExhaleLocationEvent>(OnExhaleLocation);
|
||||
SubscribeLocalEvent<NodeCrawlerComponent, AtmosExposedGetAirEvent>(OnGetAir);
|
||||
SubscribeLocalEvent<NodeCrawlerComponent, PolymorphActionEvent>(OnPolymorph);
|
||||
|
||||
SubscribeLocalEvent<NodeCrawlerComponent, EntityZombifiedEvent>(OnZombify);
|
||||
}
|
||||
@@ -224,15 +222,4 @@ public sealed class NodeCrawlSystem : SharedNodeCrawlSystem
|
||||
ent.Comp.EnterDelay = ent.Comp.ZombieEnterDelay;
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exit on polymorph or else the entity's movement bugs out.
|
||||
/// </summary>
|
||||
/// <param name="ent"></param>
|
||||
/// <param name="args"></param>
|
||||
private void OnPolymorph(Entity<NodeCrawlerComponent> ent, ref PolymorphActionEvent args)
|
||||
{
|
||||
if (ent.Comp.Mover.HasValue)
|
||||
ExitNodeCrawl(ent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._DV.Projectiles.Components;
|
||||
@@ -22,14 +21,10 @@ public sealed partial class PiercingProjectileComponent : Component
|
||||
public float PierceCounter;
|
||||
|
||||
/// <summary>
|
||||
/// The whitelist for checking what increments the <see cref="PierceCounter"/>.
|
||||
/// The tag that will cause the piercing bullet to increment it's <see cref="PierceCounter"/>.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// If this has the tag "Wall" in it, any entity with the tag "Wall" will increment <see cref="PierceCounter"/>
|
||||
/// upon being hit.
|
||||
/// </example>
|
||||
[DataField]
|
||||
public EntityWhitelist PierceCounterWhitelist;
|
||||
public List<ProtoId<TagPrototype>> PierceBlockTag = ["Wall", "Window"];
|
||||
|
||||
/// <summary>
|
||||
/// The number of entities it is allowed to pierce before being deleted.
|
||||
|
||||
@@ -3,7 +3,7 @@ using Content.Shared.FixedPoint;
|
||||
namespace Content.Server._DV.Projectiles.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a piercing projectile that doesn't follow upstream piercing rules hits an entity.
|
||||
/// Raised when a piercing projectile hits an entity that doesn't follow upstream piercing rules.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct ProjectilePierceEvent(EntityUid Target, FixedPoint2 RequiredDamage, bool Pierced = false);
|
||||
|
||||
@@ -1,33 +1,29 @@
|
||||
using Content.Server._DV.Projectiles.Components;
|
||||
using Content.Server._DV.Projectiles.Events;
|
||||
using Content.Shared.Whitelist;
|
||||
using Content.Shared.Tag;
|
||||
|
||||
namespace Content.Server._DV.Projectiles.Systems;
|
||||
|
||||
public sealed class PiercingProjectileSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
|
||||
// Mobs return a required Damage amount of Float.MaxValue. Therefore, we need to check for absurdly high values.
|
||||
private readonly int _indestructibleNumber = 20000000;
|
||||
[Dependency] private readonly TagSystem _tagSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<PiercingProjectileComponent, ProjectilePierceEvent>(OnPierce);
|
||||
}
|
||||
|
||||
private void OnPierce(Entity<PiercingProjectileComponent> bullet, ref ProjectilePierceEvent args)
|
||||
{
|
||||
// If the target doesn't have any tags to stop the bullet from piercing, it's automatically true.
|
||||
if (_whitelist.IsWhitelistFail(bullet.Comp.PierceCounterWhitelist, args.Target))
|
||||
if (!_tagSystem.HasAnyTag(args.Target, bullet.Comp.PierceBlockTag))
|
||||
{
|
||||
args.Pierced = true;
|
||||
return;
|
||||
}
|
||||
// If it does have the tag to stop it and enough health to count as "strongly armored", it'll block the bullet.
|
||||
if (bullet.Comp.HealthThreshold < args.RequiredDamage && args.RequiredDamage < _indestructibleNumber)
|
||||
if (bullet.Comp.HealthThreshold < args.RequiredDamage)
|
||||
return;
|
||||
|
||||
if (bullet.Comp.Direction == null) // Get the direction of the bullet to determine which walls count.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
using Content.Shared._DV.Silicons;
|
||||
|
||||
namespace Content.Server._DV.Silicons;
|
||||
|
||||
public sealed class SiliconEmpSystem : SharedSiliconEmpSystem;
|
||||
@@ -109,10 +109,8 @@ public sealed class FugitiveRule : StationEventSystem<FugitiveRuleComponent>
|
||||
var report = new FormattedMessage();
|
||||
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-title"));
|
||||
report.PushNewline();
|
||||
report.PushNewline();
|
||||
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-first-line"));
|
||||
report.PushNewline();
|
||||
report.PushNewline();
|
||||
|
||||
if (!TryComp<HumanoidProfileComponent>(uid, out var humanoid))
|
||||
{
|
||||
@@ -123,28 +121,22 @@ public sealed class FugitiveRule : StationEventSystem<FugitiveRuleComponent>
|
||||
var species = PrototypeManager.Index(humanoid.Species);
|
||||
|
||||
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-morphotype", ("species", Loc.GetString(species.Name))));
|
||||
report.PushNewline();
|
||||
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-age", ("age", humanoid.Age)));
|
||||
report.PushNewline();
|
||||
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-sex", ("sex", humanoid.Sex)));
|
||||
report.PushNewline();
|
||||
|
||||
if (TryComp<PhysicsComponent>(uid, out var physics))
|
||||
{
|
||||
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-weight", ("weight", Math.Round(physics.FixturesMass))));
|
||||
report.PushNewline();
|
||||
}
|
||||
|
||||
// add a random identifying quality that officers can use to track them down
|
||||
report.AddMarkupOrThrow(RobustRandom.Next(0, 2) switch
|
||||
{
|
||||
0 => Loc.GetString("fugitive-report-detail-dna", ("dna", GetDNA(uid))),
|
||||
_ => Loc.GetString("fugitive-report-detail-prints", ("prints", GetPrints(uid)))
|
||||
});
|
||||
report.PushNewline();
|
||||
|
||||
report.PushNewline();
|
||||
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-crimes-header"));
|
||||
report.PushNewline();
|
||||
|
||||
// generate some random crimes to avoid this situation
|
||||
// "officer what are my charges?"
|
||||
// "uh i dunno a piece of paper said to arrest you thats it"
|
||||
@@ -180,7 +172,6 @@ public sealed class FugitiveRule : StationEventSystem<FugitiveRuleComponent>
|
||||
{
|
||||
var count = RobustRandom.Next(rule.MinCounts, rule.MaxCounts + 1);
|
||||
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-crime", ("crime", Loc.GetString(crime)), ("count", count)));
|
||||
report.PushNewline();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
using Content.Shared.Store;
|
||||
using Content.Shared.Store.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._DV.Store.Conditions;
|
||||
|
||||
/// <summary>
|
||||
/// XOR (eXclusive-OR) Buy Condition
|
||||
/// A condition where that blocks buying a listing if another listing
|
||||
/// specified is bought before it. Used to enforce that a traitor
|
||||
/// can only buy 1 of X options.
|
||||
///
|
||||
/// Primarily used for choose-your-own-adventure DAGD Implants.
|
||||
/// </summary>
|
||||
public sealed partial class XORBuyCondition : ListingCondition
|
||||
{
|
||||
/// <summary>
|
||||
/// Listing(s) that if bought, block this purchase, if any.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public HashSet<ProtoId<ListingPrototype>>? Listings;
|
||||
|
||||
public override bool Condition(ListingConditionArgs args)
|
||||
{
|
||||
if (!args.EntityManager.TryGetComponent<StoreComponent>(args.StoreEntity, out var storeComp))
|
||||
return false;
|
||||
|
||||
var allListings = storeComp.FullListingsCatalog;
|
||||
|
||||
if (Listings != null)
|
||||
{
|
||||
foreach (var blacklistListing in Listings)
|
||||
{
|
||||
foreach (var listing in allListings)
|
||||
{
|
||||
if (listing.ID == blacklistListing.Id && listing.PurchaseAmount > 0)
|
||||
return false; // it was purchased, so return false to fail the condition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true; // If no purchases were found, return true
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
using System.Text.RegularExpressions;
|
||||
using Content.Server.Administration;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server._DV.Toolshed;
|
||||
|
||||
/// <summary>
|
||||
/// An extended version of the engine's <c>do</c> command. Runs a console command once per piped value,
|
||||
/// substituting <c>$NAME</c> tokens in the command string first.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// On top of the built-in tokens that <c>do</c> supports (<c>$ID</c>, <c>$PID</c>, <c>$WX</c>, <c>$WY</c>,
|
||||
/// <c>$LX</c>, <c>$LY</c>, <c>$SELF</c>), any other <c>$name</c> is resolved as a toolshed variable and
|
||||
/// converted to a string. Tokens that don't resolve to anything are left untouched.
|
||||
///
|
||||
/// Where the command actually runs is explicit:
|
||||
/// <list type="bullet">
|
||||
/// <item><c>doext:client</c> sends it back down to the calling user's own client to run locally. This is what
|
||||
/// you want for client-side commands like <c>exec</c>, which resolve paths against the client's user data.</item>
|
||||
/// <item><c>doext:server</c> runs it server-side as the calling session, like <c>do</c> does.</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <example><code>
|
||||
/// self doext:client "exec /Script_$var.txt"
|
||||
/// i 5 => $count; self doext:server "somecommand $count"
|
||||
/// </code></example>
|
||||
[ToolshedCommand(Name = "doext"), AdminCommand(AdminFlags.Debug)]
|
||||
public sealed class DoExtCommand : ToolshedCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// Matches a <c>$name</c> token. Names use the same character set as toolshed variable names, so this
|
||||
/// matches whole identifiers - <c>$IDLE</c> resolves as "IDLE" rather than being mangled into <c>$ID</c>.
|
||||
/// </summary>
|
||||
private static readonly Regex TokenRegex = new(@"\$(\w+)", RegexOptions.Compiled);
|
||||
|
||||
[Dependency] private readonly IConsoleHost _console = default!;
|
||||
|
||||
private SharedTransformSystem? _xform;
|
||||
|
||||
/// <summary>
|
||||
/// Sends the command back down to the calling user's client, which runs it locally.
|
||||
/// </summary>
|
||||
[CommandImplementation("client"), TakesPipedTypeAsGeneric]
|
||||
public IEnumerable<T> Client<T>(IInvocationContext ctx, [PipedArgument] IEnumerable<T> input, string command)
|
||||
{
|
||||
// No session means there's no client to hand this back to - e.g. the server console.
|
||||
if (ctx.Session is not { } session)
|
||||
{
|
||||
ctx.ReportError(new NoClientSessionError());
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var value in input)
|
||||
{
|
||||
_console.RemoteExecuteCommand(session, Substitute(command, value, ctx));
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the command on the server as the calling session.
|
||||
/// </summary>
|
||||
[CommandImplementation("server"), TakesPipedTypeAsGeneric]
|
||||
public IEnumerable<T> Server<T>(IInvocationContext ctx, [PipedArgument] IEnumerable<T> input, string command)
|
||||
{
|
||||
foreach (var value in input)
|
||||
{
|
||||
_console.ExecuteCommand(ctx.Session, Substitute(command, value, ctx));
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
|
||||
private string Substitute<T>(string command, T value, IInvocationContext ctx)
|
||||
{
|
||||
return TokenRegex.Replace(command, match =>
|
||||
{
|
||||
var name = match.Groups[1].Value;
|
||||
|
||||
if (TryGetBuiltin(name, value, ctx, out var builtin))
|
||||
return builtin;
|
||||
|
||||
// Anything else is looked up as a toolshed variable and implicitly stringified.
|
||||
if (ctx.ReadVar(name) is { } variable)
|
||||
return Stringify(variable);
|
||||
|
||||
// Unresolved, so leave the token alone rather than silently blanking it.
|
||||
return match.Value;
|
||||
});
|
||||
}
|
||||
|
||||
private bool TryGetBuiltin<T>(string name, T value, IInvocationContext ctx, [NotNullWhen(true)] out string? result)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "SELF":
|
||||
result = Stringify(value);
|
||||
return true;
|
||||
case "PID":
|
||||
result = (ctx.Session?.AttachedEntity ?? EntityUid.Invalid).ToString();
|
||||
return true;
|
||||
}
|
||||
|
||||
// The remaining tokens are all positional, so they only apply when piping entities.
|
||||
if (value is not EntityUid uid)
|
||||
{
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (name)
|
||||
{
|
||||
case "ID":
|
||||
result = uid.ToString();
|
||||
return true;
|
||||
case "WX":
|
||||
result = Number(WorldPosition(uid).X);
|
||||
return true;
|
||||
case "WY":
|
||||
result = Number(WorldPosition(uid).Y);
|
||||
return true;
|
||||
case "LX":
|
||||
result = Number(Transform(uid).Coordinates.X);
|
||||
return true;
|
||||
case "LY":
|
||||
result = Number(Transform(uid).Coordinates.Y);
|
||||
return true;
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private Vector2 WorldPosition(EntityUid uid)
|
||||
{
|
||||
_xform ??= GetSys<SharedTransformSystem>();
|
||||
return _xform.GetWorldPosition(uid);
|
||||
}
|
||||
|
||||
private static string Number(float value) => value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
private static string Stringify(object? value) => value?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
public sealed class NoClientSessionError : IConError
|
||||
{
|
||||
public FormattedMessage DescribeInner()
|
||||
{
|
||||
return FormattedMessage.FromUnformatted("There is no client to run this on. doext:client must be run by a player, not the server console.");
|
||||
}
|
||||
|
||||
public string? Expression { get; set; }
|
||||
public Vector2i? IssueSpan { get; set; }
|
||||
public StackTrace? Trace { get; set; }
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Content.Server.Administration;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server._DV.Toolshed;
|
||||
|
||||
/// <summary>
|
||||
/// Reads the value of a single field or property off of the piped input, by name.
|
||||
/// Member names are resolved the same way <c>vvread</c> does: the member must be exposed
|
||||
/// via <c>[ViewVariables]</c>, <c>[DataField]</c>, or <c>[IncludeDataField]</c>.
|
||||
/// </summary>
|
||||
/// <example><code>ent 12345 . Name</code></example>
|
||||
[ToolshedCommand(Name = "."), AdminCommand(AdminFlags.Debug)]
|
||||
public sealed class FieldCommand : ToolshedCommand
|
||||
{
|
||||
[CommandImplementation]
|
||||
public object? Field([PipedArgument] object? value, [CommandArgument(typeof(FieldNameParser))] string field, IInvocationContext ctx)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
ctx.ReportError(new NullInputFieldError());
|
||||
return null;
|
||||
}
|
||||
|
||||
var type = value.GetType();
|
||||
var member = GetSingleMember(type, field);
|
||||
|
||||
// Restrict to members that vvread would let you read, so this can't be used to peek at arbitrary internals.
|
||||
if (member == null || !ViewVariablesUtility.TryGetViewVariablesAccess(member, out _))
|
||||
{
|
||||
ctx.ReportError(new NoSuchFieldError(type, field));
|
||||
return null;
|
||||
}
|
||||
|
||||
return member switch
|
||||
{
|
||||
FieldInfo f => f.GetValue(value),
|
||||
PropertyInfo p => p.GetValue(value),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the field or property with the given name, mirroring the resolution used by <c>vvread</c>.
|
||||
/// </summary>
|
||||
private static MemberInfo? GetSingleMember(Type type, string member)
|
||||
{
|
||||
var members = type
|
||||
.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(m => m.Name == member && m is FieldInfo or PropertyInfo)
|
||||
.ToArray();
|
||||
|
||||
if (members.Length == 0)
|
||||
return null;
|
||||
|
||||
// In case there's member hiding going on, grab the one declared by the type of the object by default.
|
||||
return members.Length > 1
|
||||
? members.FirstOrDefault(m => m.DeclaringType == type) ?? members[0]
|
||||
: members[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a field name as a bare identifier (letters, digits, underscore) so that the <c>.</c> command doesn't
|
||||
/// require the name to be wrapped in quotes like the default <see cref="string"/> parser does.
|
||||
/// </summary>
|
||||
public sealed class FieldNameParser : CustomTypeParser<string>
|
||||
{
|
||||
public override bool TryParse(ParserContext ctx, [NotNullWhen(true)] out string? result)
|
||||
{
|
||||
ctx.ConsumeWhitespace();
|
||||
result = ctx.GetWord(ParserContext.IsToken);
|
||||
if (result != null)
|
||||
return true;
|
||||
|
||||
if (ctx.PeekRune() is null)
|
||||
ctx.Error = new OutOfInputError();
|
||||
else
|
||||
ctx.Error = new InvalidFieldNameError();
|
||||
|
||||
ctx.Error.Contextualize(ctx.Input, (ctx.Index, ctx.Index + 1));
|
||||
return false;
|
||||
}
|
||||
|
||||
public override CompletionResult? TryAutocomplete(ParserContext ctx, CommandArgument? arg)
|
||||
{
|
||||
return CompletionResult.FromHint(GetArgHint(arg));
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class InvalidFieldNameError : IConError
|
||||
{
|
||||
public FormattedMessage DescribeInner()
|
||||
{
|
||||
return FormattedMessage.FromUnformatted("Expected a field name (letters, digits, or underscores).");
|
||||
}
|
||||
|
||||
public string? Expression { get; set; }
|
||||
public Vector2i? IssueSpan { get; set; }
|
||||
public StackTrace? Trace { get; set; }
|
||||
}
|
||||
|
||||
public sealed class NullInputFieldError : IConError
|
||||
{
|
||||
public FormattedMessage DescribeInner()
|
||||
{
|
||||
return FormattedMessage.FromUnformatted("Cannot read a field off of a null input.");
|
||||
}
|
||||
|
||||
public string? Expression { get; set; }
|
||||
public Vector2i? IssueSpan { get; set; }
|
||||
public StackTrace? Trace { get; set; }
|
||||
}
|
||||
|
||||
public sealed class NoSuchFieldError(Type type, string field) : IConError
|
||||
{
|
||||
public FormattedMessage DescribeInner()
|
||||
{
|
||||
return FormattedMessage.FromUnformatted($"Type {type.Name} has no readable field or property named '{field}'. It must be exposed via [ViewVariables], [DataField], or [IncludeDataField].");
|
||||
}
|
||||
|
||||
public string? Expression { get; set; }
|
||||
public Vector2i? IssueSpan { get; set; }
|
||||
public StackTrace? Trace { get; set; }
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
using Content.Shared._Floof.OfferItem;
|
||||
|
||||
namespace Content.Server._Floof.OfferItem;
|
||||
|
||||
public sealed partial class OfferItemSystem : SharedOfferItemSystem;
|
||||
@@ -13,7 +13,7 @@ public sealed partial class RevenantStasisComponent : Component
|
||||
public Entity<RevenantComponent> Revenant;
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public TimeSpan StasisDuration = TimeSpan.FromSeconds(100); // DeltaV - change from 60 to 100s
|
||||
public TimeSpan StasisDuration = TimeSpan.FromSeconds(60);
|
||||
|
||||
public RevenantStasisComponent(TimeSpan stasisDuration, Entity<RevenantComponent> revenant)
|
||||
{
|
||||
|
||||
@@ -27,7 +27,6 @@ using Content.Shared.Mobs;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Shared.Construction.Components;
|
||||
using Content.Shared.Trigger.Components;
|
||||
using Content.Shared.Zombies; // DeltaV
|
||||
|
||||
namespace Content.Server._Impstation.Revenant.EntitySystems;
|
||||
|
||||
@@ -197,7 +196,6 @@ public sealed partial class RevenantAnimatedSystem : EntitySystem
|
||||
animate.EndTime = _gameTiming.CurTime + duration.Value;
|
||||
else if (revenant != null)
|
||||
animate.EndTime = _gameTiming.CurTime + revenant.Value.Comp.AnimateTime;
|
||||
EnsureComp<ZombieImmuneComponent>(target); // DeltaV - ensure immune from zombies so we don't break clients
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,293 +0,0 @@
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Server.GameObjects;
|
||||
using Content.Shared.Examine;
|
||||
using Robust.Server.Containers;
|
||||
using Content.Shared._Starlight;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Shared.Damage.Systems;
|
||||
using Content.Shared._Goobstation.Overlays;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Server.Body.Components;
|
||||
using System.Linq;
|
||||
using Content.Shared._Goobstation.Flashbang;
|
||||
using Content.Shared._Starlight.Flash.Components;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Flash; // Delta V - Flash Work
|
||||
using Content.Shared._DV.Body.Components; // Delta V - Remove various comps related to breathing
|
||||
|
||||
|
||||
namespace Content.Server._Starlight;
|
||||
|
||||
public sealed class ShadekinSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
[Dependency] private readonly ContainerSystem _container = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _speed = default!;
|
||||
[Dependency] private readonly SharedFlashSystem _flashSystem = default!;
|
||||
|
||||
private sealed class LightCone
|
||||
{
|
||||
public float Direction { get; set; }
|
||||
public float InnerWidth { get; set; }
|
||||
public float OuterWidth { get; set; }
|
||||
}
|
||||
private readonly Dictionary<string, List<LightCone>> lightMasks = new()
|
||||
{
|
||||
["/Textures/Effects/LightMasks/cone.png"] = new List<LightCone>
|
||||
{
|
||||
new LightCone { Direction = 0, InnerWidth = 30, OuterWidth = 60 }
|
||||
},
|
||||
["/Textures/Effects/LightMasks/double_cone.png"] = new List<LightCone>
|
||||
{
|
||||
new LightCone { Direction = 0, InnerWidth = 30, OuterWidth = 60 },
|
||||
new LightCone { Direction = 180, InnerWidth = 30, OuterWidth = 60 }
|
||||
}
|
||||
};
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<ShadekinComponent, ComponentStartup>(OnInit);
|
||||
SubscribeLocalEvent<ShadekinComponent, EyeColorInitEvent>(OnEyeColorChange);
|
||||
SubscribeLocalEvent<ShadekinComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeedModifiers);
|
||||
SubscribeLocalEvent<ShadekinComponent, AfterFlashedEvent>(OnShadekinFlashed); // Delta V - Prevent Chain Flashing
|
||||
SubscribeLocalEvent<ShadekinComponent, FlashDurationMultiplierEvent>(GetFlashModifier); // Delta V - Flash Modifier to Shadekin
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, ShadekinComponent component, ComponentStartup args)
|
||||
{
|
||||
UpdateAlert(uid, component, (short)component.CurrentState);
|
||||
RemComp<InternalsComponent>(uid);
|
||||
RemComp<RespiratorComponent>(uid);
|
||||
RemComp<AffectedByCPRComponent>(uid); // No lungs = no CPR
|
||||
}
|
||||
|
||||
private void OnEyeColorChange(EntityUid uid, ShadekinComponent component, EyeColorInitEvent args)
|
||||
{
|
||||
if (!TryComp<HumanoidProfileComponent>(uid, out var humanoid))
|
||||
return;
|
||||
|
||||
// humanoid.EyeColor = Color.Black;
|
||||
Dirty(uid, humanoid);
|
||||
}
|
||||
|
||||
public void UpdateAlert(EntityUid uid, ShadekinComponent component, short state)
|
||||
{
|
||||
_alerts.ShowAlert(uid, component.ShadekinAlert, state);
|
||||
}
|
||||
|
||||
private Angle GetAngle(EntityUid lightUid, SharedPointLightComponent lightComp, EntityUid targetUid)
|
||||
{
|
||||
var (lightPos, lightRot) = _transform.GetWorldPositionRotation(lightUid);
|
||||
lightPos += lightRot.RotateVec(lightComp.Offset);
|
||||
|
||||
var (targetPos, targetRot) = _transform.GetWorldPositionRotation(targetUid);
|
||||
|
||||
var mapDiff = targetPos - lightPos;
|
||||
|
||||
var oppositeMapDiff = (-lightRot).RotateVec(mapDiff);
|
||||
var angle = oppositeMapDiff.ToWorldAngle();
|
||||
|
||||
if (angle == double.NaN && _transform.ContainsEntity(targetUid, lightUid) || _transform.ContainsEntity(lightUid, targetUid))
|
||||
{
|
||||
angle = 0f;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an illumination float value with is how many "energy" of light is hitting our ent.
|
||||
/// WARNING: This function might be expensive, Avoid calling it too much and CACHE THE RESULT!
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <returns></returns>
|
||||
public float GetLightExposure(EntityUid uid)
|
||||
{
|
||||
var illumination = 0f;
|
||||
|
||||
var lightQuery = _lookup.GetEntitiesInRange<PointLightComponent>(Transform(uid).Coordinates, 20, LookupFlags.Uncontained);
|
||||
|
||||
foreach (var light in lightQuery)
|
||||
{
|
||||
if (!light.Comp.Enabled
|
||||
|| light.Comp.Radius < 1
|
||||
|| light.Comp.Energy <= 0)
|
||||
continue;
|
||||
|
||||
var (lightPos, lightRot) = _transform.GetWorldPositionRotation(light);
|
||||
lightPos += lightRot.RotateVec(light.Comp.Offset);
|
||||
|
||||
if (!_examine.InRangeUnOccluded(light, uid, light.Comp.Radius, null))
|
||||
continue;
|
||||
|
||||
Transform(uid).Coordinates.TryDistance(EntityManager, Transform(light).Coordinates, out var dist);
|
||||
|
||||
var denom = dist / light.Comp.Radius;
|
||||
var attenuation = 1 - (denom * denom);
|
||||
var calculatedLight = 0f;
|
||||
|
||||
if (light.Comp.MaskPath is not null)
|
||||
{
|
||||
var angleToTarget = GetAngle(light, light.Comp, uid);
|
||||
foreach (var cone in lightMasks[light.Comp.MaskPath])
|
||||
{
|
||||
var coneLight = 0f;
|
||||
var angleAttenuation = (float)Math.Min((float)Math.Max(cone.OuterWidth - angleToTarget, 0f), cone.InnerWidth) / cone.OuterWidth;
|
||||
|
||||
if (angleToTarget.Degrees - cone.Direction > cone.OuterWidth)
|
||||
continue;
|
||||
else if (angleToTarget.Degrees - cone.Direction > cone.InnerWidth
|
||||
&& angleToTarget.Degrees - cone.Direction < cone.OuterWidth)
|
||||
coneLight = light.Comp.Energy * attenuation * attenuation * angleAttenuation;
|
||||
else
|
||||
coneLight = light.Comp.Energy * attenuation * attenuation;
|
||||
|
||||
calculatedLight = Math.Max(calculatedLight, coneLight);
|
||||
}
|
||||
}
|
||||
else
|
||||
calculatedLight = light.Comp.Energy * attenuation * attenuation;
|
||||
|
||||
illumination += calculatedLight; //Math.Max(illumination, calculatedLight);
|
||||
}
|
||||
|
||||
return illumination;
|
||||
}
|
||||
|
||||
private void SetPassiveBuff(EntityUid uid, ShadekinState state)
|
||||
{
|
||||
if (!TryComp<PassiveDamageComponent>(uid, out var passive))
|
||||
return;
|
||||
|
||||
if (state == ShadekinState.Extreme || state == ShadekinState.Annoying || state == ShadekinState.High)
|
||||
{
|
||||
// passive.DamageCap = 1;
|
||||
}
|
||||
else if (state == ShadekinState.Low)
|
||||
{
|
||||
// passive.DamageCap = 20;
|
||||
passive.AllowedStates.Clear();
|
||||
passive.AllowedStates.Add(MobState.Alive);
|
||||
passive.Interval = 1f;
|
||||
}
|
||||
else if (state != ShadekinState.Dark)
|
||||
{
|
||||
// passive.DamageCap = 0;
|
||||
passive.AllowedStates.Clear();
|
||||
passive.AllowedStates.Add(MobState.Alive);
|
||||
passive.AllowedStates.Add(MobState.Critical);
|
||||
passive.AllowedStates.Add(MobState.Dead);
|
||||
passive.Interval = 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleNightVision(EntityUid uid, ShadekinState state)
|
||||
{
|
||||
if (state == ShadekinState.Dark)
|
||||
{
|
||||
var nightVisionComponent = EnsureComp<NightVisionComponent>(uid);
|
||||
nightVisionComponent.Color = Color.FromHex("#808080"); // Delta V - Change Night Vision Color
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TryComp<NightVisionComponent>(uid, out var nightVision) && nightVision.IsActive)
|
||||
_flashSystem.Flash(uid, uid, uid, TimeSpan.FromSeconds(0.5 * (int)state), 0.5f);
|
||||
RemComp<NightVisionComponent>(uid);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyLightDamage(EntityUid uid, float dmg)
|
||||
{
|
||||
var damage = new DamageSpecifier();
|
||||
damage.DamageDict.Add("Heat", dmg);
|
||||
_damageable.TryChangeDamage(uid, damage, true, false);
|
||||
|
||||
}
|
||||
|
||||
private void OnRefreshMovementSpeedModifiers(EntityUid uid, ShadekinComponent component, RefreshMovementSpeedModifiersEvent args)
|
||||
{
|
||||
if (component.CurrentState == ShadekinState.Low || component.CurrentState == ShadekinState.Annoying ||
|
||||
component.CurrentState == ShadekinState.Dark || component.CurrentState == ShadekinState.Invalid)
|
||||
return;
|
||||
|
||||
if (!TryComp<MovementSpeedModifierComponent>(uid, out var movement))
|
||||
return;
|
||||
|
||||
var sprintDif = movement.BaseWalkSpeed / movement.BaseSprintSpeed;
|
||||
args.ModifySpeed(1f, sprintDif);
|
||||
}
|
||||
|
||||
private ShadekinState GetStateByThreshold(ShadekinComponent component, float lightExposure)
|
||||
{
|
||||
var returnState = ShadekinState.Dark;
|
||||
|
||||
foreach (var (threshold, shadekinState) in component.Thresholds.Reverse())
|
||||
{
|
||||
if (threshold <= lightExposure)
|
||||
{
|
||||
returnState = shadekinState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return returnState;
|
||||
}
|
||||
|
||||
// Delta V - Begin Shadekin Flash Changes
|
||||
private void GetFlashModifier(EntityUid uid, ShadekinComponent comp, FlashDurationMultiplierEvent args)
|
||||
{
|
||||
if (!TryComp<FlashModifierComponent>(uid, out var flashModifier))
|
||||
return;
|
||||
|
||||
args.Multiplier = flashModifier.Modifier;
|
||||
}
|
||||
|
||||
private void OnShadekinFlashed(EntityUid uid, ShadekinComponent comp, AfterFlashedEvent ev)
|
||||
{
|
||||
RemComp<NightVisionComponent>(uid);
|
||||
}
|
||||
// Delta V - End
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
var query = EntityQueryEnumerator<ShadekinComponent>();
|
||||
while (query.MoveNext(out var uid, out var component))
|
||||
{
|
||||
if (_timing.CurTime < component.NextUpdate)
|
||||
continue;
|
||||
|
||||
component.NextUpdate = _timing.CurTime + component.UpdateCooldown;
|
||||
|
||||
var lightExposure = 0f;
|
||||
|
||||
if (!_container.IsEntityInContainer(uid))
|
||||
lightExposure = GetLightExposure(uid);
|
||||
|
||||
component.CurrentState = GetStateByThreshold(component, lightExposure);
|
||||
|
||||
UpdateAlert(uid, component, (short)component.CurrentState);
|
||||
|
||||
SetPassiveBuff(uid, component.CurrentState);
|
||||
ToggleNightVision(uid, component.CurrentState);
|
||||
|
||||
_speed.RefreshMovementSpeedModifiers(uid);
|
||||
|
||||
if (component.CurrentState == ShadekinState.Extreme)
|
||||
ApplyLightDamage(uid, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,6 @@ using Robust.Shared.Timing;
|
||||
using Content.Shared._DV.Access.Systems;
|
||||
using Content.Shared._DV.Access.Components;
|
||||
using Content.Shared.Mind; // DeltaV - Subdermal ID Cards
|
||||
using Content.Shared.Ninja.Components; // DeltaV
|
||||
using Content.Shared.Revenant.Components; // DeltaV
|
||||
|
||||
namespace Content.Shared.Access.Systems;
|
||||
|
||||
@@ -33,6 +31,7 @@ public sealed class AccessReaderSystem : EntitySystem
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly EmagSystem _emag = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly SharedGameTicker _gameTicker = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
@@ -152,7 +151,7 @@ public sealed class AccessReaderSystem : EntitySystem
|
||||
|
||||
private void OnEmagged(EntityUid uid, AccessReaderComponent reader, ref GotEmaggedEvent args)
|
||||
{
|
||||
if (HasComp<SpaceNinjaComponent>(args.UserUid) || HasComp<RevenantComponent>(args.UserUid)) // DeltaV - Don't break access if its a ninja doing it
|
||||
if (!_emag.CompareFlag(args.Type, EmagType.Interaction)) // DeltaV - emag for lockers etc instead of doorjack
|
||||
return;
|
||||
|
||||
if (!reader.BreakOnAccessBreaker)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Linq;
|
||||
using Content.Shared._DV.Humanoid; // DeltaV
|
||||
using System.Numerics;
|
||||
using Content.Shared._DV.Humanoid;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Sprite;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -16,6 +18,7 @@ public abstract partial class SharedVisualBodySystem : EntitySystem
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly MarkingManager _marking = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly SharedScaleVisualsSystem _scaleVisualsSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -25,6 +28,7 @@ public abstract partial class SharedVisualBodySystem : EntitySystem
|
||||
SubscribeLocalEvent<VisualOrganMarkingsComponent, BodyRelayedEvent<OrganCopyAppearanceEvent>>(OnMarkingsOrganCopyAppearance);
|
||||
SubscribeLocalEvent<VisualOrganComponent, BodyRelayedEvent<ApplyOrganProfileDataEvent>>(OnVisualOrganApplyProfile);
|
||||
SubscribeLocalEvent<VisualOrganMarkingsComponent, BodyRelayedEvent<ApplyOrganMarkingsEvent>>(OnMarkingsOrganApplyMarkings);
|
||||
SubscribeLocalEvent<HumanoidProfileComponent, ApplyOrganProfileDataEvent>(OnApplyOrganProfileData); // Delta V - Taking the solution from CD
|
||||
|
||||
InitializeModifiers();
|
||||
InitializeInitial();
|
||||
@@ -99,6 +103,22 @@ public abstract partial class SharedVisualBodySystem : EntitySystem
|
||||
SetOrganAppearance(ent, other.Data);
|
||||
}
|
||||
|
||||
// Delta V - BEGIN CD Solution
|
||||
private void OnApplyOrganProfileData(Entity<HumanoidProfileComponent> entity, ref ApplyOrganProfileDataEvent args)
|
||||
{
|
||||
var speciesPrototype = _prototype.Index(entity.Comp.Species);
|
||||
if (args.Base == null)
|
||||
return;
|
||||
|
||||
var height = Math.Clamp(MathF.Round(args.Base.Value.Height, 2), speciesPrototype.MinHeight, speciesPrototype.MaxHeight);
|
||||
|
||||
_scaleVisualsSystem.SetSpriteScale(
|
||||
entity.Owner,
|
||||
new Vector2(speciesPrototype.ScaleHeight ? height : 1f, height)
|
||||
);
|
||||
}
|
||||
// Delta V - END
|
||||
|
||||
|
||||
private void OnMarkingsOrganCopyAppearance(Entity<VisualOrganMarkingsComponent> ent, ref BodyRelayedEvent<OrganCopyAppearanceEvent> args)
|
||||
{
|
||||
@@ -128,7 +148,7 @@ public abstract partial class SharedVisualBodySystem : EntitySystem
|
||||
if (ent.Comp.Layer.Equals(HumanoidVisualLayers.Eyes))
|
||||
{
|
||||
// Delta V - Begin Add AppearanceLoaded Event
|
||||
var appearanceLoaded = new AppearanceLoadedEvent(ent.Comp.Profile.EyeColor, ent.Comp.Profile.SkinColor);
|
||||
var appearanceLoaded = new AppearanceLoadedEvent(ent.Comp.Profile.EyeColor);
|
||||
RaiseLocalEvent(args.Body.Owner, ref appearanceLoaded);
|
||||
// Delta V - End
|
||||
SetOrganColor(ent, ent.Comp.Profile.EyeColor);
|
||||
|
||||
@@ -392,6 +392,7 @@ public abstract partial class SharedBuckleSystem
|
||||
if (TryComp<PhysicsComponent>(buckle, out var physics))
|
||||
_physics.ResetDynamics(buckle, physics);
|
||||
|
||||
// TOOD: DV - This fails when you try to buckle the entity you're carrying to something. Figure out why later.
|
||||
DebugTools.AssertEqual(xform.ParentUid, strap.Owner);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,18 +28,4 @@ public readonly partial record struct CargoBountyData
|
||||
Bounty = bounty.ID;
|
||||
Id = $"{bounty.IdPrefix}{uniqueIdentifier:D3}";
|
||||
}
|
||||
// Begin DeltaV bounty claiming
|
||||
[DataField]
|
||||
public string ClaimedBy { get; init; } = string.Empty;
|
||||
|
||||
[DataField]
|
||||
public CargoBountyStatus Status { get; init; } = CargoBountyStatus.Undelivered;
|
||||
}
|
||||
|
||||
public enum CargoBountyStatus
|
||||
{
|
||||
Undelivered,
|
||||
Waiting,
|
||||
OnShuttle,
|
||||
} // End DeltaV bounty claiming
|
||||
|
||||
}
|
||||
|
||||
@@ -94,4 +94,3 @@ public sealed class BountySkipMessage : BoundUserInterfaceMessage
|
||||
BountyId = bountyId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,12 @@ public abstract class SharedEmpSystem : EntitySystem
|
||||
[Dependency] private readonly SharedPvsOverrideSystem _pvs = default!; // Frontier
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!; // Frontier: EMP Blast PVS
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV. Default damage of EMPs, as dertermined by direction. There's no good component to put
|
||||
/// this on so its defined here.
|
||||
/// </summary>
|
||||
private static readonly DamageSpecifier? DefaultEmpDamage = new() { DamageDict = new() { { "Ion", 130 } } };
|
||||
|
||||
private HashSet<EntityUid> _entSet = new();
|
||||
private EntityQuery<EmpResistanceComponent> _resistanceQuery;
|
||||
|
||||
@@ -53,11 +59,12 @@ public abstract class SharedEmpSystem : EntitySystem
|
||||
/// <param name="energyConsumption">The amount of energy consumed by the EMP pulse. In Joule.</param>
|
||||
/// <param name="duration">The duration of the EMP effects.</param>
|
||||
/// <param name="user">The player that caused the effect. Used for predicted audio.</param>
|
||||
public void EmpPulse(MapCoordinates mapCoordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null)
|
||||
/// <param name="damage">DeltaV - The damage that that EMP will do. If not specified or null, will do 130 Ion damage. To do no damage, pass in a DamageSpecifier with no damage types.</param>
|
||||
public void EmpPulse(MapCoordinates mapCoordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
|
||||
{
|
||||
foreach (var uid in _lookup.GetEntitiesInRange(mapCoordinates, range))
|
||||
{
|
||||
TryEmpEffects(uid, energyConsumption, duration, user);
|
||||
TryEmpEffects(uid, energyConsumption, duration, user, damage ?? DefaultEmpDamage); // DeltaV - Add Ion Damage
|
||||
}
|
||||
|
||||
// TODO: replace with PredictedSpawn once it works with animated sprites
|
||||
@@ -85,13 +92,15 @@ public abstract class SharedEmpSystem : EntitySystem
|
||||
/// <param name="energyConsumption">The amount of energy consumed by the EMP pulse.</param>
|
||||
/// <param name="duration">The duration of the EMP effects.</param>
|
||||
/// <param name="user">The player that caused the effect. Used for predicted audio.</param>'
|
||||
public void EmpPulse(EntityCoordinates coordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null, bool predicted = true)
|
||||
/// <param name="damage">DeltaV - The damage that that EMP will do. If not specified or null, will do 130 Ion damage. To do no damage, pass in a DamageSpecifier with no damage types.</param>
|
||||
/// <param name="predicted">Whether this pulse is being replicated on the client.</param>
|
||||
public void EmpPulse(EntityCoordinates coordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null, bool predicted = true) // Delta V - Add ion damage
|
||||
{
|
||||
_entSet.Clear();
|
||||
_lookup.GetEntitiesInRange(coordinates, range, _entSet);
|
||||
foreach (var uid in _entSet)
|
||||
{
|
||||
TryEmpEffects(uid, energyConsumption, duration, user);
|
||||
TryEmpEffects(uid, energyConsumption, duration, user, damage ?? DefaultEmpDamage); // DeltaV - Add Ion Damage
|
||||
}
|
||||
// TODO: replace with PredictedSpawn once it works with animated sprites
|
||||
if (_net.IsServer)
|
||||
@@ -114,31 +123,37 @@ public abstract class SharedEmpSystem : EntitySystem
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to apply the effects of an EMP pulse onto an entity by first raising an <see cref="EmpAttemptEvent"/>, followed by raising a <see cref="EmpPulseEvent"/> on it.
|
||||
/// <br/>
|
||||
/// <br/>DeltaV - In most cases, you will want to use <see cref="EmpPulse"/> instead.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity to apply the EMP effects on.</param>
|
||||
/// <param name="energyConsumption">The amount of energy consumed by the EMP.</param>
|
||||
/// <param name="duration">The duration of the EMP effects.</param>
|
||||
/// <param name="user">The player that caused the EMP. For prediction purposes.</param>
|
||||
/// <param name="damage">DeltaV - The damage that that EMP will do. If null, no damage is done.</param>
|
||||
/// <returns>If the entity was affected by the EMP.</returns>
|
||||
public bool TryEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null)
|
||||
public bool TryEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
|
||||
{
|
||||
var attemptEv = new EmpAttemptEvent();
|
||||
RaiseLocalEvent(uid, ref attemptEv);
|
||||
if (attemptEv.Cancelled)
|
||||
return false;
|
||||
|
||||
return DoEmpEffects(uid, energyConsumption, duration, user);
|
||||
return DoEmpEffects(uid, energyConsumption, duration, user, damage); // DeltaV - Add Ion Damage
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the effects of an EMP pulse onto an entity by raising a <see cref="EmpPulseEvent"/> on it.
|
||||
/// <br/>
|
||||
/// <br/>DeltaV - In most cases, you will want to use <see cref="EmpPulse"/> instead.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity to apply the EMP effects on.</param>
|
||||
/// <param name="energyConsumption">The amount of energy consumed by the EMP.</param>
|
||||
/// <param name="duration">The duration of the EMP effects.</param>
|
||||
/// <param name="user">The player that caused the EMP. For prediction purposes.</param>
|
||||
/// <param name="damage">DeltaV - The damage that that EMP will do. If null, no damage is done.</param>
|
||||
/// <returns>If the entity was affected by the EMP.</returns>
|
||||
public bool DoEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null)
|
||||
public bool DoEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
|
||||
{
|
||||
var strMultiplier = 1f;
|
||||
var durMultiplier = 1f;
|
||||
@@ -147,7 +162,7 @@ public abstract class SharedEmpSystem : EntitySystem
|
||||
strMultiplier = resistance.StrengthMultiplier;
|
||||
durMultiplier = resistance.DurationMultiplier;
|
||||
}
|
||||
var ev = new EmpPulseEvent(energyConsumption * strMultiplier, false, false, duration * durMultiplier, user);
|
||||
var ev = new EmpPulseEvent(energyConsumption * strMultiplier, false, false, duration * durMultiplier, user, damage); // DeltaV - Add Ion Damage
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
// TODO: replace with PredictedSpawn once it works with animated sprites
|
||||
@@ -220,7 +235,7 @@ public record struct EmpAttemptEvent(bool Cancelled);
|
||||
/// <param name="User">The player that caused the EMP. For prediction purposes.</param>
|
||||
|
||||
[ByRefEvent]
|
||||
public record struct EmpPulseEvent(float EnergyConsumption, bool Affected, bool Disabled, TimeSpan Duration, EntityUid? User);
|
||||
public record struct EmpPulseEvent(float EnergyConsumption, bool Affected, bool Disabled, TimeSpan Duration, EntityUid? User, DamageSpecifier? Damage = null); // DeltaV - Added Damage
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an entity after <see cref="EmpDisabledComponent"/> is removed.
|
||||
|
||||
@@ -26,7 +26,6 @@ using System.Linq;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared._Starlight.Flash.Components; // Delta V - For Flash Duration
|
||||
|
||||
namespace Content.Shared.Flash;
|
||||
|
||||
@@ -174,7 +173,7 @@ public abstract class SharedFlashSystem : EntitySystem
|
||||
// Goobstation end
|
||||
|
||||
// don't paralyze, slowdown or convert to rev if the target is immune to flashes
|
||||
if (!_statusEffectsSystem.TryAddStatusEffect<FlashedComponent>(target, FlashedKey, flashDuration * multiplier, true) && !ignoreProtection) //DeltaV: allow flashing to ignore flash protection. Added Flashduration Multiplier
|
||||
if (!_statusEffectsSystem.TryAddStatusEffect<FlashedComponent>(target, FlashedKey, flashDuration, true) && !ignoreProtection) //DeltaV: allow flashing to ignore flash protection
|
||||
return;
|
||||
|
||||
if (stunDuration != null)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Shared._DV.Administration.EntitySystems; // DeltaV - Unorbitable
|
||||
using Content.Shared.Administration.Managers;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Follower.Components;
|
||||
@@ -34,7 +33,6 @@ public sealed class FollowerSystem : EntitySystem
|
||||
[Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!;
|
||||
[Dependency] private readonly INetManager _netMan = default!;
|
||||
[Dependency] private readonly ISharedAdminManager _adminManager = default!;
|
||||
[Dependency] private readonly UnorbitableSystem _unorbitable = default!; // DeltaV - Unorbitable
|
||||
|
||||
private static readonly ProtoId<TagPrototype> ForceableFollowTag = "ForceableFollow";
|
||||
private static readonly ProtoId<TagPrototype> PreventGhostnadoWarpTag = "NotGhostnadoWarpable";
|
||||
@@ -100,11 +98,6 @@ public sealed class FollowerSystem : EntitySystem
|
||||
if (ev.User == ev.Target || IsClientSide(ev.Target))
|
||||
return;
|
||||
|
||||
// DeltaV - Unorbitable START
|
||||
if (!_unorbitable.CanFollow(ev.User, ev.Target))
|
||||
return;
|
||||
// DeltaV END
|
||||
|
||||
if (HasComp<GhostComponent>(ev.User))
|
||||
{
|
||||
var verb = new AlternativeVerb()
|
||||
@@ -194,11 +187,6 @@ public sealed class FollowerSystem : EntitySystem
|
||||
if (follower == entity || TerminatingOrDeleted(entity))
|
||||
return;
|
||||
|
||||
// DeltaV - Unorbitable START
|
||||
if (!_unorbitable.CanFollow(follower, entity))
|
||||
return;
|
||||
// DeltaV END
|
||||
|
||||
// No recursion for you
|
||||
var targetXform = Transform(entity);
|
||||
while (targetXform.ParentUid.IsValid())
|
||||
|
||||
@@ -2,7 +2,8 @@ using Content.Shared.Armor; // DeltaV - Addition of HandHeldArmor
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Camera;
|
||||
using Content.Shared.Cuffs;
|
||||
using Content.Shared.Damage.Systems; // DeltaV - Addition of HandHeldArmor
|
||||
using Content.Shared.Damage; // DeltaV End - Addition of HandHeldArmor
|
||||
using Content.Shared.Damage.Systems; // DeltaV End - Addition of HandHeldArmor
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Projectiles;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System.Numerics; // DeltaV
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Sprite; // DeltaV
|
||||
using Robust.Shared.GameObjects.Components.Localization;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -13,7 +11,6 @@ public sealed class HumanoidProfileSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly GrammarSystem _grammar = default!;
|
||||
[Dependency] private readonly SharedScaleVisualsSystem _scale = default!; // DeltaV
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -31,7 +28,6 @@ public sealed class HumanoidProfileSystem : EntitySystem
|
||||
ent.Comp.Age = profile.Age;
|
||||
ent.Comp.Species = profile.Species;
|
||||
ent.Comp.Sex = profile.Sex;
|
||||
ent.Comp.Height = profile.Height; // DeltaV
|
||||
Dirty(ent);
|
||||
|
||||
var sexChanged = new SexChangedEvent(ent.Comp.Sex, profile.Sex);
|
||||
@@ -41,15 +37,6 @@ public sealed class HumanoidProfileSystem : EntitySystem
|
||||
{
|
||||
_grammar.SetGender((ent, grammar), profile.Gender);
|
||||
}
|
||||
|
||||
// START DeltaV - Apply profile/species size
|
||||
// Assume 1.0 scale unless the original scale exists (blame Allulalo)
|
||||
var scale = Vector2.One;
|
||||
if (TryComp<ScaleVisualsComponent>(ent, out var scaledVisuals) && scaledVisuals.OriginalScale is { } originalScale)
|
||||
scale = originalScale;
|
||||
|
||||
_scale.SetSpriteScale(ent, scale);
|
||||
// END DeltaV
|
||||
}
|
||||
|
||||
private void OnExamined(Entity<HumanoidProfileComponent> ent, ref ExaminedEvent args)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Numerics; // DeltaV
|
||||
using Content.Shared.Body;
|
||||
using Content.Shared.Dataset;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
@@ -112,7 +111,7 @@ public sealed partial class SpeciesPrototype : IPrototype
|
||||
/// The base height scale for this species
|
||||
/// </summary>
|
||||
[DataField("baseScale")]
|
||||
public Vector2 BaseScale = new(1f, 1f);
|
||||
public System.Numerics.Vector2 BaseScale = new(1f, 1f);
|
||||
// End DV - CD Character Records shouldn't nuke species heights
|
||||
|
||||
// Begin CD - Character Records
|
||||
@@ -120,13 +119,13 @@ public sealed partial class SpeciesPrototype : IPrototype
|
||||
/// The minimum height for this species
|
||||
/// </summary>
|
||||
[DataField("minHeight")]
|
||||
public float MinHeight = 0.8f; // DeltaV
|
||||
public float MinHeight = 0.9f; // DeltaV - less trolling with the heights
|
||||
|
||||
/// <summary>
|
||||
/// The maximum height for this species
|
||||
/// </summary>
|
||||
[DataField("maxHeight")]
|
||||
public float MaxHeight = 1.2f; // DeltaV
|
||||
public float MaxHeight = 1.1f; // DeltaV - less trolling with the heights
|
||||
|
||||
/// <summary>
|
||||
/// The default height for this species
|
||||
|
||||
@@ -68,7 +68,6 @@ namespace Content.Shared.Input
|
||||
public static readonly BoundKeyFunction TakeScreenshotNoUI = "TakeScreenshotNoUI";
|
||||
public static readonly BoundKeyFunction ToggleFullscreen = "ToggleFullscreen";
|
||||
public static readonly BoundKeyFunction Point = "Point";
|
||||
public static readonly BoundKeyFunction OfferItem = "OfferItem"; // Floofstation
|
||||
public static readonly BoundKeyFunction ZoomOut = "ZoomOut";
|
||||
public static readonly BoundKeyFunction ZoomIn = "ZoomIn";
|
||||
public static readonly BoundKeyFunction ResetZoom = "ResetZoom";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Shared._DV.Overlays; // DeltaV
|
||||
using Content.Shared._DV.Overlays;
|
||||
using Content.Shared._DV.Psionics.Events; // DeltaV
|
||||
using Content.Shared.Armor;
|
||||
using Content.Shared.Atmos;
|
||||
@@ -85,15 +85,13 @@ public partial class InventorySystem
|
||||
SubscribeLocalEvent<InventoryComponent, WieldAttemptEvent>(RefRelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, UnwieldAttemptEvent>(RefRelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, IngestionAttemptEvent>(RefRelayInventoryEvent);
|
||||
// DeltaV Start
|
||||
// Psionic Events
|
||||
// DeltaV Start - Psionic Events
|
||||
SubscribeLocalEvent<InventoryComponent, DispelledEvent>(RefRelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, PsionicPowerUseAttemptEvent>(RefRelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, TargetedByPsionicPowerEvent>(RefRelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, NoosphericFryEvent>(RefRelayInventoryEvent);
|
||||
// Heavy Clothing
|
||||
SubscribeLocalEvent<InventoryComponent, WeightlessnessChangedEvent>(RefRelayInventoryEvent);
|
||||
// DeltaV End
|
||||
SubscribeLocalEvent<InventoryComponent, WeightlessnessChangedEvent>(RefRelayInventoryEvent); // Heavy Clothing
|
||||
// DeltaV End - Psionic Events
|
||||
|
||||
// Eye/vision events
|
||||
SubscribeLocalEvent<InventoryComponent, CanSeeAttemptEvent>(RelayInventoryEvent);
|
||||
|
||||
@@ -103,22 +103,6 @@ public abstract class SharedItemSystem : EntitySystem
|
||||
VisualsChanged(uid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - clear item visuals
|
||||
/// </summary>
|
||||
public void ClearVisuals(Entity<ItemComponent?> ent)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp))
|
||||
return;
|
||||
|
||||
ent.Comp.RsiPath = null;
|
||||
ent.Comp.InhandVisuals = new();
|
||||
ent.Comp.HeldPrefix = null;
|
||||
|
||||
Dirty(ent, ent.Comp);
|
||||
VisualsChanged(ent.Owner);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnHandInteract(EntityUid uid, ItemComponent component, InteractHandEvent args)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
|
||||
using Content.Shared.Chemistry.Components; // DeltaV - Health Analyzer Plus
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.MedicalScanner;
|
||||
@@ -30,12 +29,11 @@ public struct HealthAnalyzerUiState
|
||||
public bool? ScanMode;
|
||||
public bool? Bleeding;
|
||||
public bool? Unrevivable;
|
||||
public readonly Solution? BloodSolution; // DeltaV - Health Analyzer Plus
|
||||
public MedicalRecord? MedicalRecord; // DeltaV - Medical Records
|
||||
|
||||
public HealthAnalyzerUiState() {}
|
||||
|
||||
public HealthAnalyzerUiState(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable, Solution? bloodSolution, MedicalRecord? medicalRecord = null) // DeltaV - Health Analyzer Plus, Medical Records
|
||||
public HealthAnalyzerUiState(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable, MedicalRecord? medicalRecord = null) // DeltaV - Medical Records
|
||||
{
|
||||
TargetEntity = targetEntity;
|
||||
Temperature = temperature;
|
||||
@@ -43,7 +41,6 @@ public struct HealthAnalyzerUiState
|
||||
ScanMode = scanMode;
|
||||
Bleeding = bleeding;
|
||||
Unrevivable = unrevivable;
|
||||
BloodSolution = bloodSolution; // DeltaV - Health Analyzer Plus
|
||||
MedicalRecord = medicalRecord; // DeltaV - Medical Records
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using Content.Shared._DV.Body.Components; // DeltaV
|
||||
using Content.Shared._DV.Body.Systems; // DeltaV
|
||||
using Content.Shared._ST.Interaction; // Stellar - interaction particles
|
||||
using Content.Shared._Floof.OfferItem; // Floof
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Alert;
|
||||
@@ -12,7 +9,6 @@ using Content.Shared.Database;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Humanoid; // DeltaV
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Input;
|
||||
using Content.Shared.Interaction;
|
||||
@@ -58,7 +54,6 @@ public sealed class PullingSystem : EntitySystem
|
||||
[Dependency] private readonly HeldSpeedModifierSystem _clothingMoveSpeed = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedVirtualItemSystem _virtual = default!;
|
||||
[Dependency] private readonly SmallCharacterSystem _smallCharacter = default!; // DeltaV
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -122,11 +117,10 @@ public sealed class PullingSystem : EntitySystem
|
||||
if (TryComp(args.PullerUid, out PullerComponent? pullerComp) && !pullerComp.NeedsHands)
|
||||
return;
|
||||
|
||||
if (!_virtual.TrySpawnVirtualItemInHand(args.PulledUid, uid, out var virt)) // Floofstation - store item
|
||||
if (!_virtual.TrySpawnVirtualItemInHand(args.PulledUid, uid))
|
||||
{
|
||||
DebugTools.Assert("Unable to find available hand when starting pulling??");
|
||||
}
|
||||
EnsureComp<OfferableVirtualItemComponent>(virt.Value); // Floofstation - add a special component to allow offering it
|
||||
}
|
||||
|
||||
private void HandlePullStopped(EntityUid uid, HandsComponent component, PullStoppedMessage args)
|
||||
@@ -299,14 +293,6 @@ public sealed class PullingSystem : EntitySystem
|
||||
|
||||
private void OnRefreshMovespeed(EntityUid uid, PullerComponent component, RefreshMovementSpeedModifiersEvent args)
|
||||
{
|
||||
// BEGIN DeltaV - Slow if smaller puller
|
||||
if (TryComp<SmallCharacterComponent>(uid, out var smol))
|
||||
{
|
||||
var sizePenalty = _smallCharacter.ApplyPullSpeedPenalty((uid, smol), component.Pulling);
|
||||
args.ModifySpeed(sizePenalty, sizePenalty);
|
||||
}
|
||||
// END DeltaV
|
||||
|
||||
if (TryComp<HeldSpeedModifierComponent>(component.Pulling, out var heldMoveSpeed) && component.Pulling.HasValue)
|
||||
{
|
||||
var (walkMod, sprintMod) =
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Bed.Sleep;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Item.PseudoItem;
|
||||
@@ -23,8 +24,7 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!; // Floofstation
|
||||
[Dependency] private readonly SharedHandsSystem _hands = default!; // Floofstation
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
private readonly ProtoId<TagPrototype> PreventTag = "PreventLabel";
|
||||
private readonly EntProtoId SleepActionId = "ActionSleep"; // The action used for sleeping inside bags. Currently uses the default sleep action (same as beds)
|
||||
@@ -116,35 +116,17 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
|
||||
protected virtual void OnGettingPickedUpAttempt(EntityUid uid, PseudoItemComponent component,
|
||||
GettingPickedUpAttemptEvent args)
|
||||
{
|
||||
args.Cancel(); // Floof - this is a terrible idea. This triggers every time ANY system checks if a pseudo-item can be picked up.
|
||||
// WHY DID YOU DO THAT, NYANOTRASEN???
|
||||
if (args.User == args.Item)
|
||||
return;
|
||||
|
||||
// if (args.User == args.Item)
|
||||
// return;
|
||||
//
|
||||
// _transform.AttachToGridOrMap(uid);
|
||||
// args.Cancel();
|
||||
_transform.AttachToGridOrMap(uid);
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnDropAttempt(EntityUid uid, PseudoItemComponent component, DropAttemptEvent args)
|
||||
{
|
||||
if (!component.Active)
|
||||
return;
|
||||
|
||||
// Floof - we try to get the containing container and try to drop it into it
|
||||
// If possible, we do it, since a bagged cat probably can put things back into the bag just like they can pick them up.
|
||||
string? failReason = null;
|
||||
if (_hands.GetActiveItem(uid) is { Valid: true, } droppedItem
|
||||
&& _container.TryGetContainingContainer(Transform(uid).ParentUid, uid, out var pseudoItemContainer)
|
||||
&& TryComp<StorageComponent>(pseudoItemContainer.Owner, out var targetStorage)
|
||||
&& _storage.CanInsert(pseudoItemContainer.Owner, droppedItem, out failReason, targetStorage, ignoreStacks: true)
|
||||
)
|
||||
_storage.Insert(pseudoItemContainer.Owner, droppedItem, out _, uid, targetStorage, stackAutomatically: false);
|
||||
|
||||
if (failReason != null)
|
||||
_popupSystem.PopupEntity(Loc.GetString(failReason), uid, uid);
|
||||
|
||||
args.Cancel();
|
||||
if (component.Active)
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnInsertAttempt(EntityUid uid, PseudoItemComponent component,
|
||||
@@ -159,9 +141,8 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
|
||||
// Prevents moving within the bag :)
|
||||
private void OnInteractAttempt(EntityUid uid, PseudoItemComponent component, InteractionAttemptEvent args)
|
||||
{
|
||||
// Floof - why the fuck.
|
||||
// if (args.Uid == args.Target && component.Active)
|
||||
// args.Cancelled = true;
|
||||
if (args.Uid == args.Target && component.Active)
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnDoAfter(EntityUid uid, PseudoItemComponent component, DoAfterEvent args)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Content.Shared.Psionics.Glimmer
|
||||
get { return _glimmer; }
|
||||
set
|
||||
{
|
||||
var newGlimmer = _enabled ? Math.Clamp(value, 0, 1000) : 0;
|
||||
var newGlimmer = _enabled ? Math.Clamp(value, 0, 2000) : 0;
|
||||
if (_glimmer == newGlimmer)
|
||||
return;
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public sealed partial class ParcelWrappingSystem
|
||||
if (target == user)
|
||||
{
|
||||
var selfMsg = Loc.GetString("parcel-wrap-popup-being-wrapped-self");
|
||||
_popup.PopupEntity(selfMsg, user, user);
|
||||
_popup.PopupClient(selfMsg, user, user);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -143,7 +143,7 @@ public sealed partial class ParcelWrappingSystem
|
||||
|
||||
// Spawn the actual parcel entity.
|
||||
var targetTransform = Transform(target);
|
||||
var spawned = SpawnAtPosition(GetParcelPrototype(wrapper, target), targetTransform.Coordinates);
|
||||
var spawned = Spawn(GetParcelPrototype(wrapper, target), targetTransform.Coordinates);
|
||||
_transform.SetLocalRotation(spawned, targetTransform.LocalRotation);
|
||||
|
||||
// If the target is in a container, try to put the parcel in its place in the container.
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace Content.Shared.Preferences
|
||||
_traitPreferences = traitPreferences;
|
||||
_loadouts = loadouts;
|
||||
// Begin CD - Character Records
|
||||
Height = height; // This is the user-set scale on the profile editor. Not actual height measurements.
|
||||
Height = height;
|
||||
CDCharacterRecords = cdCharacterRecords;
|
||||
// End CD - Character Records
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems; // DeltaV
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Doors.Components;
|
||||
@@ -20,7 +19,6 @@ namespace Content.Shared.Remotes.EntitySystems;
|
||||
public abstract class SharedDoorRemoteSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAirlockSystem _airlock = default!;
|
||||
[Dependency] private readonly AccessReaderSystem _accessReader = default!; // DeltaV
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedDoorSystem _doorSystem = default!;
|
||||
[Dependency] private readonly SharedElectrocutionSystem _electrify = default!;
|
||||
@@ -98,19 +96,6 @@ public abstract class SharedDoorRemoteSystem : EntitySystem
|
||||
else if (entity.Comp.RequireTagWhitelist)
|
||||
return;
|
||||
|
||||
// Begin DeltaV - Emergency access only bypasses open/close; bolting and toggling emergency access still require actual access.
|
||||
if (entity.Comp.Mode != OperatingMode.OpenClose
|
||||
&& accessComponent != null
|
||||
&& !_accessReader.IsAllowed(accessTarget, args.Target.Value, accessComponent))
|
||||
{
|
||||
if (isAirlock)
|
||||
_doorSystem.Deny(args.Target.Value, doorComp, user: args.User, predicted: true);
|
||||
|
||||
_popup.PopupClient(Loc.GetString("door-remote-denied"), args.User, args.User);
|
||||
return;
|
||||
}
|
||||
// End DeltaV
|
||||
|
||||
switch (entity.Comp.Mode)
|
||||
{
|
||||
case OperatingMode.OpenClose:
|
||||
|
||||
@@ -32,7 +32,7 @@ public sealed partial class RevenantComponent : Component
|
||||
public string SpawnOnDeathPrototype = "EctoplasmRevenant"; // DeltaV
|
||||
|
||||
[DataField("stasisTime"), ViewVariables(VVAccess.ReadWrite)] // Begin Imp Changes
|
||||
public TimeSpan StasisTime = TimeSpan.FromSeconds(100); // DeltaV - change from 60 to 100s
|
||||
public TimeSpan StasisTime = TimeSpan.FromSeconds(60);
|
||||
|
||||
/// <summary>
|
||||
/// If true, only bible users can exorcise this revenant
|
||||
@@ -50,7 +50,7 @@ public sealed partial class RevenantComponent : Component
|
||||
/// grinder will explode.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool GrindingRequiresSalt = false; // End Imp Changes - DeltaV - true to false
|
||||
public bool GrindingRequiresSalt = true; // End Imp Changes
|
||||
|
||||
/// <summary>
|
||||
/// The entity's current max amount of essence. Can be increased
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared._CD.Silicons.Borgs; // CosmicDrift - borg subtypes
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Components;
|
||||
@@ -96,6 +97,10 @@ public abstract partial class SharedBorgSwitchableTypeSystem : EntitySystem // D
|
||||
_userInterface.CloseUi((ent.Owner, null), BorgSwitchableTypeUiKey.SelectBorgType);
|
||||
|
||||
UpdateEntityAppearance(ent);
|
||||
|
||||
// AL - event for subtype system, always runs at end of borg type code
|
||||
var ev = new AfterBorgTypeSelectEvent();
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
}
|
||||
|
||||
protected void UpdateEntityAppearance(Entity<BorgSwitchableTypeComponent> entity)
|
||||
@@ -120,24 +125,25 @@ public abstract partial class SharedBorgSwitchableTypeSystem : EntitySystem // D
|
||||
{
|
||||
footstepModifier.FootstepSoundCollection = prototype.FootstepCollection;
|
||||
}
|
||||
|
||||
if (prototype.SpriteBodyMovementState is { } movementState)
|
||||
{
|
||||
var spriteMovement = EnsureComp<SpriteMovementComponent>(entity);
|
||||
spriteMovement.NoMovementLayers.Clear();
|
||||
spriteMovement.NoMovementLayers["movement"] = new PrototypeLayerData
|
||||
{
|
||||
State = prototype.SpriteBodyState,
|
||||
};
|
||||
spriteMovement.MovementLayers.Clear();
|
||||
spriteMovement.MovementLayers["movement"] = new PrototypeLayerData
|
||||
{
|
||||
State = movementState,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
RemComp<SpriteMovementComponent>(entity);
|
||||
}
|
||||
// Start CosmicDrift Changes - Moved to BorgSwitchableTypeSystem.cs
|
||||
// if (prototype.SpriteBodyMovementState is { } movementState)
|
||||
// {
|
||||
// var spriteMovement = EnsureComp<SpriteMovementComponent>(entity);
|
||||
// spriteMovement.NoMovementLayers.Clear();
|
||||
// spriteMovement.NoMovementLayers["movement"] = new PrototypeLayerData
|
||||
// {
|
||||
// State = prototype.SpriteBodyState,
|
||||
// };
|
||||
// spriteMovement.MovementLayers.Clear();
|
||||
// spriteMovement.MovementLayers["movement"] = new PrototypeLayerData
|
||||
// {
|
||||
// State = movementState,
|
||||
// };
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// RemComp<SpriteMovementComponent>(entity);
|
||||
// }
|
||||
// End CosmicDrift Changes - Moved to BorgSwitchableTypeSystem.cs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,27 +25,11 @@ public sealed partial class ScaleVisualsComponent : Component
|
||||
[ViewVariables]
|
||||
public Vector2? OriginalScale;
|
||||
|
||||
// Delta V Addition
|
||||
/// <summary>
|
||||
/// DeltaV - Contains the species scale. Set dynamically by
|
||||
/// baseScale in the Species prototype.
|
||||
/// Base Scale of the Species, which we use to set a new height relative to this.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
[ViewVariables]
|
||||
public Vector2 SpeciesScale = new(1f, 1f);
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - Contains the user-defined scale from the character creation
|
||||
/// screen.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
[ViewVariables]
|
||||
public Vector2 ProfileScale = new(1f, 1f);
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - Contains the computer scale from applying Scale, SpeciesScale, and ProfileScale.
|
||||
/// This will contain the actual scale after all modifiers are applied.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
[ViewVariables]
|
||||
public Vector2 ComputedScale;
|
||||
public Vector2 SpeciesScale = Vector2.One;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Humanoid; // DeltaV
|
||||
using Robust.Shared.Prototypes; // DeltaV
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Sprite;
|
||||
@@ -8,7 +6,6 @@ namespace Content.Shared.Sprite;
|
||||
public abstract class SharedScaleVisualsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!; // DeltaV
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -42,28 +39,15 @@ public abstract class SharedScaleVisualsSystem : EntitySystem
|
||||
{
|
||||
var comp = EnsureComp<ScaleVisualsComponent>(uid);
|
||||
comp.Scale = scale;
|
||||
|
||||
// BEGIN DeltaV - Apply species and profile height
|
||||
// We have to ensure this is idempotent so that if it gets applied more than once
|
||||
// the sprite size at the end is the same.
|
||||
if (TryComp<HumanoidProfileComponent>(uid, out var profile))
|
||||
{
|
||||
var speciesProto = _proto.Index(profile.Species);
|
||||
comp.SpeciesScale = speciesProto.BaseScale;
|
||||
scale *= comp.SpeciesScale; // Apply both species scale and character-defined height
|
||||
|
||||
Vector2 profileHeight = new(profile.Height, profile.Height);
|
||||
comp.ProfileScale = profileHeight;
|
||||
scale *= comp.ProfileScale;
|
||||
}
|
||||
|
||||
comp.ComputedScale = scale; // Nice to know what the computed size is in case of bugs
|
||||
// END DeltaV
|
||||
|
||||
Dirty(uid, comp);
|
||||
|
||||
// Delta V - Begin Species Scaling
|
||||
// 120% species scale => add 0.2 to scale
|
||||
var newScale = scale + comp.SpeciesScale - Vector2.One;
|
||||
// Delta V - End Species Scaling
|
||||
|
||||
var appearanceComponent = EnsureComp<AppearanceComponent>(uid);
|
||||
_appearance.SetData(uid, ScaleVisuals.Scale, scale, appearanceComponent);
|
||||
_appearance.SetData(uid, ScaleVisuals.Scale, newScale /* Delta V - Custom Species Scale */, appearanceComponent);
|
||||
|
||||
// Raise an event for content use.
|
||||
var ev = new ScaleEntityEvent(uid, scale);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Stealth.Components;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -188,20 +188,12 @@ public abstract class SharedStorageSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
// Begin DeltaV - the grid check excludes the item being resized because it's already in the storage which defeats the purpose so yoink it out to remove that
|
||||
storage.StoredItems.Remove(itemEnt.Owner);
|
||||
UpdateOccupied((container.Owner, storage));
|
||||
|
||||
if (ItemFitsInGridLocation((itemEnt.Owner, itemEnt.Comp), (container.Owner, storage), loc))
|
||||
{
|
||||
storage.StoredItems.Add(itemEnt.Owner, loc);
|
||||
UpdateOccupied((container.Owner, storage));
|
||||
}
|
||||
else
|
||||
if (!ItemFitsInGridLocation((itemEnt.Owner, itemEnt.Comp), (container.Owner, storage), loc))
|
||||
{
|
||||
ContainerSystem.Remove(itemEnt.Owner, container, force: true);
|
||||
}
|
||||
// End DeltaV - the grid check excludes the item being resized because it's already in the storage which defeats the purpose so yoink it out to remove that
|
||||
}
|
||||
|
||||
private void OnNestedStorageCvar(bool obj)
|
||||
|
||||
@@ -28,4 +28,10 @@ public sealed partial class EmpOnTriggerComponent : BaseXOnTriggerComponent
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan DisableDuration = TimeSpan.FromSeconds(60);
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV - The damage dealt to silicons instead of draining their power cells
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public DamageSpecifier? Damage;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user