Skip to content

Commit

Permalink
Night vision (#370)
Browse files Browse the repository at this point in the history
система ночного зрения
  • Loading branch information
Tenteratus committed Jun 19, 2024
1 parent d3efeec commit c3e339f
Show file tree
Hide file tree
Showing 8 changed files with 346 additions and 0 deletions.
86 changes: 86 additions & 0 deletions Content.Client/Starshine/Eye/NightVision/NightVisionOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Content.Shared.Starshine.Eye.NightVision.Components; //creater - vladospupuos
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;

namespace Content.Client.GG.Eye.NightVision
{
public sealed class NightVisionOverlay : Overlay
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly ILightManager _lightManager = default!;


public override bool RequestScreenTexture => true;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ShaderInstance _greyscaleShader;
public Color NightvisionColor = Color.Green;

private NightVisionComponent _nightvisionComponent = default!;

public NightVisionOverlay(Color color)
{
IoCManager.InjectDependencies(this);
_greyscaleShader = _prototypeManager.Index<ShaderPrototype>("GreyscaleFullscreen").InstanceUnique();

NightvisionColor = color;
}
protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (!_entityManager.TryGetComponent(_playerManager.LocalSession?.AttachedEntity, out EyeComponent? eyeComp))
return false;

if (args.Viewport.Eye != eyeComp.Eye)
return false;

var playerEntity = _playerManager.LocalSession?.AttachedEntity;

if (playerEntity == null)
return false;

if (!_entityManager.TryGetComponent<NightVisionComponent>(playerEntity, out var nightvisionComp))
return false;

_nightvisionComponent = nightvisionComp;

var nightvision = _nightvisionComponent.IsNightVision;

if (!nightvision && _nightvisionComponent.DrawShadows) // Disable our Night Vision
{
_lightManager.DrawLighting = true;
_nightvisionComponent.DrawShadows = false;
_nightvisionComponent.GraceFrame = true;
return true;
}

return nightvision;
}

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

if (!_nightvisionComponent.GraceFrame)
{
_nightvisionComponent.DrawShadows = true; // Enable our Night Vision
_lightManager.DrawLighting = false;
}
else
{
_nightvisionComponent.GraceFrame = false;
}

_greyscaleShader?.SetParameter("SCREEN_TEXTURE", ScreenTexture);

var worldHandle = args.WorldHandle;
var viewport = args.WorldBounds;
worldHandle.UseShader(_greyscaleShader);
worldHandle.DrawRect(viewport, NightvisionColor);
worldHandle.UseShader(null);
}
}
}
47 changes: 47 additions & 0 deletions Content.Client/Starshine/Eye/NightVision/NightVisionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Content.Client.Overlays;
using Content.Shared.GameTicking;
using Content.Shared.Starshine.Eye.NightVision.Components;
using Content.Shared.Inventory.Events;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Player;

namespace Content.Client.GG.Eye.NightVision;

public sealed class NightVisionSystem : EquipmentHudSystem<NightVisionComponent>
{
[Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly ILightManager _lightManager = default!;


private NightVisionOverlay _overlay = default!;

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

_overlay = new(Color.Green);
}

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

foreach (var comp in component.Components)
{
_overlay.NightvisionColor = comp.NightVisionColor;
}
if (!_overlayMan.HasOverlay<NightVisionOverlay>())
{
_overlayMan.AddOverlay(_overlay);
}
_lightManager.DrawLighting = false;
}

protected override void DeactivateInternal()
{
base.DeactivateInternal();
_overlayMan.RemoveOverlay(_overlay);
_lightManager.DrawLighting = true;
}
}
5 changes: 5 additions & 0 deletions Content.Shared/Inventory/InventorySystem.Relay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Content.Shared.IdentityManagement.Components;
using Content.Shared.Inventory.Events;
using Content.Shared.Movement.Systems;
using Content.Shared.Starshine.Eye.NightVision.Systems; // NightVision
using Content.Shared.Overlays;
using Content.Shared.Radio;
using Content.Shared.Slippery;
Expand Down Expand Up @@ -39,6 +40,10 @@ public void InitializeRelay()
SubscribeLocalEvent<InventoryComponent, GetBlurEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, SolutionScanEvent>(RelayInventoryEvent);

// NightVision-Start
SubscribeLocalEvent<InventoryComponent, CanVisionAttemptEvent>(RelayInventoryEvent);
// NightVision-End

// ComponentActivatedClientSystems
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowJobIconsComponent>>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowHealthBarsComponent>>(RelayInventoryEvent);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Content.Shared.Actions;
using Content.Shared.Starshine.Eye.NightVision.Systems;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;

namespace Content.Shared.Starshine.Eye.NightVision.Components;

[RegisterComponent]
[NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(NightVisionSystem))]
public sealed partial class NightVisionComponent : Component
{
[ViewVariables(VVAccess.ReadWrite), DataField("isOn"), AutoNetworkedField]
public bool IsNightVision;

[DataField("color")]
public Color NightVisionColor = Color.Green;

[DataField]
public bool IsToggle = false;

[DataField] public EntityUid? ActionContainer;

[Access(Other = AccessPermissions.ReadWriteExecute)]
public bool DrawShadows = false;

[Access(Other = AccessPermissions.ReadWriteExecute)]
public bool GraceFrame = false;

[DataField("playSoundOn")]
public bool PlaySoundOn = true;
public SoundSpecifier OnOffSound = new SoundPathSpecifier("/Audio/Backmen/Misc/night-vision-sound-effect_E_minor.ogg");
}

