-
Notifications
You must be signed in to change notification settings - Fork 48
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
base: master
Are you sure you want to change the base?
Holograms #233
Changes from 23 commits
707cd02
51f9f7a
dda4ecb
a130117
be2c58e
c0c4f96
b1cefe2
4f45ffd
6e1458c
3688ea1
731832e
f8c39b3
aa7ec26
232b0c6
10e158e
7986db5
45a55d5
5279c73
15995ca
4718be2
29de297
d29cb66
22d3845
311227d
f6706a9
bc384d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
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(); | ||
} | ||
} |
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"), | ||
}) | ||
} | ||
}, | ||
} | ||
}, | ||
} | ||
}); | ||
} | ||
} |
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
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; | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
} |
This file was deleted.
This file was deleted.
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||
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)); | ||||||||
} | ||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||||||||
} | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
burn