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

Holograms #233

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
707cd02
Added a new mob typed named Hologram, set up a clone of the Drone whi…
Pspritechologist Feb 7, 2023
51f9f7a
adds early scutters, and the basis of a charging system.
Pspritechologist Feb 13, 2023
dda4ecb
Working on it
Pspritechologist Feb 14, 2023
a130117
Lots more work towards holograms, probably too long without committin…
Pspritechologist Feb 24, 2023
be2c58e
Committing more
Pspritechologist Feb 25, 2023
c0c4f96
More work on Holograms. Moved most things over to events, bug where h…
Pspritechologist Feb 26, 2023
b1cefe2
Fixed holocorgi ID
Pspritechologist Feb 27, 2023
4f45ffd
Fuckin working again. Stuff is networked now, though not to any real …
Pspritechologist Feb 28, 2023
6e1458c
Prepared for projected, lightbee, and hardlight holos by separating t…
Pspritechologist Mar 1, 2023
3688ea1
Removed some unneeded things, cleaned some files, made it Holograms c…
Pspritechologist Mar 2, 2023
731832e
Added damage sets for Holograms, kinda fixed rotation on spawn, begun…
Pspritechologist Mar 18, 2023
f8c39b3
Removed unneeded files
Pspritechologist Mar 21, 2023
aa7ec26
Removed unused component
Pspritechologist Mar 31, 2023
232b0c6
Death's tweaks, filtered :)
Pspritechologist Apr 20, 2023
10e158e
Made Enum worked, cleaned up a bit, and fixed all namespaces
Pspritechologist Apr 24, 2023
7986db5
Substantial cleanup to the code post rebase
Pspritechologist Oct 11, 2023
45a55d5
Fixes double-playing audio
Pspritechologist Oct 12, 2023
5279c73
Completely overhauled large portions.
Pspritechologist Oct 15, 2023
15995ca
Bulk of work done towards the HologramProjectedComponent's functional…
Pspritechologist Oct 23, 2023
4718be2
Ton of work refactoring Holograms, generally cleaning it up, and addi…
Pspritechologist Feb 6, 2024
29de297
Merge branch 'master' into holograms
Pspritechologist Feb 7, 2024
d29cb66
Work towards cleaning up, making the Eye better.
Pspritechologist Feb 8, 2024
22d3845
Apply suggestions from code review
Pspritechologist Feb 8, 2024
311227d
Lots of using hardcoded values less, switched collision to a whitelist.
Pspritechologist Feb 8, 2024
f6706a9
Making more things holograms
Pspritechologist Feb 9, 2024
bc384d3
CCTV System is in place for getting Holodisks... *
Pspritechologist Feb 10, 2024
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
44 changes: 44 additions & 0 deletions Content.Client/SimpleStation14/Holograms/AcceptHologramEui.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Content.Client.Eui;
using Content.Client.Holograms;
using Content.Shared.SimpleStation14.Holograms;
using JetBrains.Annotations;
using Robust.Client.Graphics;

namespace Content.Client.SimpleStation14.Holograms;

[UsedImplicitly]
public sealed class AcceptHologramEui : BaseEui
{
private readonly AcceptHologramWindow _window;

public AcceptHologramEui()
{
_window = new AcceptHologramWindow();

_window.DenyButton.OnPressed += _ =>
{
SendMessage(new AcceptHologramChoiceMessage(AcceptHologramUiButton.Deny));
_window.Close();
};

_window.OnClose += () => SendMessage(new AcceptHologramChoiceMessage(AcceptHologramUiButton.Deny));

_window.AcceptButton.OnPressed += _ =>
{
SendMessage(new AcceptHologramChoiceMessage(AcceptHologramUiButton.Accept));
_window.Close();
};
}

public override void Opened()
{
IoCManager.Resolve<IClyde>().RequestWindowAttention();
_window.OpenCentered();
}

public override void Closed()
{
_window.Close();
}

Pspritechologist marked this conversation as resolved.
Show resolved Hide resolved
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

burn

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Numerics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using static Robust.Client.UserInterface.Controls.BoxContainer;

namespace Content.Client.Holograms;

public sealed class AcceptHologramWindow : DefaultWindow
{
public readonly Button DenyButton;
public readonly Button AcceptButton;

public AcceptHologramWindow()
{

Title = Loc.GetString("accept-hologram-window-title");

Contents.AddChild(new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
Children =
{
new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
Children =
{
new Label()
{
Text = Loc.GetString("accept-hologram-window-prompt-text-part")
},
new BoxContainer
{
Orientation = LayoutOrientation.Horizontal,
Align = AlignMode.Center,
Children =
{
(AcceptButton = new Button
{
Text = Loc.GetString("accept-hologram-window-accept-button"),
}),

new Control()
{
MinSize = new Vector2(20, 0)
},

(DenyButton = new Button
{
Text = Loc.GetString("accept-hologram-window-deny-button"),
})
}
},
}
},
}
});
}
}
129 changes: 129 additions & 0 deletions Content.Client/SimpleStation14/Holograms/HologramSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using System.Numerics;
using Content.Shared.SimpleStation14.Holograms;
using Content.Shared.SimpleStation14.Holograms.Components;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Map;

