Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mics #7

Merged
merged 2 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions Content.Server/ADT/NightVision/NightVisionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995

using Content.Shared.ADT.NightVision;

namespace Content.Server.ADT.NightVision;

public sealed class NightVisionSystem : SharedNightVisionSystem;
25 changes: 25 additions & 0 deletions Content.Shared/ADT/NightVision/ADTNightVisionVisibleComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995

using Robust.Shared.GameStates;

namespace Content.Shared.ADT.NightVision;

/// <summary>
/// For rendering sprites on top of FOV when the user has a <see cref="NightVisionComponent"/>.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class NightVisionVisibleComponent : Component
{
/// <summary>
/// Priority for rendering order.
/// Rendered from lowest to highest, which means higher numbers will be rendered above lower numbers.
/// </summary>
[DataField, AutoNetworkedField]
public int Priority = 0;

/// <summary>
/// Transparency of the rendered sprite.
/// </summary>
[DataField, AutoNetworkedField]
public float? Transparency = null;
}
38 changes: 38 additions & 0 deletions Content.Shared/ADT/NightVision/NightVisionComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995

using Content.Shared.Alert;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;

namespace Content.Shared.ADT.NightVision;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedNightVisionSystem))]
public sealed partial class NightVisionComponent : Component
{
[DataField]
public ProtoId<AlertPrototype>? Alert;

[DataField, AutoNetworkedField]
public NightVisionState State = NightVisionState.Full;

[DataField, AutoNetworkedField]
public bool Overlay;

[DataField, AutoNetworkedField]
public bool Innate;

[DataField, AutoNetworkedField]
public bool SeeThroughContainers;
}

[Serializable, NetSerializable]
public enum NightVisionState
{
Off,
Half,
Full
}

public sealed partial class ToggleNightVision : BaseAlertEvent;
28 changes: 28 additions & 0 deletions Content.Shared/ADT/NightVision/NightVisionItemComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995

using Content.Shared.Inventory;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;

namespace Content.Shared.ADT.NightVision;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedNightVisionSystem))]
public sealed partial class NightVisionItemComponent : Component
{
[DataField, AutoNetworkedField]
public EntProtoId ActionId = "ActionToggleNinjaNightVision";

[DataField, AutoNetworkedField]
public EntityUid? Action;

[DataField, AutoNetworkedField]
public EntityUid? User;

[DataField, AutoNetworkedField]
public bool Toggleable = true;

// Only allows for a single slotflag right now because some code uses strings and some code uses enums to determine slots :(
[DataField, AutoNetworkedField]
public SlotFlags SlotFlags { get; set; } = SlotFlags.EYES;
}
11 changes: 11 additions & 0 deletions Content.Shared/ADT/NightVision/NightVisionItemVisuals.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995

using Robust.Shared.Serialization;

namespace Content.Shared.ADT.NightVision;

[Serializable, NetSerializable]
public enum NightVisionItemVisuals
{
Active,
}
201 changes: 201 additions & 0 deletions Content.Shared/ADT/NightVision/SharedNightVisionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
// taken and adapted from https://github.com/RMC-14/RMC-14?ysclid=lzx00zxd6e53093995

using Content.Shared.Actions;
using Content.Shared.Alert;
using Content.Shared.Inventory.Events;
using Content.Shared.Rounding;
using Content.Shared.Toggleable;
using Robust.Shared.Timing;

namespace Content.Shared.ADT.NightVision;

public abstract class SharedNightVisionSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly IGameTiming _timing = default!;

public override void Initialize()
{
SubscribeLocalEvent<NightVisionComponent, ComponentStartup>(OnNightVisionStartup);
SubscribeLocalEvent<NightVisionComponent, MapInitEvent>(OnNightVisionMapInit);
SubscribeLocalEvent<NightVisionComponent, AfterAutoHandleStateEvent>(OnNightVisionAfterHandle);
SubscribeLocalEvent<NightVisionComponent, ComponentRemove>(OnNightVisionRemove);

SubscribeLocalEvent<NightVisionItemComponent, GetItemActionsEvent>(OnNightVisionItemGetActions);
SubscribeLocalEvent<NightVisionItemComponent, ToggleActionEvent>(OnNightVisionItemToggle);
SubscribeLocalEvent<NightVisionItemComponent, GotEquippedEvent>(OnNightVisionItemGotEquipped);
SubscribeLocalEvent<NightVisionItemComponent, GotUnequippedEvent>(OnNightVisionItemGotUnequipped);
SubscribeLocalEvent<NightVisionItemComponent, ActionRemovedEvent>(OnNightVisionItemActionRemoved);
SubscribeLocalEvent<NightVisionItemComponent, ComponentRemove>(OnNightVisionItemRemove);
SubscribeLocalEvent<NightVisionItemComponent, EntityTerminatingEvent>(OnNightVisionItemTerminating);
}

private void OnNightVisionStartup(Entity<NightVisionComponent> ent, ref ComponentStartup args)
{
NightVisionChanged(ent);
}

private void OnNightVisionAfterHandle(Entity<NightVisionComponent> ent, ref AfterAutoHandleStateEvent args)
{
NightVisionChanged(ent);
}

private void OnNightVisionMapInit(Entity<NightVisionComponent> ent, ref MapInitEvent args)
{
UpdateAlert(ent);
}

private void OnNightVisionRemove(Entity<NightVisionComponent> ent, ref ComponentRemove args)
{
if (ent.Comp.Alert is { } alert)
_alerts.ClearAlert(ent, alert);

NightVisionRemoved(ent);
}

