Files
OldThink/Content.Server/_White/Wizard/Charging/ChargingSystem.cs

202 lines
5.4 KiB
C#
Raw Normal View History

using Content.Server.Actions;
using Content.Shared._White.Wizard;
using Content.Shared._White.Wizard.Charging;
using Content.Shared.Actions;
using Content.Shared.Follower;
using Content.Shared.Mobs;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Player;
namespace Content.Server._White.Wizard.Charging;
public sealed class ChargingSystem : SharedChargingSystem
{
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly FollowerSystem _followerSystem = default!;
[Dependency] private readonly ActionsSystem _actionsSystem = default!;
private readonly Dictionary<EntityUid, List<EntityUid>> _charges = new();
private readonly Dictionary<EntityUid, EntityUid> _chargingLoops = new();
private readonly Dictionary<EntityUid, EntityUid> _chargedLoop = new();
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<RequestSpellChargingAudio>(OnCharging);
SubscribeNetworkEvent<RequestSpellChargedAudio>(OnCharged);
SubscribeNetworkEvent<RequestAudioSpellStop>(OnStop);
SubscribeLocalEvent<PlayerDetachedEvent>(OnDetach);
SubscribeLocalEvent<MobStateChangedEvent>(OnStateChanged);
SubscribeNetworkEvent<AddWizardChargeEvent>(Add);
SubscribeNetworkEvent<RemoveWizardChargeEvent>(Remove);
}
#region Audio
private void OnCharging(RequestSpellChargingAudio msg, EntitySessionEventArgs args)
{
var user = args.SenderSession?.AttachedEntity;
if (user == null)
return;
var shouldLoop = msg.Loop;
var sound = msg.Sound;
if (!shouldLoop)
{
_audio.PlayPvs(sound, user.Value);
return;
}
if (_chargingLoops.TryGetValue(user.Value, out var currentStream))
{
_audio.Stop(currentStream);
_chargingLoops.Remove(user.Value);
}
var newStream = _audio.PlayPvs(sound, user.Value, AudioParams.Default.WithLoop(true));
if (newStream.HasValue)
{
_chargingLoops[user.Value] = newStream.Value.Entity;
}
}
private void OnCharged(RequestSpellChargedAudio msg, EntitySessionEventArgs args)
{
var user = args.SenderSession?.AttachedEntity;
if (user == null)
return;
if (_chargingLoops.TryGetValue(user.Value, out var currentStream))
{
_audio.Stop(currentStream);
_chargingLoops.Remove(user.Value);
}
var shouldLoop = msg.Loop;
var sound = msg.Sound;
if (!shouldLoop)
{
_audio.PlayPvs(sound, user.Value);
return;
}
if (_chargedLoop.TryGetValue(user.Value, out var chargedLoop))
{
_audio.Stop(chargedLoop);
_chargedLoop.Remove(user.Value);
}
var newStream = _audio.PlayPvs(sound, user.Value, AudioParams.Default.WithLoop(true));
if (newStream.HasValue)
{
_chargedLoop[user.Value] = newStream.Value.Entity;
}
}
private void OnStop(RequestAudioSpellStop msg, EntitySessionEventArgs args)
{
var user = args.SenderSession?.AttachedEntity;
if (user == null)
return;
StopAllSounds(user.Value);
}
#endregion
#region Charges
private void OnDetach(PlayerDetachedEvent msg)
{
var user = msg.Entity;
RemoveAllCharges(user);
StopAllSounds(user);
}
private void OnStateChanged(MobStateChangedEvent ev)
{
var user = ev.Target;
RemoveAllCharges(user);
StopAllSounds(user);
}
private void Add(AddWizardChargeEvent msg, EntitySessionEventArgs args)
{
var spell = GetEntity(msg.Spell);
if (!_actionsSystem.TryGetActionData(spell, out var baseAction) ||
baseAction is not BaseTargetActionComponent action || !action.IsChargeEnabled)
{
return;
}
if (args.SenderSession.AttachedEntity != null)
AddCharge(args.SenderSession.AttachedEntity.Value, action.ChargeProto);
}
private void Remove(RemoveWizardChargeEvent msg, EntitySessionEventArgs args)
{
if (args.SenderSession.AttachedEntity != null)
RemoveAllCharges(args.SenderSession.AttachedEntity.Value);
}
#endregion
#region Helpers
public void StopAllSounds(EntityUid uid)
{
if (_chargingLoops.TryGetValue(uid, out var currentStream))
{
_audio.Stop(currentStream);
_chargingLoops.Remove(uid);
}
if (_chargedLoop.TryGetValue(uid, out var chargedLoop))
{
_audio.Stop(chargedLoop);
_chargedLoop.Remove(uid);
}
}
public void AddCharge(EntityUid uid, string msgChargeProto)
{
var itemEnt = Spawn(msgChargeProto, Transform(uid).Coordinates);
_followerSystem.StartFollowingEntity(itemEnt, uid);
if (!_charges.ContainsKey(uid))
{
_charges[uid] = new List<EntityUid>();
}
_charges[uid].Add(itemEnt);
}
public void RemoveAllCharges(EntityUid uid)
{
if (!_charges.ContainsKey(uid))
return;
foreach (var followerEnt in _charges[uid])
{
Del(followerEnt);
}
_charges.Remove(uid);
}
#endregion
}