namespace Content.Client.SimpleStation14.Holograms;

public sealed class HologramSystem : SharedHologramSystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly TransformSystem _transform = default!;

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

SubscribeLocalEvent<HologramProjectedComponent, ComponentShutdown>(OnProjectedShutdown);
}

Comment on lines +14 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<HologramProjectedComponent, ComponentShutdown>(OnProjectedShutdown);
}
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<HologramProjectedComponent, ComponentShutdown>(OnProjectedShutdown);
}

public override void Update(float frameTime)
{
var player = _player.LocalPlayer?.ControlledEntity;
if (TryComp<HologramProjectedComponent>(player, out var holoProjComp))
{
ProjectedUpdate(player.Value, holoProjComp, frameTime); // This makes it so only the currently controlled entity is predicted, assuming they're a hologram.

// Check if we should be setting the eye target of the hologram.
if (holoProjComp.SetEyeTarget && TryComp<EyeComponent>(player.Value, out var eyeComp))
eyeComp.Target = holoProjComp.CurProjector;
}

HandleProjectedEffects(EntityQueryEnumerator<HologramProjectedComponent>());
}

private void OnProjectedShutdown(EntityUid hologram, HologramProjectedComponent component, ComponentShutdown args)
{
DeleteEffect(component);

if (component.SetEyeTarget && TryComp<EyeComponent>(hologram, out var eyeComp))
eyeComp.Target = null; // This should be fine? I guess if you're a hologram riding a vehicle when this happens it'd be a bit weird.
}

private void HandleProjectedEffects(EntityQueryEnumerator<HologramProjectedComponent> query)
{
while (query.MoveNext(out var hologram, out var holoProjectedComp))
{
if (holoProjectedComp.EffectPrototype == null)
{
DeleteEffect(holoProjectedComp);
continue;
}

if (!holoProjectedComp.CurrentlyInProjector || holoProjectedComp.CurProjector == null || !Exists(holoProjectedComp.CurProjector.Value))
{
DeleteEffect(holoProjectedComp);
continue;
}

var projector = holoProjectedComp.CurProjector.Value;

var holoXformComp = Transform(hologram);
var holoCoords = _transform.GetMoverCoordinates(hologram, holoXformComp);

var projXformComp = Transform(projector);
var projCoords = _transform.GetMoverCoordinates(projector, projXformComp);

if (holoCoords.EntityId != projCoords.EntityId) // ¯\_(ツ)_/¯
{
DeleteEffect(holoProjectedComp);
continue;
}

var originPos = projCoords.Position;

// Add the effect's offset, if applicable.
if (TryComp<HologramProjectorComponent>(projector, out var projComp))
{
var direction = projXformComp.LocalRotation.GetCardinalDir();

var offset = direction switch
{
Direction.North => projComp.EffectOffsets[Direction.South],
Direction.South => projComp.EffectOffsets[Direction.North],
Direction.East => projComp.EffectOffsets[Direction.West],
Direction.West => projComp.EffectOffsets[Direction.East],
_ => Vector2.Zero
};

originPos += offset;
}

// Determine a middle point between the hologram and the projector.
var effectPos = (holoCoords.Position + originPos) / 2;

// Determine a rotation that points from the projector to the hologram.
var effectRot = (holoCoords.Position - originPos).ToAngle() - MathHelper.PiOver2;

var effectCoords = new EntityCoordinates(holoCoords.EntityId, effectPos);
if (!effectCoords.IsValid(EntityManager))
{
DeleteEffect(holoProjectedComp);
continue;
}

// Set or spawn the effect.
if (holoProjectedComp.EffectEntity == null || !Exists(holoProjectedComp.EffectEntity.Value))
holoProjectedComp.EffectEntity = Spawn(holoProjectedComp.EffectPrototype, effectCoords);
else
_transform.SetLocalPosition(holoProjectedComp.EffectEntity.Value, effectPos);

_transform.SetLocalRotation(holoProjectedComp.EffectEntity.Value, effectRot);

// Determine the scaling factor to make it fit between the hologram and the projector.
var yScale = (holoCoords.Position - originPos).Length();
var effectScale = new Vector2(1, Math.Max(0.1f, yScale)); // No smaller than 0.1.
Comp<SpriteComponent>(holoProjectedComp.EffectEntity.Value).Scale = effectScale;
}
}

