Skip to content

Commit

Permalink
Thermal Vision (#1131)
Browse files Browse the repository at this point in the history
* WIP thermals

* WIP its working

* Thermals done

* fixed formatting and few mistakes

* Update Content.Client/SS220/Thermals/ThermalVisionSystem.cs

Co-authored-by: Anri <[email protected]>

* Thermals fix

* ThermalFixed

* TestFix

---------

Co-authored-by: Dexler <[email protected]>
Co-authored-by: Anri <[email protected]>
  • Loading branch information
3 people authored Jul 24, 2024
1 parent 8a0153f commit 229cd77
Show file tree
Hide file tree
Showing 32 changed files with 657 additions and 2 deletions.
93 changes: 93 additions & 0 deletions Content.Client/SS220/Thermals/ThermalVisionOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Original code github.com/CM-14 Licence MIT, EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using System.Numerics;
using Content.Shared.SS220.Thermals;
using Content.Shared.Mobs.Components;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Serilog;
using Robust.Client.ComponentTrees;

namespace Content.Client.SS220.Thermals;

public sealed class ThermalVisionOverlay : Overlay
{
[Dependency] private readonly IEntityManager _entity = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;

private readonly ContainerSystem _container;
private readonly TransformSystem _transform;
private readonly EntityLookupSystem _entityLookup;
private readonly float _showRadius;
private readonly float _showCloseRadius;
private const float MIN_RANGE = 0.3f;
public override OverlaySpace Space => OverlaySpace.WorldSpace;

public ThermalVisionOverlay(float showRadius)
{
IoCManager.InjectDependencies(this);

_container = _entity.System<ContainerSystem>();
_transform = _entity.System<TransformSystem>();
_entityLookup = _entity.System<EntityLookupSystem>();

_showRadius = showRadius;
_showCloseRadius = _showRadius / 4 < MIN_RANGE ? MIN_RANGE : _showRadius / 4;
}

protected override void Draw(in OverlayDrawArgs args)
{
if (_playerManager.LocalEntity == null)
return;

if (!_entity.TryGetComponent(_playerManager.LocalEntity, out ThermalVisionComponent? thermalVision) ||
thermalVision.State == ThermalVisionState.Off)
return;

if (_entity.TryGetComponent<TransformComponent>(_playerManager.LocalEntity,
out var playerTransform) == false)
return; // maybe need to log it
var handle = args.WorldHandle;
var eye = args.Viewport.Eye;
var eyeRot = eye?.Rotation ?? default;

if (_showRadius < MIN_RANGE)
return; // can cause execp also need to log it

var entities = _entityLookup.GetEntitiesInRange<MobStateComponent>(playerTransform.Coordinates, _showRadius);
var entitiesClose = _entityLookup.GetEntitiesInRange<MobStateComponent>(playerTransform.Coordinates, _showCloseRadius);

foreach (var (uid, stateComp) in entities)
{
if (_entity.TryGetComponent<SpriteComponent>(uid, out var sprite) == false)
continue;
if (_entity.TryGetComponent<TransformComponent>(uid, out var xform) == false)
continue;
if (_container.IsEntityOrParentInContainer(uid)
&& entitiesClose.Contains((uid, stateComp)) == false)
continue;

Render((uid, sprite, xform), eye?.Position.MapId, handle, eyeRot);
}
handle.SetTransform(Matrix3x2.Identity);
}

private void Render(Entity<SpriteComponent, TransformComponent> ent,
MapId? map, DrawingHandleWorld handle, Angle eyeRot)
{
var (uid, sprite, xform) = ent;
if (xform.MapID != map)
return;



var position = _transform.GetWorldPosition(xform);
var rotation = _transform.GetWorldRotation(xform);

sprite.Render(handle, eyeRot, rotation, position: position);
}
}
80 changes: 80 additions & 0 deletions Content.Client/SS220/Thermals/ThermalVisionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Original code github.com/CM-14 Licence MIT, All edits under © SS220, EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.SS220.Thermals;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Player;

namespace Content.Client.SS220.Thermals;

public sealed class ThermalVisionSystem : SharedThermalVisonSystem
{
[Dependency] private readonly ILightManager _light = default!;
[Dependency] private readonly IOverlayManager _overlay = default!;
[Dependency] private readonly IPlayerManager _player = default!;

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

SubscribeLocalEvent<ThermalVisionComponent, LocalPlayerAttachedEvent>(OnThermalAttached);
SubscribeLocalEvent<ThermalVisionComponent, LocalPlayerDetachedEvent>(OnThermalDetached);
}
private void OnThermalAttached(Entity<ThermalVisionComponent> ent, ref LocalPlayerAttachedEvent args)
{
ThermalVisionChanged(ent);
}

private void OnThermalDetached(Entity<ThermalVisionComponent> ent, ref LocalPlayerDetachedEvent args)
{
Off(ent.Comp.ThermalVisionRadius);
}

protected override void ThermalVisionChanged(Entity<ThermalVisionComponent> ent)
{
if (ent != _player.LocalEntity)
return;
// Do you know what is the worst finite state automat realization?
// After code below you will know
switch (ent.Comp.State)
{
case ThermalVisionState.Off:
Off(ent.Comp.ThermalVisionRadius);
break;
case ThermalVisionState.Half:
Off(ent.Comp.ThermalVisionRadius);
Half(ent.Comp.ThermalVisionRadius);
break;
case ThermalVisionState.Full:
Full(ent.Comp.ThermalVisionRadius);
break;
default:
throw new ArgumentOutOfRangeException();
}
}

protected override void ThermalVisionRemoved(Entity<ThermalVisionComponent> ent)
{
if (ent != _player.LocalEntity)
return;

Off(ent.Comp.ThermalVisionRadius);
}

private void Off(float radius)
{
_overlay.RemoveOverlay(new ThermalVisionOverlay(radius));
_light.DrawLighting = true;
}

private void Half(float radius)
{
_overlay.AddOverlay(new ThermalVisionOverlay(radius));
_light.DrawLighting = true;
}

private void Full(float radius)
{
_overlay.AddOverlay(new ThermalVisionOverlay(radius));
_light.DrawLighting = false;
}
}
12 changes: 12 additions & 0 deletions Content.Server/Mindshield/MindShieldSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Content.Shared.Mindshield.Components;
using Content.Shared.Revolutionary.Components;
using Content.Shared.Tag;
using Content.Server.SS220.Thermals;

