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 Mar 26, 2024
2 parents 678f1b1 + 00f95c6 commit e2b8ec6
Show file tree
Hide file tree
Showing 32 changed files with 814 additions and 98 deletions.
32 changes: 29 additions & 3 deletions Content.Server/Atmos/Components/AirtightComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,53 @@ public sealed partial class AirtightComponent : Component
{
public (EntityUid Grid, Vector2i Tile) LastPosition { get; set; }

/// <summary>
/// The directions in which this entity should block airflow, relative to its own reference frame.
/// </summary>
[DataField("airBlockedDirection", customTypeSerializer: typeof(FlagSerializer<AtmosDirectionFlags>))]
public int InitialAirBlockedDirection { get; set; } = (int) AtmosDirection.All;

/// <summary>
/// The directions in which the entity is currently blocking airflow, relative to the grid that the entity is on.
/// I.e., this is a variant of <see cref="InitialAirBlockedDirection"/> that takes into account the entity's
/// current rotation.
/// </summary>
[ViewVariables]
public int CurrentAirBlockedDirection;

[DataField("airBlocked")]
/// <summary>
/// Whether the airtight entity is currently blocking airflow.
/// </summary>
[DataField]
public bool AirBlocked { get; set; } = true;

[DataField("fixVacuum")]
/// <summary>
/// If true, entities on this tile will attempt to draw air from surrounding tiles when they become unblocked
/// and currently have no air. This is generally only required when <see cref="NoAirWhenFullyAirBlocked"/> is
/// true, or if the entity is likely to occupy the same tile as another no-air airtight entity.
/// </summary>
[DataField]
public bool FixVacuum { get; set; } = true;
// I think fixvacuum exists to ensure that repeatedly closing/opening air-blocking doors doesn't end up
// depressurizing a room. However it can also effectively be used as a means of generating gasses for free
// TODO ATMOS Mass conservation. Make it actually push/pull air from adjacent tiles instead of destroying & creating,


// TODO ATMOS Do we need these two fields?
[DataField("rotateAirBlocked")]
public bool RotateAirBlocked { get; set; } = true;

// TODO ATMOS remove this? What is this even for??
[DataField("fixAirBlockedDirectionInitialize")]
public bool FixAirBlockedDirectionInitialize { get; set; } = true;

[DataField("noAirWhenFullyAirBlocked")]
/// <summary>
/// If true, then the tile that this entity is on will have no air at all if all directions are blocked.
/// </summary>
[DataField]
public bool NoAirWhenFullyAirBlocked { get; set; } = true;

/// <inheritdoc cref="CurrentAirBlockedDirection"/>
[Access(Other = AccessPermissions.ReadWriteExecute)]
public AtmosDirection AirBlockedDirection => (AtmosDirection)CurrentAirBlockedDirection;
}
Expand Down
2 changes: 0 additions & 2 deletions Content.Server/Atmos/EntitySystems/AirtightSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ private void OnAirtightMoved(Entity<AirtightComponent> airtight, ref MoveEvent e
private bool AirtightMove(Entity<AirtightComponent> ent, ref MoveEvent ev)
{
var (owner, airtight) = ent;
if (!airtight.RotateAirBlocked || airtight.InitialAirBlockedDirection == (int)AtmosDirection.Invalid)
return false;

airtight.CurrentAirBlockedDirection = (int) Rotate((AtmosDirection)airtight.InitialAirBlockedDirection, ev.NewRotation);
var pos = airtight.LastPosition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,7 @@ private void GridIsHotspotActive(EntityUid uid, GridAtmosphereComponent componen
args.Handled = true;
}

private void GridFixTileVacuum(
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
TileAtmosphere tile,
float volume)
private void GridFixTileVacuum(TileAtmosphere tile)
{
DebugTools.AssertNotNull(tile.Air);
DebugTools.Assert(tile.Air?.Immutable == false );
Expand All @@ -416,6 +413,9 @@ private void GridFixTileVacuum(
count++;
}

if (count == 0)
return;

var ratio = 1f / count;
var totalTemperature = 0f;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ private void UpdateTileAir(
tile.Air = new GasMixture(volume){Temperature = Atmospherics.T20C};

if (data.FixVacuum)
GridFixTileVacuum(ent, tile, volume);
GridFixTileVacuum(tile);
}

private void QueueRunTiles(
Expand Down
3 changes: 2 additions & 1 deletion Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,13 @@ private AirtightData GetAirtightData(EntityUid uid, MapGridComponent grid, Vecto
if (!_airtightQuery.TryGetComponent(ent, out var airtight))
continue;

fixVacuum |= airtight.FixVacuum;

if(!airtight.AirBlocked)
continue;

blockedDirs |= airtight.AirBlockedDirection;
noAirWhenBlocked |= airtight.NoAirWhenFullyAirBlocked;
fixVacuum |= airtight.FixVacuum;

if (blockedDirs == AtmosDirection.All && noAirWhenBlocked && fixVacuum)
break;
Expand Down
7 changes: 4 additions & 3 deletions Content.Server/Atmos/GasMixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ public float Temperature
get => _temperature;
set
{
DebugTools.Assert(!float.IsNaN(_temperature));
if (Immutable) return;
_temperature = MathF.Min(MathF.Max(value, Atmospherics.TCMB), Atmospherics.Tmax);
DebugTools.Assert(!float.IsNaN(value));
if (!Immutable)
_temperature = MathF.Min(MathF.Max(value, Atmospherics.TCMB), Atmospherics.Tmax);
}
}

Expand All @@ -91,6 +91,7 @@ public GasMixture(float[] moles, float temp, float volume = Atmospherics.CellVol
if (volume < 0)
volume = 0;

DebugTools.Assert(!float.IsNaN(temp));
_temperature = temp;
Moles = moles;
Volume = volume;
Expand Down
3 changes: 3 additions & 0 deletions Content.Server/Atmos/TileAtmosphere.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public sealed class TileAtmosphere : IGasMixtureHolder
[ViewVariables]
public TileAtmosphere? PressureSpecificTarget { get; set; }

/// <summary>
/// This is either the pressure difference, or the quantity of moles transferred if monstermos is enabled.
/// </summary>
[ViewVariables]
public float PressureDifference { get; set; }

Expand Down
21 changes: 21 additions & 0 deletions Content.Server/Implants/ImplanterSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server.Popups;
using Content.Shared.DoAfter;
using Content.Shared.IdentityManagement;
Expand Down Expand Up @@ -57,6 +58,17 @@ private void OnImplanterAfterInteract(EntityUid uid, ImplanterComponent componen
return;
}

// Check if we are trying to implant a implant which is already implanted
if (implant.HasValue && !component.AllowMultipleImplants && CheckSameImplant(target, implant.Value))
{
var name = Identity.Name(target, EntityManager, args.User);
var msg = Loc.GetString("implanter-component-implant-already", ("implant", implant), ("target", name));
_popup.PopupEntity(msg, target, args.User);
args.Handled = true;
return;
}


//Implant self instantly, otherwise try to inject the target.
if (args.User == target)
Implant(target, target, uid, component);
Expand All @@ -67,6 +79,15 @@ private void OnImplanterAfterInteract(EntityUid uid, ImplanterComponent componen
args.Handled = true;
}

public bool CheckSameImplant(EntityUid target, EntityUid implant)
{
if (!TryComp<ImplantedComponent>(target, out var implanted))
return false;

var implantPrototype = Prototype(implant);
return implanted.ImplantContainer.ContainedEntities.Any(entity => Prototype(entity) == implantPrototype);
}

/// <summary>
/// Attempt to implant someone else.
/// </summary>
Expand Down
22 changes: 17 additions & 5 deletions Content.Server/Research/Systems/ResearchStealerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using Content.Shared.Research.Components;
using Content.Shared.Research.Systems;
using Robust.Shared.Random;

namespace Content.Server.Research.Systems;

public sealed class ResearchStealerSystem : SharedResearchStealerSystem
{
[Dependency] private readonly SharedResearchSystem _research = default!;
[Dependency] private readonly IRobustRandom _random = default!;

public override void Initialize()
{
Expand All @@ -24,16 +26,26 @@ private void OnDoAfter(EntityUid uid, ResearchStealerComponent comp, ResearchSte
if (!TryComp<TechnologyDatabaseComponent>(target, out var database))
return;

var ev = new ResearchStolenEvent(uid, target, database.UnlockedTechnologies);
var ev = new ResearchStolenEvent(uid, target, new());
var count = _random.Next(comp.MinToSteal, comp.MaxToSteal + 1);
for (var i = 0; i < count; i++)
{
if (database.UnlockedTechnologies.Count == 0)
break;

var toRemove = _random.Pick(database.UnlockedTechnologies);
if (_research.TryRemoveTechnology((target, database), toRemove))
ev.Techs.Add(toRemove);
}
RaiseLocalEvent(uid, ref ev);
// oops, no more advanced lasers!
_research.ClearTechs(target, database);

args.Handled = true;
}
}

/// <summary>
/// Event raised on the user when research is stolen from a R&D server.
/// Event raised on the user when research is stolen from a RND server.
/// Techs contains every technology id researched.
/// </summary>
[ByRefEvent]
public record struct ResearchStolenEvent(EntityUid Used, EntityUid Target, List<String> Techs);
public record struct ResearchStolenEvent(EntityUid Used, EntityUid Target, List<string> Techs);
59 changes: 59 additions & 0 deletions Content.Shared/Chat/V2/Moderation/ChatCensor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Linq;

namespace Content.Shared.Chat.V2.Moderation;

public interface IChatCensor
{
public bool Censor(string input, out string output, char replaceWith = '*');
}

public sealed class CompoundChatCensor(IEnumerable<IChatCensor> censors) : IChatCensor
{
public bool Censor(string input, out string output, char replaceWith = '*')
{
var censored = false;

foreach (var censor in censors)
{
if (censor.Censor(input, out output, replaceWith))
{
censored = true;
}
}

output = input;

return censored;
}
}

public sealed class ChatCensorFactory
{
private List<IChatCensor> _censors = new();

public void With(IChatCensor censor)
{
_censors.Add(censor);
}

/// <summary>
/// Builds a ChatCensor that combines all the censors that have been added to this.
/// </summary>
public IChatCensor Build()
{
return new CompoundChatCensor(_censors.ToArray());
}

/// <summary>
/// Resets the build state to zero, allowing for different rules to be provided to the next censor(s) built.
/// </summary>
/// <returns>True if the builder had any setup prior to the reset.</returns>
public bool Reset()
{
var notEmpty = _censors.Count > 0;

_censors = new List<IChatCensor>();

return notEmpty;
}
}
15 changes: 15 additions & 0 deletions Content.Shared/Chat/V2/Moderation/RegexCensor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Text.RegularExpressions;

namespace Content.Shared.Chat.V2.Moderation;

public sealed class RegexCensor(Regex censorInstruction) : IChatCensor
{
private readonly Regex _censorInstruction = censorInstruction;

public bool Censor(string input, out string output, char replaceWith = '*')
{
output = _censorInstruction.Replace(input, replaceWith.ToString());

return !string.Equals(input, output);
}
}
Loading

0 comments on commit e2b8ec6

Please sign in to comment.