Files
tbd-station-14/Content.Client/Turrets/DeployableTurretSystem.cs
chromiumboy dfd3e36a0a Sentry turrets - Part 4: The sentry turret and its primary systems (#35123)
* Initial commit

* Removed mention of StationAiTurretComponent (for now)

* Prep for moving out of draft

* Fixing merge conflict

* Re-added new net frequencies to AI turrets

* Removed turret control content

* Removed unintended change

* Final tweaks

* Fixed incorrect file name

* Improvement to fire mode handling

* Addressed review comments

* Updated how turret wire panel auto-closing is handled

* Ranged NPCs no longer waste shots on stunned targets

* Fixed bug in tracking broken state

* Addressed review comments

* Bug fix

* Removed unnecessary event call
2025-03-29 12:55:58 -05:00

122 lines
4.6 KiB
C#

using Content.Client.Power;
using Content.Shared.Turrets;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
namespace Content.Client.Turrets;
public sealed partial class DeployableTurretSystem : SharedDeployableTurretSystem
{
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly AnimationPlayerSystem _animation = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DeployableTurretComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<DeployableTurretComponent, AnimationCompletedEvent>(OnAnimationCompleted);
SubscribeLocalEvent<DeployableTurretComponent, AppearanceChangeEvent>(OnAppearanceChange);
}
private void OnComponentInit(Entity<DeployableTurretComponent> ent, ref ComponentInit args)
{
ent.Comp.DeploymentAnimation = new Animation
{
Length = TimeSpan.FromSeconds(ent.Comp.DeploymentLength),
AnimationTracks = {
new AnimationTrackSpriteFlick() {
LayerKey = DeployableTurretVisuals.Turret,
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(ent.Comp.DeployingState, 0f)}
},
}
};
ent.Comp.RetractionAnimation = new Animation
{
Length = TimeSpan.FromSeconds(ent.Comp.RetractionLength),
AnimationTracks = {
new AnimationTrackSpriteFlick() {
LayerKey = DeployableTurretVisuals.Turret,
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(ent.Comp.RetractingState, 0f)}
},
}
};
}
private void OnAnimationCompleted(Entity<DeployableTurretComponent> ent, ref AnimationCompletedEvent args)
{
if (args.Key != DeployableTurretComponent.AnimationKey)
return;
if (!TryComp<SpriteComponent>(ent, out var sprite))
return;
if (!_appearance.TryGetData<DeployableTurretState>(ent, DeployableTurretVisuals.Turret, out var state))
state = ent.Comp.VisualState;
// Convert to terminal state
var targetState = state & DeployableTurretState.Deployed;
UpdateVisuals(ent, targetState, sprite, args.AnimationPlayer);
}
private void OnAppearanceChange(Entity<DeployableTurretComponent> ent, ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
return;
if (!TryComp<AnimationPlayerComponent>(ent, out var animPlayer))
return;
if (!_appearance.TryGetData<DeployableTurretState>(ent, DeployableTurretVisuals.Turret, out var state, args.Component))
state = DeployableTurretState.Retracted;
UpdateVisuals(ent, state, args.Sprite, animPlayer);
}
private void UpdateVisuals(Entity<DeployableTurretComponent> ent, DeployableTurretState state, SpriteComponent sprite, AnimationPlayerComponent? animPlayer = null)
{
if (!Resolve(ent, ref animPlayer))
return;
if (_animation.HasRunningAnimation(ent, animPlayer, DeployableTurretComponent.AnimationKey))
return;
if (state == ent.Comp.VisualState)
return;
var targetState = state & DeployableTurretState.Deployed;
var destinationState = ent.Comp.VisualState & DeployableTurretState.Deployed;
if (targetState != destinationState)
targetState = targetState | DeployableTurretState.Retracting;
ent.Comp.VisualState = state;
// Toggle layer visibility
sprite.LayerSetVisible(DeployableTurretVisuals.Weapon, (targetState & DeployableTurretState.Deployed) > 0);
sprite.LayerSetVisible(PowerDeviceVisualLayers.Powered, HasAmmo(ent) && targetState == DeployableTurretState.Retracted);
// Change the visual state
switch (targetState)
{
case DeployableTurretState.Deploying:
_animation.Play((ent, animPlayer), (Animation)ent.Comp.DeploymentAnimation, DeployableTurretComponent.AnimationKey);
break;
case DeployableTurretState.Retracting:
_animation.Play((ent, animPlayer), (Animation)ent.Comp.RetractionAnimation, DeployableTurretComponent.AnimationKey);
break;
case DeployableTurretState.Deployed:
sprite.LayerSetState(DeployableTurretVisuals.Turret, ent.Comp.DeployedState);
break;
case DeployableTurretState.Retracted:
sprite.LayerSetState(DeployableTurretVisuals.Turret, ent.Comp.RetractedState);
break;
}
}
}