namespace Content.Server.Mindshield;

Expand All @@ -32,6 +33,10 @@ public sealed class MindShieldSystem : EntitySystem
[ValidatePrototypeId<TagPrototype>]
public const string MindSlaveTag = "MindSlave";
//SS220-mindslave end
//SS220 Thermal implant begin
[ValidatePrototypeId<TagPrototype>]
public const string ThermalImplantTag = "ThermalImplant";
//SS220 Thermal implant ends

public override void Initialize()
{
Expand All @@ -57,6 +62,13 @@ public void ImplantCheck(EntityUid uid, SubdermalImplantComponent comp, ref Impl
_sharedSubdermalImplant.ForceRemove(ev.Implanted.Value, ev.Implant);
}
//SS220-mindslave end
//SS220 Thermalvisionimplant begins
if (_tag.HasTag(ev.Implant, ThermalImplantTag) && ev.Implanted != null)
{
EnsureComp<ThermalVisionImplantComponent>(ev.Implanted.Value);
}
// else (_tag.HasTag(ev.Implant, ThermalImplantTag) && ev.Implanted != null)
//SS220 Thermalvisionimplant ends
}

/// <summary>
Expand Down
14 changes: 14 additions & 0 deletions Content.Server/SS220/Thermals/ThermalVisionClothingComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Robust.Shared.GameStates;

namespace Content.Server.SS220.Thermals;

/// <summary>
/// Adds ThermalComponent to the user when enabled, either by an action or the system's SetEnabled method.
/// </summary>
[RegisterComponent]
public sealed partial class ThermalVisionClothingComponent : Component
{
[DataField, ViewVariables]
public float ThermalVisionRadius = 8f;
}
38 changes: 38 additions & 0 deletions Content.Server/SS220/Thermals/ThermalVisionClothingSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.Inventory.Events;
using Content.Shared.SS220.Thermals;


namespace Content.Server.SS220.Thermals;

/// <summary>
/// Handles enabling of thermal vision when clothing is equipped and disabling when unequipped.
/// </summary>
public sealed class ThermalVisionClothingSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ThermalVisionClothingComponent, GotEquippedEvent>(OnCompEquip);
SubscribeLocalEvent<ThermalVisionClothingComponent, GotUnequippedEvent>(OnCompUnequip);
}
private void OnCompEquip(Entity<ThermalVisionClothingComponent> ent, ref GotEquippedEvent args)
{
if (args.Slot != "eyes")
return;

if (!TryComp<ThermalVisionComponent>(args.Equipee, out var thermalVisionComp))
{
AddComp(args.Equipee, new ThermalVisionComponent(ent.Comp.ThermalVisionRadius));
return;
}
}

