Skip to content

Commit

Permalink
Merge branch 'space-wizards:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
RonRonstation authored Apr 4, 2024
2 parents c7c39c3 + 8cd0cce commit 69f5c31
Show file tree
Hide file tree
Showing 39 changed files with 337 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ private void PopulateDepartmentList(IEnumerable<SuitSensorStatus> departmentSens
specifier = new SpriteSpecifier.Rsi(new ResPath("Interface/Alerts/human_crew_monitoring.rsi"), "dead");
}

else if (sensor.TotalDamage != null)
else if (sensor.DamagePercentage != null)
{
var index = MathF.Round(4f * (sensor.TotalDamage.Value / 100f));
var index = MathF.Round(4f * sensor.DamagePercentage.Value);

if (index >= 5)
specifier = new SpriteSpecifier.Rsi(new ResPath("Interface/Alerts/human_crew_monitoring.rsi"), "critical");
Expand Down
1 change: 1 addition & 0 deletions Content.Client/Options/UI/Tabs/MiscTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
<Label Text="{Loc 'ui-options-general-speech'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ShowOocPatronColor" Text="{Loc 'ui-options-show-ooc-patron-color'}" />
<CheckBox Name="ShowLoocAboveHeadCheckBox" Text="{Loc 'ui-options-show-looc-on-head'}" />
<CheckBox Name="FancySpeechBubblesCheckBox" Text="{Loc 'ui-options-fancy-speech'}" />
<CheckBox Name="FancyNameBackgroundsCheckBox" Text="{Loc 'ui-options-fancy-name-background'}" />
Expand Down
11 changes: 11 additions & 0 deletions Content.Client/Options/UI/Tabs/MiscTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
using Content.Shared.CCVar;
using Content.Shared.HUD;
using Robust.Client.AutoGenerated;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Range = Robust.Client.UserInterface.Controls.Range;

Expand All @@ -16,6 +19,7 @@ namespace Content.Client.Options.UI.Tabs
[GenerateTypedNameReferences]
public sealed partial class MiscTab : Control
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;

Expand Down Expand Up @@ -55,8 +59,11 @@ public MiscTab()
UpdateApplyButton();
};

ShowOocPatronColor.Visible = _playerManager.LocalSession?.Channel.UserData.PatronTier is { } patron;

HudThemeOption.OnItemSelected += OnHudThemeChanged;
DiscordRich.OnToggled += OnCheckBoxToggled;
ShowOocPatronColor.OnToggled += OnCheckBoxToggled;
ShowLoocAboveHeadCheckBox.OnToggled += OnCheckBoxToggled;
ShowHeldItemCheckBox.OnToggled += OnCheckBoxToggled;
ShowCombatModeIndicatorsCheckBox.OnToggled += OnCheckBoxToggled;
Expand All @@ -73,6 +80,7 @@ public MiscTab()

