Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9122be6
tajaran species prototype
portfiend May 15, 2026
c359ee7
add tajaran body sprites
portfiend May 15, 2026
e6e658f
add tajaran mob
portfiend May 15, 2026
00052ae
add tajaran speech verb
portfiend May 15, 2026
6df59d9
add tajaran physiodesc
portfiend May 15, 2026
b442e35
mechanical notes
portfiend May 15, 2026
91c9813
add tajaran marking sprites
portfiend May 19, 2026
f9bb54c
texture reorg
portfiend May 19, 2026
8e4195b
tajaran marking prototypes
portfiend May 19, 2026
cbcc33b
marking locales
portfiend May 19, 2026
55a3e99
tajaran have a light step
portfiend May 21, 2026
dd8ba3b
add marking migrations
portfiend May 28, 2026
aca55c0
start guidebook entry
portfiend May 28, 2026
3bacd00
Merge remote-tracking branch 'origin/master' into feat/tajaran-species
portfiend May 30, 2026
2db6f37
tajaran guidebook expanded
portfiend May 31, 2026
2eae744
add guidebook entry for tajara
portfiend Jun 7, 2026
71a8448
tajaran flash sensitivity part 1
portfiend Jun 8, 2026
b35dc64
tajaran guidebook tweak
portfiend Jun 8, 2026
e2be4c9
make this its own system actually
portfiend Jun 8, 2026
11e847a
add flashing blindness to tajaran
portfiend Jun 9, 2026
13a69be
actually this has to be server side
portfiend Jun 9, 2026
e4636e6
we ball
portfiend Jun 11, 2026
d7652ba
add night vision overlays
portfiend Jun 13, 2026
f65314b
fix fov
portfiend Jun 18, 2026
3ce8640
allow night vision overlays to modify the curve
portfiend Jun 18, 2026
6164ae1
rework night vision tint
portfiend Jun 18, 2026
1dbb18c
eh
portfiend Jun 18, 2026
bb4c8b4
Merge branch 'master' into feat/tajaran-species
portfiend Jun 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions Content.Client/_DEN/Overlays/NightVisionOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;

namespace Content.Client._DEN.Overlays;

public sealed partial class NightVisionOverlay : Overlay
{
private static readonly ProtoId<ShaderPrototype> ShaderId = "NightVision";

[Dependency] private IPrototypeManager _prototypeManager = default!;

public override OverlaySpace Space => OverlaySpace.WorldSpace;
public override bool RequestScreenTexture => true;
private readonly ShaderInstance _nightVisionShader;

private Color _tintColor = Color.White;

public NightVisionOverlay()
{
IoCManager.InjectDependencies(this);
_nightVisionShader = _prototypeManager.Index(ShaderId).InstanceUnique();
}

protected override void Draw(in OverlayDrawArgs args)
{
if (ScreenTexture == null)
return;

_nightVisionShader.SetParameter("SCREEN_TEXTURE", ScreenTexture);

var handle = args.WorldHandle;
handle.UseShader(_nightVisionShader);
handle.DrawRect(args.WorldBounds, _tintColor);
handle.UseShader(null);
}

/// <summary>
/// Sets the tint color of this overlay.
/// </summary>
/// <param name="tint">The tint color.</param>
public void SetColorTint(Color tint)
{
_tintColor = tint;
}

public void SetCurve(float? lowCurve, float? midCurve, float? highCurve, float? curveAmount)
{
if (lowCurve != null)
_nightVisionShader.SetParameter("low_curve", lowCurve.Value);

if (midCurve != null)
_nightVisionShader.SetParameter("mid_curve", midCurve.Value);

if (highCurve != null)
_nightVisionShader.SetParameter("high_curve", highCurve.Value);

if (curveAmount != null)
_nightVisionShader.SetParameter("curve_amount", curveAmount.Value);
}
}
48 changes: 48 additions & 0 deletions Content.Client/_DEN/Overlays/NightVisionOverlaySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Content.Client.Overlays;
using Content.Shared._DEN.Overlays.Components;
using Content.Shared.Inventory.Events;
using Robust.Client.Graphics;
using Robust.Shared.Utility;

namespace Content.Client._DEN.Overlays;

public sealed partial class NightVisionOverlaySystem : EquipmentHudSystem<NightVisionOverlayComponent>
{
[Dependency] private ILightManager _lightManager = default!;
[Dependency] private IOverlayManager _overlayMan = default!;

private NightVisionOverlay _overlay = default!;

public override void Initialize()
{
base.Initialize();

_overlay = new();
}

protected override void UpdateInternal(RefreshEquipmentHudEvent<NightVisionOverlayComponent> component)
{
base.UpdateInternal(component);

_overlayMan.AddOverlay(_overlay);
_lightManager.DrawLighting = false;

var comps = component.Components;
if (comps.TryFirstOrDefault(out var comp))
{
_overlay.SetColorTint(comp.TintColor);
_overlay.SetCurve(comp.LowCurve, comp.MidCurve, comp.HighCurve, comp.CurveAmount);
return;
}

_overlay.SetColorTint(NightVisionOverlayComponent.DefaultTintColor);
}

protected override void DeactivateInternal()
{
base.DeactivateInternal();

_overlayMan.RemoveOverlay(_overlay);
_lightManager.DrawLighting = true;
}
}
38 changes: 38 additions & 0 deletions Content.Server/_DEN/Flash/EntitySystems/BlindedByFlashingSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