private void OnCompUnequip(Entity<ThermalVisionClothingComponent> ent, ref GotUnequippedEvent args)
{
if (HasComp<ThermalVisionComponent>(args.Equipee))
RemComp<ThermalVisionComponent>(args.Equipee);
}

}
16 changes: 16 additions & 0 deletions Content.Server/SS220/Thermals/ThermalVisionImplantComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Robust.Shared.GameStates;

namespace Content.Server.SS220.Thermals;

/// <summary>
/// Adds ThermalComponent to the user when implant action is used.
/// </summary>
[RegisterComponent]
public sealed partial class ThermalVisionImplantComponent : Component
{
[DataField]
public bool IsAcive = false;
[DataField, ViewVariables]
public float ThermalVisionRadius = 8f;
}
37 changes: 37 additions & 0 deletions Content.Server/SS220/Thermals/ThermalVisionImplantSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.SS220.Thermals;


namespace Content.Server.SS220.Thermals;

/// <summary>
/// Handles enabling of thermal vision when clothing is equipped and disabling when unequipped.
/// </summary>
public sealed class SharedThermalVisionImplantSystem : EntitySystem
{

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

SubscribeLocalEvent<ThermalVisionImplantComponent, UseThermalVisionEvent>(OnThermalVisionAction);
}

private void OnThermalVisionAction(Entity<ThermalVisionImplantComponent> ent, ref UseThermalVisionEvent args)
{
if (!TryComp<ThermalVisionImplantComponent>(args.Performer, out var thermalVisionImpalnt))
return;

if (HasComp<ThermalVisionComponent>(args.Performer) && thermalVisionImpalnt.IsAcive)
RemComp<ThermalVisionComponent>(args.Performer);
else if (!TryComp<ThermalVisionComponent>(args.Performer, out var thermalVision))
AddComp(args.Performer, new ThermalVisionComponent(ent.Comp.ThermalVisionRadius));
else
{
thermalVision.ThermalVisionRadius = ent.Comp.ThermalVisionRadius;
Dirty(args.Performer, thermalVision);
}

thermalVisionImpalnt.IsAcive = !thermalVisionImpalnt.IsAcive;
}
}
9 changes: 8 additions & 1 deletion Content.Shared/Implants/SharedSubdermalImplantSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Content.Shared.Interaction.Events;
using Content.Shared.Mindshield.Components;
using Content.Shared.Mobs;
using Content.Shared.SS220.Thermals;
using Content.Shared.Tag;
using JetBrains.Annotations;
using Robust.Shared.Containers;
Expand All @@ -30,6 +31,9 @@ public abstract class SharedSubdermalImplantSystem : EntitySystem
[ValidatePrototypeId<TagPrototype>]
public const string MindShieldTag = "MindShield";
//SS220-removable-mindshield end
//SS220 thermalvision begin
public const string ThermalImplantTag = "ThermalImplant";
//SS220 thermalvision end

public override void Initialize()
{
Expand Down Expand Up @@ -95,7 +99,10 @@ private void OnRemove(EntityUid uid, SubdermalImplantComponent component, EntGot
if (_tag.HasTag(uid, MindShieldTag) && TryComp<MindShieldComponent>(component.ImplantedEntity.Value, out var mindShield))
RemComp(component.ImplantedEntity.Value, mindShield);
//SS220-removable-mindshield end

//SS220 thermalvision begin
if (_tag.HasTag(uid, ThermalImplantTag) && TryComp<ThermalVisionComponent>(component.ImplantedEntity.Value, out var thermalVision))
RemComp(component.ImplantedEntity.Value, thermalVision);
//SS220 thermalvision end
if (!_container.TryGetContainer(uid, BaseStorageId, out var storageImplant))
return;

Expand Down
39 changes: 39 additions & 0 deletions Content.Shared/SS220/Thermals/ThermalVisionComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Original code github.com/CM-14 Licence MIT, EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.Actions;
using Content.Shared.Alert;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;

namespace Content.Shared.SS220.Thermals;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
public sealed partial class ThermalVisionComponent : Component
{
[DataField]
public ProtoId<AlertPrototype> Alert = "ThermalVision";

[DataField, AutoNetworkedField]
public ThermalVisionState State = ThermalVisionState.Half;

[ViewVariables, AutoNetworkedField]
public float ThermalVisionRadius = 8f;

public ThermalVisionComponent(float radius)
{
ThermalVisionRadius = radius;
}
}

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

public sealed partial class UseThermalVisionEvent : InstantActionEvent
{

}
Loading

0 comments on commit 229cd77

Please sign in to comment.