HudThemeOption.SelectId(_hudThemeIdToIndex.GetValueOrDefault(_cfg.GetCVar(CVars.InterfaceTheme), 0));
DiscordRich.Pressed = _cfg.GetCVar(CVars.DiscordEnabled);
ShowOocPatronColor.Pressed = _cfg.GetCVar(CCVars.ShowOocPatronColor);
ShowLoocAboveHeadCheckBox.Pressed = _cfg.GetCVar(CCVars.LoocAboveHeadShow);
ShowHeldItemCheckBox.Pressed = _cfg.GetCVar(CCVars.HudHeldItemShow);
ShowCombatModeIndicatorsCheckBox.Pressed = _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
Expand Down Expand Up @@ -130,6 +138,7 @@ private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
_cfg.SetCVar(CCVars.HudHeldItemShow, ShowHeldItemCheckBox.Pressed);
_cfg.SetCVar(CCVars.CombatModeIndicatorsPointShow, ShowCombatModeIndicatorsCheckBox.Pressed);
_cfg.SetCVar(CCVars.OpaqueStorageWindow, OpaqueStorageWindowCheckBox.Pressed);
_cfg.SetCVar(CCVars.ShowOocPatronColor, ShowOocPatronColor.Pressed);
_cfg.SetCVar(CCVars.LoocAboveHeadShow, ShowLoocAboveHeadCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatFancyNameBackground, FancyNameBackgroundsCheckBox.Pressed);
Expand Down Expand Up @@ -158,6 +167,7 @@ private void UpdateApplyButton()
var isShowHeldItemSame = ShowHeldItemCheckBox.Pressed == _cfg.GetCVar(CCVars.HudHeldItemShow);
var isCombatModeIndicatorsSame = ShowCombatModeIndicatorsCheckBox.Pressed == _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
var isOpaqueStorageWindow = OpaqueStorageWindowCheckBox.Pressed == _cfg.GetCVar(CCVars.OpaqueStorageWindow);
var isOocPatronColorShowSame = ShowOocPatronColor.Pressed == _cfg.GetCVar(CCVars.ShowOocPatronColor);
var isLoocShowSame = ShowLoocAboveHeadCheckBox.Pressed == _cfg.GetCVar(CCVars.LoocAboveHeadShow);
var isFancyChatSame = FancySpeechBubblesCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
var isFancyBackgroundSame = FancyNameBackgroundsCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatFancyNameBackground);
Expand All @@ -175,6 +185,7 @@ private void UpdateApplyButton()
isShowHeldItemSame &&
isCombatModeIndicatorsSame &&
isOpaqueStorageWindow &&
isOocPatronColorShowSame &&
isLoocShowSame &&
isFancyChatSame &&
isFancyBackgroundSame &&
Expand Down
3 changes: 1 addition & 2 deletions Content.Server/Chat/Managers/ChatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,7 @@ private void SendOOC(ICommonSession player, string message)
var prefs = _preferencesManager.GetPreferences(player.UserId);
colorOverride = prefs.AdminOOCColor;
}
if (player.Channel.UserData.PatronTier is { } patron &&
PatronOocColors.TryGetValue(patron, out var patronColor))
if ( _netConfigManager.GetClientCVar(player.Channel, CCVars.ShowOocPatronColor) && player.Channel.UserData.PatronTier is { } patron && PatronOocColors.TryGetValue(patron, out var patronColor))
{
wrappedMessage = Loc.GetString("chat-manager-send-ooc-patron-wrap-message", ("patronColor", patronColor),("playerName", player.Name), ("message", FormattedMessage.EscapeText(message)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,12 @@ private void OnThrowCollide(EntityUid uid, SharedDisposalUnitComponent component
var canInsert = CanInsert(uid, component, args.Thrown);
var randDouble = _robustRandom.NextDouble();

if (!canInsert || randDouble > 0.75)
if (!canInsert)
{
return;
}

if (randDouble > 0.75)
{
_audioSystem.PlayPvs(component.MissSound, uid);

Expand Down
3 changes: 3 additions & 0 deletions Content.Server/Fluids/EntitySystems/PuddleSystem.Spillable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ private void SpillOnLand(Entity<SpillableComponent> entity, ref LandEvent args)
if (Openable.IsClosed(entity.Owner))
return;

if (!entity.Comp.SpillWhenThrown)
return;

if (args.User != null)
{
_adminLogger.Add(LogType.Landed,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Content.Shared.Whitelist;

namespace Content.Server.GameTicking.Rules.VariationPass.Components;

/// <summary>
/// Handles cutting a random wire on random devices around the station.
/// </summary>
[RegisterComponent]
public sealed partial class CutWireVariationPassComponent : Component
{
/// <summary>
/// Blacklist of hackable entities that should not be chosen to
/// have wires cut.
/// </summary>
[DataField]
public EntityWhitelist Blacklist = new();

/// <summary>
/// Chance for an individual wire to be cut.
/// </summary>
[DataField]
public float WireCutChance = 0.05f;

/// <summary>
/// Maximum number of wires that can be cut stationwide.
/// </summary>
[DataField]
public int MaxWiresCut = 10;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Content.Server.GameTicking.Rules.VariationPass.Components;
using Content.Server.Wires;
using Robust.Shared.Random;

namespace Content.Server.GameTicking.Rules.VariationPass;

/// <summary>
/// Handles cutting a random wire on random devices around the station.
/// This system identifies target devices and adds <see cref="CutWireOnMapInitComponent"/> to them.
/// The actual wire cutting is handled by <see cref="CutWireOnMapInitSystem"/>.
/// </summary>
public sealed class CutWireVariationPassSystem : VariationPassSystem<CutWireVariationPassComponent>
{
protected override void ApplyVariation(Entity<CutWireVariationPassComponent> ent, ref StationVariationPassEvent args)
{
var wiresCut = 0;
var query = AllEntityQuery<WiresComponent, TransformComponent>();
while (query.MoveNext(out var uid, out _, out var transform))
{
// Ignore if not part of the station
if (!IsMemberOfStation((uid, transform), ref args))
continue;

// Check against blacklist
if (ent.Comp.Blacklist.IsValid(uid))
continue;

if (Random.Prob(ent.Comp.WireCutChance))
{
EnsureComp<CutWireOnMapInitComponent>(uid);
wiresCut++;

// Limit max wires cut
if (wiresCut >= ent.Comp.MaxWiresCut)
break;
}
}
}
}
5 changes: 3 additions & 2 deletions Content.Server/GameTicking/Rules/ZombieRuleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ private void InfectInitialPlayers(ZombieRuleComponent component)
_playerManager.Sessions,
component.PatientZeroPrototypeId,
includeAllJobs: false,
customExcludeCondition: player => HasComp<ZombieImmuneComponent>(player) || HasComp<InitialInfectedExemptComponent>(player)
customExcludeCondition: player => HasComp<ZombieImmuneComponent>(player) || HasComp<InitialInfectedExemptComponent>(player)
);

//And get all players, excluding ZombieImmune and roles with CanBeAntag = False - to fill any leftover initial infected slots
Expand All @@ -259,7 +259,7 @@ private void InfectInitialPlayers(ZombieRuleComponent component)
acceptableAntags: Shared.Antag.AntagAcceptability.All,
includeAllJobs: false ,
ignorePreferences: true,
customExcludeCondition: HasComp<ZombieImmuneComponent>
customExcludeCondition: HasComp<ZombieImmuneComponent>
);

//If there are no players to choose, abort
Expand Down Expand Up @@ -293,6 +293,7 @@ private void MakeZombie(EntityUid entity, ZombieRuleComponent component)

//Add the role to the mind silently (to avoid repeating job assignment)
_roles.MindAddRole(mind, new InitialInfectedRoleComponent { PrototypeId = component.PatientZeroPrototypeId }, silent: true);
EnsureComp<InitialInfectedComponent>(entity);

//Add the zombie components and grace period
var pending = EnsureComp<PendingZombieComponent>(entity);
Expand Down
6 changes: 6 additions & 0 deletions Content.Server/Medical/HealthAnalyzerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ public override void Update(float frameTime)
if (component.ScannedEntity is not {} patient)
continue;

if (Deleted(patient))
{
StopAnalyzingEntity((uid, component), patient);
continue;
}

component.NextUpdate = _timing.CurTime + component.UpdateInterval;

//Get distance between health analyzer and the scanned entity
Expand Down
12 changes: 12 additions & 0 deletions Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public sealed class SuitSensorSystem : EntitySystem
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly SingletonDeviceNetServerSystem _singletonServerSystem = default!;
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;

public override void Initialize()
{
Expand Down Expand Up @@ -344,6 +345,11 @@ public void SetSensor(EntityUid uid, SuitSensorMode mode, EntityUid? userUid = n
if (TryComp<DamageableComponent>(sensor.User.Value, out var damageable))
totalDamage = damageable.TotalDamage.Int();

// Get mob total damage crit threshold
int? totalDamageThreshold = null;
if (_mobThresholdSystem.TryGetThresholdForState(sensor.User.Value, Shared.Mobs.MobState.Critical, out var critThreshold))
totalDamageThreshold = critThreshold.Value.Int();

// finally, form suit sensor status
var status = new SuitSensorStatus(GetNetEntity(uid), userName, userJob, userJobIcon, userJobDepartments);
switch (sensor.Mode)
Expand All @@ -354,10 +360,12 @@ public void SetSensor(EntityUid uid, SuitSensorMode mode, EntityUid? userUid = n
case SuitSensorMode.SensorVitals:
status.IsAlive = isAlive;
status.TotalDamage = totalDamage;
status.TotalDamageThreshold = totalDamageThreshold;
break;
case SuitSensorMode.SensorCords:
status.IsAlive = isAlive;
status.TotalDamage = totalDamage;
status.TotalDamageThreshold = totalDamageThreshold;
EntityCoordinates coordinates;
var xformQuery = GetEntityQuery<TransformComponent>();

Expand Down Expand Up @@ -402,6 +410,8 @@ public NetworkPayload SuitSensorToPacket(SuitSensorStatus status)

if (status.TotalDamage != null)
payload.Add(SuitSensorConstants.NET_TOTAL_DAMAGE, status.TotalDamage);
if (status.TotalDamageThreshold != null)
payload.Add(SuitSensorConstants.NET_TOTAL_DAMAGE_THRESHOLD, status.TotalDamageThreshold);
if (status.Coordinates != null)
payload.Add(SuitSensorConstants.NET_COORDINATES, status.Coordinates);

Expand Down Expand Up @@ -429,12 +439,14 @@ public NetworkPayload SuitSensorToPacket(SuitSensorStatus status)

// try get total damage and cords (optionals)
payload.TryGetValue(SuitSensorConstants.NET_TOTAL_DAMAGE, out int? totalDamage);
payload.TryGetValue(SuitSensorConstants.NET_TOTAL_DAMAGE_THRESHOLD, out int? totalDamageThreshold);
payload.TryGetValue(SuitSensorConstants.NET_COORDINATES, out NetCoordinates? coords);

var status = new SuitSensorStatus(suitSensorUid, name, job, jobIcon, jobDepartments)
{
IsAlive = isAlive.Value,
TotalDamage = totalDamage,
TotalDamageThreshold = totalDamageThreshold,
Coordinates = coords,
};
return status;
Expand Down
10 changes: 10 additions & 0 deletions Content.Server/Shuttles/Systems/ThrusterSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,11 @@ public void EnableThruster(EntityUid uid, ThrusterComponent component, Transform
return;
}

if (TryComp<ApcPowerReceiverComponent>(uid, out var apcPower))
{
apcPower.NeedsPower = true;
}

component.IsOn = true;

if (!EntityManager.TryGetComponent(xform.GridUid, out ShuttleComponent? shuttleComponent))
Expand Down Expand Up @@ -366,6 +371,11 @@ public void DisableThruster(EntityUid uid, ThrusterComponent component, EntityUi
if (!EntityManager.TryGetComponent(gridId, out ShuttleComponent? shuttleComponent))
return;

if (TryComp<ApcPowerReceiverComponent>(uid, out var apcPower))
{
apcPower.NeedsPower = false;
}

// Logger.DebugS("thruster", $"Disabled thruster {uid}");

switch (component.Type)
Expand Down
68 changes: 41 additions & 27 deletions Content.Server/Spawners/Components/TimedSpawnerComponent.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,54 @@
using System.Threading;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;

namespace Content.Server.Spawners.Components
namespace Content.Server.Spawners.Components;

/// <summary>
/// Spawns entities at a set interval.
/// Can configure the set of entities, spawn timing, spawn chance,
/// and min/max number of entities to spawn.
/// </summary>
[RegisterComponent]
public sealed partial class TimedSpawnerComponent : Component, ISerializationHooks
{
[RegisterComponent]
public sealed partial class TimedSpawnerComponent : Component, ISerializationHooks
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField("prototypes", customTypeSerializer:typeof(PrototypeIdListSerializer<EntityPrototype>))]
public List<string> Prototypes { get; set; } = new();
/// <summary>
/// List of entities that can be spawned by this component. One will be randomly
/// chosen for each entity spawned. When multiple entities are spawned at once,
/// each will be randomly chosen separately.
/// </summary>
[DataField]
public List<EntProtoId> Prototypes = [];

[ViewVariables(VVAccess.ReadWrite)]
[DataField("chance")]
public float Chance { get; set; } = 1.0f;
/// <summary>
/// Chance of an entity being spawned at the end of each interval.
/// </summary>
[DataField]
public float Chance = 1.0f;

[ViewVariables(VVAccess.ReadWrite)]
[DataField("intervalSeconds")]
public int IntervalSeconds { get; set; } = 60;
/// <summary>
/// Length of the interval between spawn attempts.
/// </summary>
[DataField]
public int IntervalSeconds = 60;

[ViewVariables(VVAccess.ReadWrite)]
[DataField("MinimumEntitiesSpawned")]
public int MinimumEntitiesSpawned { get; set; } = 1;
/// <summary>
/// The minimum number of entities that can be spawned when an interval elapses.
/// </summary>
[DataField]
public int MinimumEntitiesSpawned = 1;

[ViewVariables(VVAccess.ReadWrite)]
[DataField("MaximumEntitiesSpawned")]
public int MaximumEntitiesSpawned { get; set; } = 1;
/// <summary>
/// The maximum number of entities that can be spawned when an interval elapses.
/// </summary>
[DataField]
public int MaximumEntitiesSpawned = 1;

public CancellationTokenSource? TokenSource;
public CancellationTokenSource? TokenSource;

void ISerializationHooks.AfterDeserialization()
{
if (MinimumEntitiesSpawned > MaximumEntitiesSpawned)
throw new ArgumentException("MaximumEntitiesSpawned can't be lower than MinimumEntitiesSpawned!");
}
void ISerializationHooks.AfterDeserialization()
{
if (MinimumEntitiesSpawned > MaximumEntitiesSpawned)
throw new ArgumentException("MaximumEntitiesSpawned can't be lower than MinimumEntitiesSpawned!");
}
}
Loading

0 comments on commit 69f5c31

Please sign in to comment.