private void DeleteEffect(HologramProjectedComponent component)
{
if (component.EffectEntity != null && Exists(component.EffectEntity.Value))
QueueDel(component.EffectEntity.Value);

component.EffectEntity = null;
}
}
5 changes: 0 additions & 5 deletions Content.Server/Nyanotrasen/Holograms/HologramComponent.cs

This file was deleted.

22 changes: 0 additions & 22 deletions Content.Server/Nyanotrasen/Holograms/HologramSystem.cs

This file was deleted.

32 changes: 32 additions & 0 deletions Content.Server/SimpleStation14/Holograms/AcceptHologramEui.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Content.Server.EUI;
using Content.Shared.Eui;
using Content.Shared.SimpleStation14.Holograms;

namespace Content.Server.SimpleStation14.Holograms;

public sealed class AcceptHologramEui : BaseEui
{
private readonly HologramSystem _hologramSystem;
private readonly Mind.Mind _mind;

public AcceptHologramEui(Mind.Mind mind, HologramSystem hologramSys)
{
_mind = mind;
_hologramSystem = hologramSys;
}

Comment on lines +11 to +17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public AcceptHologramEui(Mind.Mind mind, HologramSystem hologramSys)
{
_mind = mind;
_hologramSystem = hologramSys;
}
public AcceptHologramEui(Mind.Mind mind, HologramSystem hologramSys)
{
_mind = mind;
_hologramSystem = hologramSys;
}

public override void HandleMessage(EuiMessageBase msg)
{
base.HandleMessage(msg);

if (msg is not AcceptHologramChoiceMessage choice ||
choice.Button == AcceptHologramUiButton.Deny)
{
Close();
return;
}

_hologramSystem.TransferMindToHologram(_mind);
Close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Content.Server.SimpleStation14.Holograms;

/// <summary>
/// Marks this entity as storing a hologram's data in it, for use in a <see cref="HologramServerComponent"/>.
/// </summary>
[RegisterComponent]
public sealed class HologramDiskComponent : Component
{
/// <summary>
/// The mind stored in this Holodisk.
/// </summary>
[ViewVariables]
public Mind.Mind? HoloMind = null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.SimpleStation14.Holograms.Components;

/// <summary>
/// For any items that should generate a 'dummy' hologram when inserted as a holo disk.
/// Mostly intended for jokes and gaffs, but could be used for useful AI entities as well.
/// </summary>
[RegisterComponent]
public sealed class HologramDiskDummyComponent : Component
{
/// <summary>
/// The prototype to spawn when this disk is inserted into a server.
/// </summary>
[DataField("prototype", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
public string HoloPrototype = default!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.SurveillanceCamera;
using Content.Shared.SimpleStation14.Holograms;
using Content.Shared.SimpleStation14.Holograms.Components;

namespace Content.Server.SimpleStation14.Holograms;

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

SubscribeLocalEvent((EntityUid ent, HologramProjectorComponent comp, ref PowerChangedEvent _) => CheckState(ent, comp));
SubscribeLocalEvent<HologramProjectorComponent, SurveillanceCameraChangeStateEvent>((ent, comp, args) => CheckState(ent, comp));
SubscribeLocalEvent<HologramProjectorComponent, MapInitEvent>((ent, comp, args) => CheckState(ent, comp));
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

public void CheckState(EntityUid projector, HologramProjectorComponent? projComp = null)
{
if (!Resolve(projector, ref projComp))
return;

if (TryComp<ApcPowerReceiverComponent>(projector, out var powerComp) && !powerComp.Powered ||
TryComp<SurveillanceCameraComponent>(projector, out var cameraComp) && !cameraComp.Active)
{
RemComp<HologramProjectorActiveComponent>(projector);
return;
}

EnsureComp<HologramProjectorActiveComponent>(projector);
}
}
Loading
Loading