Skip to content

Commit

Permalink
Merge branch 'master' into lavaland-ops
Browse files Browse the repository at this point in the history
Signed-off-by: deltanedas <[email protected]>
  • Loading branch information
deltanedas authored Dec 10, 2024
2 parents e1d024d + 3a1c59e commit 7d5cae7
Show file tree
Hide file tree
Showing 85 changed files with 3,147 additions and 1,097 deletions.
24 changes: 21 additions & 3 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,36 @@
# C# code
/Content.*/ @DeltaV-Station/maintainers

# Any assets
/Resources/ @DeltaV-Station/maintainers

# Server config files
/Resources/ConfigPresets/ @MilonPL

# YML files
/Resources/*.yml @DeltaV-Station/yaml-maintainers
/Resources/**/*.yml @DeltaV-Station/yaml-maintainers

# Sprites
/Resources/Textures/ @IamVelcroboy
/Resources/Textures/ @DeltaV-Station/direction

# Lobby art and music - automatically direction issues since its immediately visible to players
/Resources/Audio/Lobby/ @DeltaV-Station/game-directors
/Resources/Textures/LobbyScreens/ @DeltaV-Station/game-directors
/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

# Server rules
/Resources/ServerInfo/Guidebook/DeltaV/Rules/ @DeltaV-Station/head-administrators

# Tools and scripts
/Tools/ @deltanedas @MilonPL

# Workflows, codeowners, templates, etc.
/.github/ @deltanedas @MilonPL