private void OnNightVisionItemGetActions(Entity<NightVisionItemComponent> ent, ref GetItemActionsEvent args)
{
if (args.InHands || !ent.Comp.Toggleable)
return;

if (ent.Comp.SlotFlags != args.SlotFlags)
return;

args.AddAction(ref ent.Comp.Action, ent.Comp.ActionId);
}

private void OnNightVisionItemToggle(Entity<NightVisionItemComponent> ent, ref ToggleActionEvent args)
{
if (args.Handled)
return;

args.Handled = true;
ToggleNightVisionItem(ent, args.Performer);
}

private void OnNightVisionItemGotEquipped(Entity<NightVisionItemComponent> ent, ref GotEquippedEvent args)
{
if (ent.Comp.SlotFlags != args.SlotFlags)
return;

EnableNightVisionItem(ent, args.Equipee);
}

private void OnNightVisionItemGotUnequipped(Entity<NightVisionItemComponent> ent, ref GotUnequippedEvent args)
{
if (ent.Comp.SlotFlags != args.SlotFlags)
return;

DisableNightVisionItem(ent, args.Equipee);
}

private void OnNightVisionItemActionRemoved(Entity<NightVisionItemComponent> ent, ref ActionRemovedEvent args)
{
DisableNightVisionItem(ent, ent.Comp.User);
}

private void OnNightVisionItemRemove(Entity<NightVisionItemComponent> ent, ref ComponentRemove args)
{
DisableNightVisionItem(ent, ent.Comp.User);
}

private void OnNightVisionItemTerminating(Entity<NightVisionItemComponent> ent, ref EntityTerminatingEvent args)
{
DisableNightVisionItem(ent, ent.Comp.User);
}

public void Toggle(Entity<NightVisionComponent?> ent)
{
if (!Resolve(ent, ref ent.Comp))
return;

ent.Comp.State = ent.Comp.State switch
{
NightVisionState.Off => NightVisionState.Half,
NightVisionState.Half => NightVisionState.Full,
NightVisionState.Full => NightVisionState.Off,
_ => throw new ArgumentOutOfRangeException(),
};

Dirty(ent);
UpdateAlert((ent, ent.Comp));
}

private void UpdateAlert(Entity<NightVisionComponent> ent)
{
if (ent.Comp.Alert is { } alert)
{
var level = MathF.Max((int) NightVisionState.Off, (int) ent.Comp.State);
var max = _alerts.GetMaxSeverity(alert);
var severity = max - ContentHelpers.RoundToLevels(level, (int) NightVisionState.Full, max + 1);
_alerts.ShowAlert(ent, alert, (short) severity);
}

NightVisionChanged(ent);
}

private void ToggleNightVisionItem(Entity<NightVisionItemComponent> item, EntityUid user)
{
if (item.Comp.User == user && item.Comp.Toggleable)
{
DisableNightVisionItem(item, item.Comp.User);
return;
}

EnableNightVisionItem(item, user);
}

private void EnableNightVisionItem(Entity<NightVisionItemComponent> item, EntityUid user)
{
DisableNightVisionItem(item, item.Comp.User);

item.Comp.User = user;
Dirty(item);

_appearance.SetData(item, NightVisionItemVisuals.Active, true);

if (!_timing.ApplyingState)
{
var nightVision = EnsureComp<NightVisionComponent>(user);
nightVision.State = NightVisionState.Full;
Dirty(user, nightVision);
}

_actions.SetToggled(item.Comp.Action, true);
}

protected virtual void NightVisionChanged(Entity<NightVisionComponent> ent)
{
}

protected virtual void NightVisionRemoved(Entity<NightVisionComponent> ent)
{
}

protected void DisableNightVisionItem(Entity<NightVisionItemComponent> item, EntityUid? user)
{
_actions.SetToggled(item.Comp.Action, false);

item.Comp.User = null;
Dirty(item);

_appearance.SetData(item, NightVisionItemVisuals.Active, false);

if (TryComp(user, out NightVisionComponent? nightVision) &&
!nightVision.Innate)
{
RemCompDeferred<NightVisionComponent>(user.Value);
}
}

public void SetSeeThroughContainers(Entity<NightVisionComponent?> ent, bool see)
{
if (!Resolve(ent, ref ent.Comp, false))
return;

ent.Comp.SeeThroughContainers = see;
Dirty(ent);
}
}
13 changes: 13 additions & 0 deletions Content.Shared/ADT/NightVision/ToggleNightVision.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//using Content.Shared.Alert;

//namespace Content.Shared.ADT.NightVision;

//[DataDefinition]
//public sealed partial class ToggleNightVision : IAlertClick
//{
// public void AlertClicked(EntityUid player)
// {
// var entities = IoCManager.Resolve<IEntityManager>();
// entities.System<SharedNightVisionSystem>().Toggle(player);
// }
//}
38 changes: 38 additions & 0 deletions Resources/Prototypes/_Silver/Surgery/implants.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# - type: NightVisionItem # RMC Night vision
# - type: ItemToggle

- type: entity
parent: BasicCyberneticEyes
id: NightVisionCyberneticEyes
name: cybernetic eyes
description: A pair of cybernetic eyes that enhance your vision, and protect you from eye damage.
components:
- type: Organ
onAdd:
- type: InstantAction
icon:
sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
state: icon
iconOn:
sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
state: icon
event: !type:ToggleActionEvent
useDelay: 0.25
- NightVisionComponent
- NightVisionItemComponent

- type: entity
id: ActionToggleNinjaNightVision
categories: [HideSpawnMenu]
name: Toggle ninja visor nightvision
description: Allows you to see even in complete darkness.
components:
- type: InstantAction
icon:
sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
state: icon
iconOn:
sprite: Clothing/Eyes/Glasses/ninjavisor.rsi
state: icon
event: !type:ToggleActionEvent
useDelay: 0.25
Loading
Loading