public sealed partial class NVInstantActionEvent : InstantActionEvent { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Content.Shared.Actions;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Shared.Starshine.Eye.NightVision.Components;


[RegisterComponent, NetworkedComponent]
public sealed partial class PNVComponent : Component
{
[DataField] public EntProtoId<InstantActionComponent> ActionProto = "NVToggleAction";
[DataField] public EntityUid? ActionContainer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Content.Shared.Starshine.Eye.NightVision.Components;
using Content.Shared.Inventory;
using Content.Shared.Actions;
using JetBrains.Annotations;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;

namespace Content.Shared.Starshine.Eye.NightVision.Systems;

public sealed class NightVisionSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly INetManager _net = default!;

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

if(_net.IsServer)
SubscribeLocalEvent<NightVisionComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<NightVisionComponent, NVInstantActionEvent>(OnActionToggle);
}

[ValidatePrototypeId<EntityPrototype>]
private const string SwitchNightVisionAction = "SwitchNightVision";

private void OnComponentStartup(EntityUid uid, NightVisionComponent component, ComponentStartup args)
{
if (component.IsToggle)
_actionsSystem.AddAction(uid, ref component.ActionContainer, SwitchNightVisionAction);
}

private void OnActionToggle(EntityUid uid, NightVisionComponent component, NVInstantActionEvent args)
{
component.IsNightVision = !component.IsNightVision;
var changeEv = new NightVisionnessChangedEvent(component.IsNightVision);
RaiseLocalEvent(uid, ref changeEv);
Dirty(uid, component);
_actionsSystem.SetCooldown(component.ActionContainer, TimeSpan.FromSeconds(1));
if (component is { IsNightVision: true, PlaySoundOn: true })
{
if(_net.IsServer)
_audioSystem.PlayPvs(component.OnOffSound, uid);
}
}

[PublicAPI]
public void UpdateIsNightVision(EntityUid uid, NightVisionComponent? component = null)
{
if (!Resolve(uid, ref component, false))
return;

var old = component.IsNightVision;


var ev = new CanVisionAttemptEvent();
RaiseLocalEvent(uid, ev);
component.IsNightVision = ev.NightVision;

if (old == component.IsNightVision)
return;

var changeEv = new NightVisionnessChangedEvent(component.IsNightVision);
RaiseLocalEvent(uid, ref changeEv);
Dirty(uid, component);
}
}

[ByRefEvent]
public record struct NightVisionnessChangedEvent(bool NightVision);


public sealed class CanVisionAttemptEvent : CancellableEntityEventArgs, IInventoryRelayEvent
{
public bool NightVision => Cancelled;
public SlotFlags TargetSlots => SlotFlags.EYES | SlotFlags.MASK | SlotFlags.HEAD;
}
68 changes: 68 additions & 0 deletions Content.Shared/Starshine/Eye/NightVision/Systems/PNVSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Content.Shared.Starshine.Eye.NightVision.Components;
using Content.Shared.Inventory;
using Content.Shared.Actions;
using Content.Shared.Inventory.Events;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Network;

namespace Content.Shared.Starshine.Eye.NightVision.Systems;

public sealed class PNVSystem : EntitySystem
{
[Dependency] private readonly NightVisionSystem _nightvisionableSystem = default!;
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly INetManager _net = default!;

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

SubscribeLocalEvent<PNVComponent, GotEquippedEvent>(OnEquipped);
SubscribeLocalEvent<PNVComponent, GotUnequippedEvent>(OnUnequipped);
SubscribeLocalEvent<PNVComponent, InventoryRelayedEvent<CanVisionAttemptEvent>>(OnPNVTrySee);
}

private void OnPNVTrySee(EntityUid uid, PNVComponent component, InventoryRelayedEvent<CanVisionAttemptEvent> args)
{
args.Args.Cancel();
}

private void OnEquipped(EntityUid uid, PNVComponent component, GotEquippedEvent args)
{
if (args.Slot is not ("eyes" or "mask" or "head"))
return;

if (HasComp<NightVisionComponent>(args.Equipee))
return;

var nvcomp = EnsureComp<NightVisionComponent>(args.Equipee);

_nightvisionableSystem.UpdateIsNightVision(args.Equipee, nvcomp);
if(component.ActionContainer == null)
_actionsSystem.AddAction(args.Equipee, ref component.ActionContainer, component.ActionProto);
_actionsSystem.SetCooldown(component.ActionContainer, TimeSpan.FromSeconds(1)); // GCD?

if (nvcomp.PlaySoundOn)
{
if(_net.IsServer)
_audioSystem.PlayPvs(nvcomp.OnOffSound, uid);
}

}

private void OnUnequipped(EntityUid uid, PNVComponent component, GotUnequippedEvent args)
{
if (args.Slot is not ("eyes" or "mask" or "head"))
return;

if (!TryComp<NightVisionComponent>(args.Equipee, out var nvcomp))
return;

_nightvisionableSystem.UpdateIsNightVision(args.Equipee, nvcomp);
_actionsSystem.RemoveAction(args.Equipee, component.ActionContainer);
component.ActionContainer = null;

RemCompDeferred<NightVisionComponent>(args.Equipee);
}
}
12 changes: 12 additions & 0 deletions Resources/Prototypes/Starshine/Actions/PNV.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
- type: entity
id: SwitchNightVision
name: switch night vision
description: Switches night vision
noSpawn: true
components:
- type: InstantAction
useDelay: 2.5
icon:
sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
state: icon
event: !type:NVInstantActionEvent

0 comments on commit c3e339f

Please sign in to comment.