using Content.Shared._DEN.Flash.Components;
using Content.Shared.Eye.Blinding.Systems;
using Content.Shared.Flash;
using Robust.Shared.Random;

namespace Content.Server._DEN.Flash.EntitySystems;

public sealed partial class BlindedByFlashingSystem : EntitySystem
{
[Dependency] private BlindableSystem _blindable = default!;
[Dependency] private IRobustRandom _random = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<BlindedByFlashingComponent, AfterFlashedEvent>(OnAfterFlashed);
}

/// <summary>
/// Add eye damage to this entity when they are flashed.
/// </summary>
/// <param name="ent">The entity that receives eye damage when flashed.</param>
public void OnAfterFlashed(Entity<BlindedByFlashingComponent> ent, ref AfterFlashedEvent args)
{
if (ent.Owner != args.Target
|| ent.Comp.Damage == 0
|| ent.Comp.Chance <= 0.0f)
return;

if (ent.Comp.Chance < 1.0f
&& _random.NextFloat() > ent.Comp.Chance)
return;

_blindable.AdjustEyeDamage(ent.Owner, ent.Comp.Damage);
}
}
11 changes: 11 additions & 0 deletions Content.Shared/Flash/SharedFlashSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using Content.Shared._DEN.Flash.EntitySystems;
using Content.Shared.Charges.Components;
using Content.Shared.Charges.Systems;
using Content.Shared.Clothing.Components;
Expand Down Expand Up @@ -185,6 +186,16 @@ public void Flash(
if (attempt.Cancelled)
return;

// Begin DEN - Flash modifiers
var flashMod = new FlashModifierEvent(target, user, used);
RaiseLocalEvent(target, ref flashMod);

flashDuration *= Math.Max(flashMod.FlashDurationModifier, 0.0f);
stunDuration *= Math.Max(flashMod.StunDurationModifier, 0.0f);
slowTo *= flashMod.SpeedModifier;
slowTo = Math.Clamp(slowTo, 0.0f, 1.0f); // Should not be faster than base speed, or negative
// End DEN

// don't paralyze, slowdown or convert to rev if the target is immune to flashes
if (!_statusEffectsSystem.TryAddStatusEffect<FlashedComponent>(target, FlashedKey, flashDuration, true))
return;
Expand Down
5 changes: 5 additions & 0 deletions Content.Shared/Inventory/InventorySystem.Relay.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Shared._DEN.Overlays.Components;
using Content.Shared.Armor;
using Content.Shared.Atmos;
using Content.Shared.Chat;
Expand Down Expand Up @@ -102,6 +103,10 @@ public void InitializeRelay()
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<NoirOverlayComponent>>(RefRelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ThermalSightComponent>>(RefRelayInventoryEvent);

// Begin DEN
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<NightVisionOverlayComponent>>(RefRelayInventoryEvent);
// End DEN

SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<EquipmentVerb>>(OnGetEquipmentVerbs);
SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<InnateVerb>>(OnGetInnateVerbs);

Expand Down
10 changes: 10 additions & 0 deletions Content.Shared/Movement/Systems/SharedMoverController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using Content.Shared._DEN.Movement.Components;
using Content.Shared.ActionBlocker;
using Content.Shared.CCVar;
using Content.Shared.Friction;
Expand Down Expand Up @@ -48,6 +49,7 @@ public abstract partial class SharedMoverController : VirtualController
[Dependency] private SharedTransformSystem _transform = default!;
[Dependency] private TagSystem _tags = default!;

[Dependency] protected EntityQuery<BarestepModifierComponent> BarestepModifierQuery = default!; // DEN - Barestep sounds
[Dependency] protected EntityQuery<CanMoveInAirComponent> CanMoveInAirQuery = default!;
[Dependency] protected EntityQuery<FootstepModifierComponent> FootstepModifierQuery = default!;
[Dependency] protected EntityQuery<FTLComponent> FTLQuery = default!;
Expand Down Expand Up @@ -552,6 +554,14 @@ private bool TryGetSound(
return sound != null;
}

// DEN start: Barestep modifiers for shoeless walking
if (shoes == null && BarestepModifierQuery.TryComp(uid, out var barestepModifier))
{
sound = barestepModifier.FootstepSoundCollection;
return sound != null;
}
// DEN end

return TryGetFootstepSound(uid, xform, shoes != null, out sound, tileDef: tileDef);
}

Expand Down
20 changes: 20 additions & 0 deletions Content.Shared/_DEN/Flash/Components/BlindedByFlashingComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Content.Shared._DEN.Flash.Components;

/// <summary>
/// Entities with this component will take eye damage when they are flashed.
/// </summary>
[RegisterComponent]
public sealed partial class BlindedByFlashingComponent : Component
{
/// <summary>
/// How much eye damage this entity receives when flashed.
/// </summary>
[DataField]
public int Damage = 1;

/// <summary>
/// The chance of this entity receiving eye damage when flashed.
/// </summary>
[DataField]
public float Chance = 1.0f;
}
26 changes: 26 additions & 0 deletions Content.Shared/_DEN/Flash/Components/FlashedModifierComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Content.Shared._DEN.Flash.Components;

/// <summary>
/// Entities with this component will modify the stats of an incoming flash.
/// </summary>
[RegisterComponent]
public sealed partial class FlashedModifierComponent : Component
{
/// <summary>
/// A multiplier to the duration of flashes received by this entity.
/// </summary>
[DataField("durationMod")]
public float FlashDurationModifier = 1.0f;

/// <summary>
/// A motiplier to the stun duration of flashes received by this entity.
/// </summary>
[DataField("stunMod")]
public float StunDurationModifier = 1.0f;

/// <summary>
/// A multiplier to the movement speed of this entity when they are flashed.
/// </summary>
[DataField("speedMod")]
public float SpeedModifier = 1.0f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Content.Shared._DEN.Flash.Components;

namespace Content.Shared._DEN.Flash.EntitySystems;

public sealed partial class SharedFlashModifierSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<FlashedModifierComponent, FlashModifierEvent>(OnFlashModified);
}

/// <summary>
/// Modifies the stats of an incoming flash on this entity.
/// </summary>
/// <param name="ent">The entity being flashed.</param>
private void OnFlashModified(Entity<FlashedModifierComponent> ent, ref FlashModifierEvent args)
{
args.FlashDurationModifier *= ent.Comp.FlashDurationModifier;
args.StunDurationModifier *= ent.Comp.StunDurationModifier;
args.SpeedModifier *= ent.Comp.SpeedModifier;
}
}