# Standalone files in the root repo
/* @deltanedas
9 changes: 4 additions & 5 deletions Content.Client/DeltaV/AACTablet/UI/AACBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using Content.Shared.DeltaV.AACTablet;
using Content.Shared.DeltaV.QuickPhrase;
using Robust.Shared.Prototypes;

namespace Content.Client.DeltaV.AACTablet.UI;

public sealed class AACBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;

[ViewVariables]
private AACWindow? _window;

Expand All @@ -18,21 +17,21 @@ protected override void Open()
{
base.Open();
_window?.Close();
_window = new AACWindow(this, _prototypeManager);
_window = new AACWindow();
_window.OpenCentered();

_window.PhraseButtonPressed += OnPhraseButtonPressed;
_window.OnClose += Close;
}

private void OnPhraseButtonPressed(string phraseId)
private void OnPhraseButtonPressed(ProtoId<QuickPhrasePrototype> phraseId)
{
SendMessage(new AACTabletSendPhraseMessage(phraseId));
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_window?.Dispose();
_window?.Orphan();
}
}
2 changes: 1 addition & 1 deletion Content.Client/DeltaV/AACTablet/UI/AACWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
MinSize="540 300">
<ScrollContainer HScrollEnabled="False" Name="WindowBody">
</ScrollContainer>
</controls:FancyWindow>
</controls:FancyWindow>
54 changes: 22 additions & 32 deletions Content.Client/DeltaV/AACTablet/UI/AACWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,26 @@ namespace Content.Client.DeltaV.AACTablet.UI;
[GenerateTypedNameReferences]
public sealed partial class AACWindow : FancyWindow
{
private IPrototypeManager _prototypeManager;
public event Action<string>? PhraseButtonPressed;
[Dependency] private readonly IPrototypeManager _prototype = default!;
public event Action<ProtoId<QuickPhrasePrototype>>? PhraseButtonPressed;

public AACWindow(AACBoundUserInterface ui, IPrototypeManager prototypeManager)
private const float SpaceWidth = 10f;
private const float ParentWidth = 540f;
private const int ColumnCount = 4;

private const int ButtonWidth =
(int)((ParentWidth - SpaceWidth * 2) / ColumnCount - SpaceWidth * ((ColumnCount - 1f) / ColumnCount));

public AACWindow()
{
RobustXamlLoader.Load(this);
_prototypeManager = prototypeManager;
PopulateGui(ui);
IoCManager.InjectDependencies(this);
PopulateGui();
}

private void PopulateGui(AACBoundUserInterface ui)
private void PopulateGui()
{
var loc = IoCManager.Resolve<ILocalizationManager>();
var phrases = _prototypeManager.EnumeratePrototypes<QuickPhrasePrototype>().ToList();
var phrases = _prototype.EnumeratePrototypes<QuickPhrasePrototype>().ToList();

// take ALL phrases and turn them into tabs and groups, so the buttons are sorted and tabbed
var sortedTabs = phrases
Expand All @@ -38,7 +44,7 @@ private void PopulateGui(AACBoundUserInterface ui)
.OrderBy(gg => gg.Key)
.ToDictionary(
gg => gg.Key,
gg => gg.OrderBy(p => loc.GetString(p.Text)).ToList()
gg => gg.OrderBy(p => Loc.GetString(p.Text)).ToList()
)
);

Expand All @@ -49,11 +55,10 @@ private void PopulateGui(AACBoundUserInterface ui)
private TabContainer CreateTabContainer(Dictionary<string, Dictionary<string, List<QuickPhrasePrototype>>> sortedTabs)
{
var tabContainer = new TabContainer();
var loc = IoCManager.Resolve<ILocalizationManager>();

foreach (var tab in sortedTabs)
{
var tabName = loc.GetString(tab.Key);
var tabName = Loc.GetString(tab.Key);
var boxContainer = CreateBoxContainerForTab(tab.Value);
tabContainer.AddChild(boxContainer);
tabContainer.SetTabTitle(tabContainer.ChildCount - 1, tabName);
Expand All @@ -64,7 +69,7 @@ private TabContainer CreateTabContainer(Dictionary<string, Dictionary<string, Li

private BoxContainer CreateBoxContainerForTab(Dictionary<string, List<QuickPhrasePrototype>> groups)
{
var boxContainer = new BoxContainer()
var boxContainer = new BoxContainer
{
HorizontalExpand = true,
Orientation = BoxContainer.LayoutOrientation.Vertical
Expand All @@ -81,7 +86,7 @@ private BoxContainer CreateBoxContainerForTab(Dictionary<string, List<QuickPhras
return boxContainer;
}

private Label CreateHeaderForGroup(string groupName)
private static Label CreateHeaderForGroup(string groupName)
{
var header = new Label
{
Expand All @@ -96,13 +101,12 @@ private Label CreateHeaderForGroup(string groupName)

private GridContainer CreateButtonContainerForGroup(List<QuickPhrasePrototype> phrases)
{
var loc = IoCManager.Resolve<ILocalizationManager>();
var buttonContainer = CreateButtonContainer();
foreach (var phrase in phrases)
{
var text = loc.GetString(phrase.Text);
var text = Loc.GetString(phrase.Text);
var button = CreatePhraseButton(text, phrase.StyleClass);
button.OnPressed += _ => OnPhraseButtonPressed(phrase.ID);
button.OnPressed += _ => OnPhraseButtonPressed(new ProtoId<QuickPhrasePrototype>(phrase.ID));
buttonContainer.AddChild(button);
}
return buttonContainer;
Expand All @@ -121,11 +125,10 @@ private static GridContainer CreateButtonContainer()

private static Button CreatePhraseButton(string text, string styleClass)
{
var buttonWidth = GetButtonWidth();
var phraseButton = new Button
{
Access = AccessLevel.Public,
MaxSize = new Vector2(buttonWidth, buttonWidth),
MaxSize = new Vector2(ButtonWidth, ButtonWidth),
ClipText = false,
HorizontalExpand = true,
StyleClasses = { styleClass }
Expand All @@ -142,20 +145,7 @@ private static Button CreatePhraseButton(string text, string styleClass)
return phraseButton;
}

private static int GetButtonWidth()
{
var spaceWidth = 10;
var parentWidth = 540;
var columnCount = 4;

var paddingSize = spaceWidth * 2;
var gutterScale = (columnCount - 1) / columnCount;
var columnWidth = (parentWidth - paddingSize) / columnCount;
var buttonWidth = columnWidth - spaceWidth * gutterScale;
return buttonWidth;
}

private void OnPhraseButtonPressed(string phraseId)
private void OnPhraseButtonPressed(ProtoId<QuickPhrasePrototype> phraseId)
{
PhraseButtonPressed?.Invoke(phraseId);
}
Expand Down
5 changes: 5 additions & 0 deletions Content.IntegrationTests/Tests/EntityTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ await server.WaitPost(() =>
if (protoId == "MobHumanSpaceNinja")
continue;

// TODO fix tests properly upstream
// Fails due to audio components made when making anouncements
if (protoId == "StandardNanotrasenStation")
continue;

var count = server.EntMan.EntityCount;
var clientCount = client.EntMan.EntityCount;
EntityUid uid = default;
Expand Down
6 changes: 3 additions & 3 deletions Content.Server/Cargo/Systems/PricingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace Content.Server.Cargo.Systems;
/// <summary>
/// This handles calculating the price of items, and implements two basic methods of pricing materials.
/// </summary>
public sealed class PricingSystem : EntitySystem
public sealed partial class PricingSystem : EntitySystem // DeltaV - Made partial
{
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IConsoleHost _consoleHost = default!;
Expand Down Expand Up @@ -208,7 +208,7 @@ public double GetEstimatedPrice(EntityPrototype prototype)

// TODO: Proper container support.

return price;
return ApplyPrototypePriceModifier(prototype, price); // DeltaV
}

/// <summary>
Expand Down Expand Up @@ -254,7 +254,7 @@ public double GetPrice(EntityUid uid, bool includeContents = true)
}
}

return price;
return ApplyPriceModifier(uid, price); // DeltaV
}

private double GetMaterialsPrice(EntityUid uid)
Expand Down
6 changes: 4 additions & 2 deletions Content.Server/DeltaV/AACTablet/AACTabletComponent.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;

namespace Content.Server.DeltaV.AACTablet;

[RegisterComponent]
[RegisterComponent, AutoGenerateComponentPause]
public sealed partial class AACTabletComponent : Component
{
// Minimum time between each phrase, to prevent spam
[DataField]
public TimeSpan Cooldown = TimeSpan.FromSeconds(1);

// Time that the next phrase can be sent.
[DataField]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan NextPhrase;
}
26 changes: 11 additions & 15 deletions Content.Server/DeltaV/AACTablet/AACTabletSystem.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Content.Server.Chat.Systems;
using Content.Server.Speech.Components;
using Content.Shared.DeltaV.AACTablet;
using Content.Shared.DeltaV.QuickPhrase;
using Content.Shared.IdentityManagement;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
Expand All @@ -11,40 +10,37 @@ namespace Content.Server.DeltaV.AACTablet;
public sealed class AACTabletSystem : EntitySystem
{
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly ILocalizationManager _loc = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AACTabletComponent, AACTabletSendPhraseMessage>(OnSendPhrase);
}

private void OnSendPhrase(EntityUid uid, AACTabletComponent component, AACTabletSendPhraseMessage message)
private void OnSendPhrase(Entity<AACTabletComponent> ent, ref AACTabletSendPhraseMessage message)
{
if (component.NextPhrase > Timing.CurTime)
if (ent.Comp.NextPhrase > _timing.CurTime)
return;

// the AAC tablet uses the name of the person who pressed the tablet button
// for quality of life
var senderName = Identity.Entity(message.Actor, EntityManager);
var speakerName = Loc.GetString("speech-name-relay",
("speaker", Name(uid)),
("speaker", Name(ent)),
("originalName", senderName));

if (!_prototypeManager.TryIndex<QuickPhrasePrototype>(message.PhraseID, out var phrase))
if (!_prototype.TryIndex(message.PhraseId, out var phrase))
return;

EnsureComp<VoiceOverrideComponent>(uid).NameOverride = speakerName;
EnsureComp<VoiceOverrideComponent>(ent).NameOverride = speakerName;

_chat.TrySendInGameICMessage(uid,
_loc.GetString(phrase.Text),
_chat.TrySendInGameICMessage(ent,
Loc.GetString(phrase.Text),
InGameICChatType.Speak,
hideChat: false,
nameOverride: speakerName);

var curTime = Timing.CurTime;
component.NextPhrase = curTime + component.Cooldown;
var curTime = _timing.CurTime;
ent.Comp.NextPhrase = curTime + ent.Comp.Cooldown;
}
}
4 changes: 4 additions & 0 deletions Content.Server/DeltaV/Cabinet/SpareIDSafeComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Content.Server.DeltaV.Cabinet;

[RegisterComponent]
public sealed partial class SpareIDSafeComponent : Component;
14 changes: 14 additions & 0 deletions Content.Server/DeltaV/Cargo/Components/PriceModifierComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Content.Server.DeltaV.Cargo.Components;

/// <summary>
/// This is used for modifying the sell price of an entity.
/// </summary>
[RegisterComponent]
public sealed partial class PriceModifierComponent : Component
{
/// <summary>
/// The price modifier.
/// </summary>
[DataField]
public float Modifier;
}
41 changes: 41 additions & 0 deletions Content.Server/DeltaV/Cargo/Systems/PricingSystem.Modifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Content.Server.DeltaV.Cargo.Components;
using Robust.Shared.Prototypes;

namespace Content.Server.Cargo.Systems;

public sealed partial class PricingSystem
{
/// <summary>
/// Applies any price modifiers defined in the entity prototype.
/// </summary>
/// <param name="prototype">The entity prototype.</param>
/// <param name="basePrice">The base price before modification.</param>
/// <returns>The modified price.</returns>
private double ApplyPrototypePriceModifier(EntityPrototype prototype, double basePrice)
{
if (prototype.Components.TryGetValue(_factory.GetComponentName(typeof(PriceModifierComponent)),
out var modProto))
{
var priceModifier = (PriceModifierComponent)modProto.Component;
return basePrice * priceModifier.Modifier;
}

return basePrice;
}

/// <summary>
/// Applies any price modifiers to the calculated price.
/// </summary>
/// <param name="uid">The entity whose price is being modified.</param>
/// <param name="basePrice">The base price before modification.</param>
/// <returns>The modified price.</returns>
private double ApplyPriceModifier(EntityUid uid, double basePrice)
{
if (TryComp<PriceModifierComponent>(uid, out var modifier))
{
return basePrice * modifier.Modifier;
}

return basePrice;
}
}
Loading

0 comments on commit 7d5cae7

Please sign in to comment.