/// <summary>
/// Event used to modify the stats associated with a particular flash attempt.
/// </summary>
[ByRefEvent]
public record struct FlashModifierEvent(EntityUid Target,
EntityUid? User,
EntityUid? Used)
{
/// <summary>
/// A multiplier to the duration of flashes received by this entity.
/// </summary>
public float FlashDurationModifier = 1.0f;

/// <summary>
/// A motiplier to the stun duration of flashes received by this entity.
/// </summary>
public float StunDurationModifier = 1.0f;

/// <summary>
/// A multiplier to the movement speed of this entity when they are flashed.
/// </summary>
public float SpeedModifier = 1.0f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;

namespace Content.Shared._DEN.Movement.Components;

/// <summary>
/// Changes footstep sounds ONLY when this entity is not wearing shoes.
/// </summary>
/// <remarks>
/// This is similar to FootstepModifierComponent.
/// </remarks>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class BarestepModifierComponent : Component
{
[DataField, AutoNetworkedField]
public SoundSpecifier? FootstepSoundCollection;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Robust.Shared.GameStates;

namespace Content.Shared._DEN.Overlays.Components;

/// <summary>
/// When applied to an entity or a clothing item, this gives the entity (or wearer)
/// a "night vision" shader. This shader allows you to see better in dark environments.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class NightVisionOverlayComponent : Component
{
public readonly static Color DefaultTintColor = Color.FromHex("#888");

/// <summary>
/// What color to tint the night vision effect.
/// </summary>
[DataField]
public Color TintColor = DefaultTintColor;

/// <summary>
/// The minimum bound of lightness that this shader will begin rebalancing values.
/// </summary>
[DataField]
public float? LowCurve = null;

/// <summary>
/// The point at which the "curve" is highest - what lightness increases the curve the most.
/// </summary>
[DataField]
public float? MidCurve = null;

/// <summary>
/// The upper bound of lightness that this shader will begin rebalancing values.
/// </summary>
[DataField]
public float? HighCurve = null;

/// <summary>
/// The amount that lightness values will be increased at its peak.
/// </summary>
[DataField]
public float? CurveAmount = null;
}
9 changes: 8 additions & 1 deletion Resources/Locale/en-US/_DEN/chat/managers/chat-manager.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ chat-manager-entity-subtle-wrap-message = [italic]{ PROPER($entity) ->
[true] {CAPITALIZE($entityName)} {$message}[/italic]
}

chat-manager-entity-subtle-ooc-wrap-message = [italic](OOC) {$entityName} {$message}[/italic]
chat-manager-entity-subtle-ooc-wrap-message = [italic](OOC) {$entityName} {$message}[/italic]

# speech verbs

chat-speech-verb-name-tajaran = Tajaran
chat-speech-verb-tajaran-1 = meows
chat-speech-verb-tajaran-2 = mews
chat-speech-verb-tajaran-3 = purrs
Loading
Loading