И твой сорванный голос мне напомнит о прошлом

This commit is contained in:
Remuchi
2024-03-27 21:23:18 +07:00
parent 3c9c149b81
commit 96238b0fb8
29 changed files with 687 additions and 660 deletions

View File

@@ -7,21 +7,21 @@ namespace Content.Client._White.Jukebox;
public sealed class JukeboxBUI : BoundUserInterface
{
[Dependency] private readonly EntityManager _entityManager = default!;
private readonly SharedPopupSystem _sharedPopupSystem = default!;
private JukeboxMenu? _window;
private readonly JukeboxMenu? _window;
public JukeboxBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
_sharedPopupSystem = _entityManager.System<SharedPopupSystem>();
var sharedPopupSystem = _entityManager.System<SharedPopupSystem>();
if (!_entityManager.TryGetComponent(owner, out JukeboxComponent? jukeboxComponent))
{
_sharedPopupSystem.PopupEntity($"Тут нет JukeboxComponent, звоните кодерам", owner);
sharedPopupSystem.PopupEntity("Тут нет JukeboxComponent, звоните кодерам", owner);
return;
}
_window = new JukeboxMenu(jukeboxComponent);
_window = new JukeboxMenu(owner, jukeboxComponent);
_window.RepeatButton.OnToggled += OnRepeatButtonToggled;
_window.StopButton.OnPressed += OnStopButtonPressed;
_window.EjectButton.OnPressed += OnEjectButtonPressed;
@@ -42,7 +42,6 @@ public sealed class JukeboxBUI : BoundUserInterface
SendMessage(new JukeboxRepeatToggled(obj.Pressed));
}
protected override void Open()
{
base.Open();
@@ -64,4 +63,4 @@ public sealed class JukeboxBUI : BoundUserInterface
_window?.Dispose();
}
}
}

View File

@@ -12,20 +12,22 @@ namespace Content.Client._White.Jukebox;
public sealed partial class JukeboxMenu : DefaultWindow
{
[Dependency] private readonly IEntityManager _entityManager = default!;
private readonly JukeboxSystem _jukeboxSystem = default!;
private readonly JukeboxSystem _jukeboxSystem;
private readonly EntityUid _jukeboxEntity;
private readonly JukeboxComponent _component;
private List<JukeboxSongEntry> _defaultSongsEntries = new();
private List<JukeboxSongEntry> _tapeSongsEntries = new();
private readonly List<JukeboxSongEntry> _defaultSongsEntries = [];
private readonly List<JukeboxSongEntry> _tapeSongsEntries = [];
public JukeboxMenu(JukeboxComponent component)
public JukeboxMenu(EntityUid jukeboxEntity, JukeboxComponent component)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_jukeboxSystem = _entityManager.System<JukeboxSystem>();
_jukeboxEntity = jukeboxEntity;
_component = component;
/*TabContainer.SetTabTitle(DefaultSongsTab, "Прямо с завода");*/
@@ -39,7 +41,7 @@ public sealed partial class JukeboxMenu : DefaultWindow
{
CurrenSongLabel.Text = _component.PlayingSongData == null ? "..." : _component.PlayingSongData.SongName!;
RepeatButton.Pressed = _component.Repeating;
RepeatButton.Pressed = _component.Playing;
base.FrameUpdate(args);
}
@@ -94,6 +96,6 @@ public sealed partial class JukeboxMenu : DefaultWindow
private void RequestSongPlay(JukeboxSong song)
{
_jukeboxSystem.RequestSongToPlay(_component, song);
_jukeboxSystem.RequestSongToPlay(_jukeboxEntity, _component, song);
}
}

View File

@@ -8,7 +8,6 @@ using Robust.Client.Player;
using Robust.Client.ResourceManagement;
using Robust.Shared.Audio.Sources;
using Robust.Shared.Configuration;
using Robust.Shared.GameStates;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Utility;
@@ -17,12 +16,14 @@ namespace Content.Client._White.Jukebox;
public sealed class JukeboxSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IResourceCache _resource = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IAudioManager _clydeAudio = default!;
[Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!;
[Dependency] private readonly TransformSystem _transform = default!;
private const CollisionGroup CollisionMask = CollisionGroup.Impassable;
private readonly Dictionary<JukeboxComponent, JukeboxAudio> _playingJukeboxes = new();
@@ -34,7 +35,6 @@ public sealed class JukeboxSystem : EntitySystem
_cfg.OnValueChanged(WhiteCVars.JukeboxVolume, JukeboxVolumeChanged, true);
SubscribeLocalEvent<JukeboxComponent, ComponentHandleState>(OnStateChanged);
SubscribeLocalEvent<JukeboxComponent, ComponentRemove>(OnComponentRemoved);
SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnRoundRestart);
SubscribeNetworkEvent<TickerJoinLobbyEvent>(JoinLobby);
@@ -60,6 +60,7 @@ public sealed class JukeboxSystem : EntitySystem
private void OnComponentRemoved(EntityUid uid, JukeboxComponent component, ComponentRemove args)
{
if (!_playingJukeboxes.TryGetValue(component, out var playingData)) return;
playingData.PlayingStream.StopPlaying();
_playingJukeboxes.Remove(component);
}
@@ -67,36 +68,35 @@ public sealed class JukeboxSystem : EntitySystem
private void OnStopPlaying(JukeboxStopPlaying ev)
{
if (!ev.JukeboxUid.HasValue) return;
if(!TryComp<JukeboxComponent>(GetEntity(ev.JukeboxUid), out var jukeboxComponent)) return;
if (!TryComp<JukeboxComponent>(GetEntity(ev.JukeboxUid), out var jukeboxComponent)) return;
if(!_playingJukeboxes.TryGetValue(jukeboxComponent, out var jukeboxAudio)) return;
if (!_playingJukeboxes.TryGetValue(jukeboxComponent, out var jukeboxAudio)) return;
jukeboxAudio.PlayingStream.StopPlaying();
_playingJukeboxes.Remove(jukeboxComponent);
}
public void RequestSongToPlay(JukeboxComponent component, JukeboxSong jukeboxSong)
public void RequestSongToPlay(EntityUid jukebox, JukeboxComponent component, JukeboxSong jukeboxSong)
{
if (!_resource.TryGetResource<AudioResource>((ResPath) jukeboxSong.SongPath!, out var songResource))
{
return;
}
RaiseNetworkEvent(new JukeboxRequestSongPlay()
RaiseNetworkEvent(new JukeboxRequestSongPlay
{
Jukebox = GetNetEntity(component.Owner),
Jukebox = GetNetEntity(jukebox),
SongName = jukeboxSong.SongName,
SongPath = jukeboxSong.SongPath,
SongDuration = (float)songResource.AudioStream.Length.TotalSeconds
SongDuration = (float) songResource.AudioStream.Length.TotalSeconds
});
}
public override void FrameUpdate(float frameTime)
{
base.FrameUpdate(frameTime);
var localPlayerEntity = _playerManager.LocalPlayer!.ControlledEntity;
var localPlayerEntity = _playerManager.LocalEntity;
if (!localPlayerEntity.HasValue)
{
CleanUp();
@@ -108,18 +108,18 @@ public sealed class JukeboxSystem : EntitySystem
private void ProcessJukeboxes()
{
var jukeboxes = EntityQuery<JukeboxComponent, TransformComponent>();
var playerXform = Comp<TransformComponent>(_playerManager.LocalPlayer!.ControlledEntity!.Value);
var jukeboxes = EntityQueryEnumerator<JukeboxComponent, TransformComponent>();
var player = _playerManager.LocalEntity!.Value;
var playerXform = Comp<TransformComponent>(player);
foreach (var (jukeboxComponent, jukeboxXform) in jukeboxes)
while (jukeboxes.MoveNext(out var jukebox, out var jukeboxComponent, out var jukeboxXform))
{
if (jukeboxXform.MapID != playerXform.MapID || (jukeboxXform.MapPosition.Position - playerXform.MapPosition.Position).Length() > jukeboxComponent.MaxAudioRange)
if (jukeboxXform.MapID != playerXform.MapID ||
(_transform.GetWorldPosition(jukebox) - _transform.GetWorldPosition(player)).Length() >
jukeboxComponent.MaxAudioRange)
{
if (_playingJukeboxes.TryGetValue(jukeboxComponent, out var stream))
if (_playingJukeboxes.Remove(jukeboxComponent, out var stream))
{
_playingJukeboxes.Remove(jukeboxComponent);
stream.PlayingStream.StopPlaying();
stream.PlayingStream.Dispose();
}
@@ -131,28 +131,28 @@ public sealed class JukeboxSystem : EntitySystem
{
if (!jukeboxAudio.PlayingStream.Playing)
{
HandleDoneStream(jukeboxAudio, jukeboxComponent, jukeboxXform, playerXform);
HandleDoneStream(jukebox, player, jukeboxAudio, jukeboxComponent);
continue;
}
if (jukeboxAudio.SongData.SongPath != jukeboxComponent.PlayingSongData?.SongPath)
{
HandleSongChanged(jukeboxAudio, jukeboxComponent, jukeboxXform, playerXform);
HandleSongChanged(jukebox, player, jukeboxAudio, jukeboxComponent);
continue;
}
SetRolloffAndOcclusion(jukeboxComponent, playerXform, jukeboxXform, jukeboxAudio);
SetPosition(jukeboxXform, jukeboxAudio);
SetRolloffAndOcclusion(jukebox, player, jukeboxComponent, jukeboxAudio);
SetPosition(jukebox, jukeboxAudio);
}
else
{
if (jukeboxComponent.PlayingSongData == null)
{
SetBarsLayerVisible(jukeboxComponent, false);
SetBarsLayerVisible(jukebox, false);
continue;
}
var stream = TryCreateStream(jukeboxComponent, jukeboxXform, playerXform);
var stream = TryCreateStream(jukebox, player, jukeboxComponent);
if (stream == null)
{
@@ -160,141 +160,139 @@ public sealed class JukeboxSystem : EntitySystem
}
_playingJukeboxes.Add(jukeboxComponent, stream);
SetBarsLayerVisible(jukeboxComponent, true);
SetBarsLayerVisible(jukebox, true);
}
}
}
private void SetPosition(TransformComponent jukeboxXform, JukeboxAudio jukeboxAudio)
private void SetPosition(EntityUid jukebox, JukeboxAudio jukeboxAudio)
{
jukeboxAudio.PlayingStream.Position = jukeboxXform.MapPosition.Position;
jukeboxAudio.PlayingStream.Position = _transform.GetWorldPosition(jukebox);
}
private void SetRolloffAndOcclusion(JukeboxComponent jukeboxComponent, TransformComponent playerXform, TransformComponent jukeboxXform, JukeboxAudio jukeboxAudio)
private void SetRolloffAndOcclusion(
EntityUid player,
EntityUid jukebox,
JukeboxComponent jukeboxComponent,
JukeboxAudio jukeboxAudio)
{
var collisionMask = CollisionGroup.Impassable;
var sourceRelative = playerXform.MapPosition.Position - jukeboxXform.MapPosition.Position;
var jukeboxWorldPosition = _transform.GetWorldPosition(jukebox);
var playerWorldPosition = _transform.GetWorldPosition(player);
var sourceRelative = playerWorldPosition - jukeboxWorldPosition;
var occlusion = 0f;
if (sourceRelative.Length() > 0)
{
occlusion = _physicsSystem.IntersectRayPenetration(jukeboxXform.MapID,
new CollisionRay(jukeboxXform.MapPosition.Position, sourceRelative.Normalized(), (int)collisionMask),
sourceRelative.Length(), jukeboxXform.Owner) * 3f;
occlusion = _physicsSystem.IntersectRayPenetration(_transform.GetMapCoordinates(jukebox).MapId,
new CollisionRay(jukeboxWorldPosition, sourceRelative.Normalized(), (int) CollisionMask),
sourceRelative.Length(), jukebox) * 3f;
}
jukeboxAudio.PlayingStream.Occlusion = occlusion;
jukeboxAudio.PlayingStream.RolloffFactor = (jukeboxXform.MapPosition.Position - playerXform.MapPosition.Position).Length() * jukeboxComponent.RolloffFactor;
jukeboxAudio.PlayingStream.RolloffFactor =
(jukeboxWorldPosition - playerWorldPosition).Length() * jukeboxComponent.RolloffFactor;
}
private void HandleSongChanged(JukeboxAudio jukeboxAudio, JukeboxComponent jukeboxComponent, TransformComponent jukeboxXform, TransformComponent playerXform)
private void HandleSongChanged(
EntityUid jukebox,
EntityUid player,
JukeboxAudio jukeboxAudio,
JukeboxComponent jukeboxComponent)
{
jukeboxAudio.PlayingStream.StopPlaying();
if (jukeboxComponent.PlayingSongData != null && jukeboxComponent.PlayingSongData.SongPath == jukeboxAudio.SongData.SongPath)
if (jukeboxComponent.PlayingSongData != null &&
jukeboxComponent.PlayingSongData.SongPath == jukeboxAudio.SongData.SongPath)
{
var newStream = TryCreateStream(jukeboxComponent, jukeboxXform, playerXform);
if(newStream == null) return;
var newStream = TryCreateStream(jukebox, player, jukeboxComponent);
if (newStream == null) return;
_playingJukeboxes[jukeboxComponent] = newStream;
SetBarsLayerVisible(jukeboxComponent, true);
SetBarsLayerVisible(jukebox, true);
}
else
{
_playingJukeboxes.Remove(jukeboxComponent);
SetBarsLayerVisible(jukeboxComponent, false);
SetBarsLayerVisible(jukebox, false);
}
}
private void HandleDoneStream(JukeboxAudio jukeboxAudio, JukeboxComponent jukeboxComponent, TransformComponent jukeboxXform, TransformComponent playerXform)
private void HandleDoneStream(
EntityUid jukebox,
EntityUid player,
JukeboxAudio jukeboxAudio,
JukeboxComponent jukeboxComponent)
{
if (!jukeboxComponent.Repeating)
if (!jukeboxComponent.Playing)
{
jukeboxAudio.PlayingStream.StopPlaying();
_playingJukeboxes.Remove(jukeboxComponent);
SetBarsLayerVisible(jukeboxComponent, false);
SetBarsLayerVisible(jukebox, false);
return;
}
if(jukeboxComponent.PlayingSongData == null) return;
if (jukeboxComponent.PlayingSongData == null) return;
var newStream = TryCreateStream(jukeboxComponent, jukeboxXform, playerXform);
var newStream = TryCreateStream(jukebox, player, jukeboxComponent);
if (newStream == null)
{
_playingJukeboxes.Remove(jukeboxComponent);
SetBarsLayerVisible(jukeboxComponent, false);
SetBarsLayerVisible(jukebox, false);
}
else
{
_playingJukeboxes[jukeboxComponent] = newStream;
SetBarsLayerVisible(jukeboxComponent, true);
SetBarsLayerVisible(jukebox, true);
}
}
private JukeboxAudio? TryCreateStream(JukeboxComponent jukeboxComponent, TransformComponent jukeboxXform, TransformComponent playerXform)
private JukeboxAudio? TryCreateStream(EntityUid jukebox, EntityUid player, JukeboxComponent jukeboxComponent)
{
if (jukeboxComponent.PlayingSongData == null) return null!;
var resourcePath = jukeboxComponent.PlayingSongData.SongPath!;
if(!_resource.TryGetResource<AudioResource>((ResPath) resourcePath, out var audio))
return null!;
if (!_resource.TryGetResource<AudioResource>((ResPath) resourcePath, out var audio))
return null;
if (audio.AudioStream.Length.TotalSeconds < jukeboxComponent.PlayingSongData!.PlaybackPosition)
{
return null!;
return null;
}
var playingStream = _clydeAudio.CreateAudioSource(audio.AudioStream);
if (playingStream == null)
return null!;
return null;
playingStream.Volume = _jukeboxVolume;
playingStream.PlaybackPosition = jukeboxComponent.PlayingSongData.PlaybackPosition;
playingStream.Position = jukeboxXform.MapPosition.Position;
playingStream.Position = _transform.GetWorldPosition(jukebox);
var jukeboxAudio = new JukeboxAudio(playingStream!, audio, jukeboxComponent.PlayingSongData);
var jukeboxAudio = new JukeboxAudio(playingStream, audio, jukeboxComponent.PlayingSongData);
SetRolloffAndOcclusion(jukeboxComponent, playerXform, jukeboxXform, jukeboxAudio);
SetRolloffAndOcclusion(jukebox, player, jukeboxComponent, jukeboxAudio);
playingStream.StartPlaying();
return jukeboxAudio;
}
private void SetBarsLayerVisible(JukeboxComponent jukeboxComponent, bool visible)
private void SetBarsLayerVisible(EntityUid jukebox, bool visible)
{
var spriteComponent = Comp<SpriteComponent>(jukeboxComponent.Owner);
var spriteComponent = Comp<SpriteComponent>(jukebox);
spriteComponent.LayerMapTryGet("bars", out var layer);
spriteComponent.LayerSetVisible(layer, visible);
}
private void OnStateChanged(EntityUid uid, JukeboxComponent component, ref ComponentHandleState args)
private sealed class JukeboxAudio(IAudioSource playingStream, AudioResource audioStream, PlayingSongData songData)
{
if (args.Current is JukeboxComponentState state)
{
component.Repeating = state.Playing;
component.Volume = state.Volume;
component.PlayingSongData = state.SongData;
}
}
public PlayingSongData SongData { get; } = songData;
private class JukeboxAudio
{
public PlayingSongData SongData { get; }
public IAudioSource PlayingStream { get; }
public AudioResource AudioStream { get; }
public IAudioSource PlayingStream { get; } = playingStream;
public JukeboxAudio(IAudioSource playingStream, AudioResource audioStream, PlayingSongData songData)
{
PlayingStream = playingStream;
AudioStream = audioStream;
SongData = songData;
}
public AudioResource AudioStream { get; } = audioStream;
}
private void CleanUp()
@@ -307,4 +305,4 @@ public sealed class JukeboxSystem : EntitySystem
_playingJukeboxes.Clear();
}
}
}

View File

@@ -133,7 +133,7 @@ public sealed partial class AdminVerbSystem
Icon = new SpriteSpecifier.Rsi(new ResPath("/Textures/White/Cult/interface.rsi"), "icon"),
Act = () =>
{
_cultRule.MakeCultist(args.Target);
_cultRule.AdminMakeCultist(args.Target);
}
};
args.Verbs.Add(cultist);
@@ -142,12 +142,10 @@ public sealed partial class AdminVerbSystem
{
Text = Loc.GetString("admin-verb-text-make-changeling"),
Category = VerbCategory.Antag,
Icon = new SpriteSpecifier.Texture(new ("/Textures/White/Actions/changeling.rsi/absorb.png")),
Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/White/Actions/changeling.rsi/absorb.png")),
Act = () =>
{
var isHuman = HasComp<HumanoidAppearanceComponent>(args.Target);
_changelingRule.MakeChangeling(args.Target);
_changelingRule.AdminMakeChangeling(args.Target);
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-changeling"),

View File

@@ -481,12 +481,12 @@ namespace Content.Server.Administration.Systems
str = str[..(DescriptionMax - _maxAdditionalChars - unameLength)];
}
var nonAfkAdmins = GetNonAfkAdmins();
_messageQueues[msg.UserId].Enqueue(GenerateAHelpMessage(senderSession.Name, str, !personalChannel, _gameTicker.RoundDuration().ToString("hh\\:mm\\:ss"), _gameTicker.RunLevel, playedSound: playSound, noReceivers: nonAfkAdmins.Count == 0));
_messageQueues[msg.UserId].Enqueue(GenerateAHelpMessage(senderSession.Name, str, !personalChannel, _gameTicker.RoundDuration().ToString(@"hh\:mm\:ss"), _gameTicker.RunLevel, playedSound: playSound, noReceivers: nonAfkAdmins.Count == 0));
}
// WD start
var utkaCkey = _playerManager.GetSessionByUserId(message.UserId).ConnectedClient.UserName;
var utkaSender = _playerManager.GetSessionByUserId(senderSession.UserId).ConnectedClient.UserName;
var utkaCkey = _playerManager.GetSessionById(message.UserId).Channel.UserName;
var utkaSender = _playerManager.GetSessionById(senderSession.UserId).Channel.UserName;
UtkaSendAhelpPm(message.Text, utkaCkey, utkaSender);
// WD end
@@ -624,8 +624,8 @@ namespace Content.Server.Administration.Systems
// Notify player
if (_playerManager.TryGetSessionById(receiver, out var session))
{
if (!admins.Contains(session.ConnectedClient))
RaiseNetworkEvent(msg, session.ConnectedClient);
if (!admins.Contains(session.Channel))
RaiseNetworkEvent(msg, session.Channel);
}
var sendsWebhook = _webhookUrl != string.Empty;
@@ -642,10 +642,10 @@ namespace Content.Server.Administration.Systems
str = str[..(DescriptionMax - _maxAdditionalChars - unameLength)];
}
_messageQueues[msg.UserId].Enqueue(GenerateAHelpMessage(sender, str, true,
_gameTicker.RoundDuration().ToString("hh\\:mm\\:ss"), _gameTicker.RunLevel));
_gameTicker.RoundDuration().ToString(@"hh\:mm\:ss"), _gameTicker.RunLevel, false));
}
var utkaCkey = _playerManager.GetSessionByUserId(receiver).ConnectedClient.UserName;
var utkaCkey = _playerManager.GetSessionById(receiver).Channel.UserName;
UtkaSendAhelpPm(text, utkaCkey, sender);
}
@@ -665,12 +665,12 @@ namespace Content.Server.Administration.Systems
entity = meta.EntityName;
}
var utkaAhelpEvent = new UtkaAhelpPmEvent()
var utkaAhelpEvent = new UtkaAhelpPmEvent
{
Message = message,
Ckey = ckey,
Sender = sender,
Rid = Get<GameTicker>().RoundId,
Rid = _gameTicker.RoundId,
NoAdmins = !admins,
Entity = entity
};

View File

@@ -301,26 +301,21 @@ public sealed class RespiratorSystem : EntitySystem
return false;
}
if (_inventorySystem.TryGetSlotEntity(target, "mask", out var maskUidTarget) &&
EntityManager.TryGetComponent<IngestionBlockerComponent>(maskUidTarget, out var blockerTarget) &&
blockerTarget.Enabled)
{
_popupSystem.PopupEntity(
Loc.GetString("cpr-mask-block-target", ("target", Identity.Entity(target, EntityManager))), target,
user);
return false;
}
if (!_inventorySystem.TryGetSlotEntity(target, "mask", out var maskUidTarget) ||
!EntityManager.TryGetComponent<IngestionBlockerComponent>(maskUidTarget, out var blockerTarget) ||
!blockerTarget.Enabled)
return true;
return true;
_popupSystem.PopupEntity(
Loc.GetString("cpr-mask-block-target", ("target", Identity.Entity(target, EntityManager))), target, user);
return false;
}
private void DoCPR(EntityUid target, RespiratorComponent comp, EntityUid user)
{
var doAfterEventArgs = new DoAfterArgs(EntityManager, user, 1, new CPREndedEvent(), target,
target: target)
var doAfterEventArgs = new DoAfterArgs(EntityManager, user, 1, new CPREndedEvent(), target, target: target)
{
BreakOnTargetMove = true,
BreakOnUserMove = true,
BreakOnMove = true,
BreakOnDamage = true,
NeedHand = true,
BreakOnHandChange = true
@@ -334,12 +329,11 @@ public sealed class RespiratorSystem : EntitySystem
comp.CPRPerformedBy = user;
_popupSystem.PopupEntity(
Loc.GetString("cpr-started", ("target", Identity.Entity(target, EntityManager)),
_popupSystem.PopupEntity(Loc.GetString("cpr-started", ("target", Identity.Entity(target, EntityManager)),
("user", Identity.Entity(user, EntityManager))), target, PopupType.Medium);
comp.CPRPlayingStream =
_audio.PlayPvs(comp.CPRSound, target, audioParams: AudioParams.Default.WithVolume(-3f).WithLoop(true)).Value
.Entity;
_audio.PlayPvs(comp.CPRSound, target, AudioParams.Default.WithVolume(-3f).WithLoop(true)).Value.Entity;
_adminLogger.Add(LogType.Action, LogImpact.High,
$"{ToPrettyString(user):entity} начал произовдить СЛР на {ToPrettyString(target):entity}");
@@ -351,7 +345,7 @@ public sealed class RespiratorSystem : EntitySystem
return;
if (args.Cancelled || !TryComp<MobStateComponent>(args.Target, out var targetState) ||
targetState!.CurrentState != MobState.Critical)
targetState.CurrentState != MobState.Critical)
{
_audio.Stop(component.CPRPlayingStream);
component.CPRPerformedBy = null;
@@ -365,15 +359,16 @@ public sealed class RespiratorSystem : EntitySystem
_damageable.TryChangeDamage(uid, -component.Damage * 2, true, false);
_popupSystem.PopupEntity(
Loc.GetString("cpr-cycle-ended", ("target", Identity.Entity(uid, EntityManager)),
_popupSystem.PopupEntity(Loc.GetString("cpr-cycle-ended", ("target", Identity.Entity(uid, EntityManager)),
("user", Identity.Entity(args.User, EntityManager))), uid);
_adminLogger.Add(LogType.Action, LogImpact.High,
$"{ToPrettyString(args.User):entity} произвёл СЛР на {ToPrettyString(args.Target):entity}");
if (args.Target != null && CanCPR(args.Target.Value, component, args.User))
{
args.Repeat = true;
}
else
{
component.CPRPerformedBy = null;

View File

@@ -14,20 +14,16 @@ using Content.Shared.Chat;
using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
using Content.Shared.Humanoid;
using Content.Shared.Mind;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Systems;
using Content.Shared.Popups;
using Content.Shared.Silicons.Borgs.Components;
using Robust.Server.Containers;
using Robust.Shared.Containers;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
using Robust.Shared.Timing;
@@ -36,31 +32,24 @@ namespace Content.Server.Borer;
public sealed class ServerBorerSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _action = default!;
[Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly QuickDialogSystem _quickDialog = default!;
[Dependency] private readonly ReactiveSystem _reactiveSystem = default!;
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly StunSystem _stuns = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly VomitSystem _vomitSystem = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly SharedBorerSystem _sharedBorerSystem = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly GodmodeSystem _godmodeSystem = default!;
private const string SugarPrototype = "Sugar";
public override void Initialize()
{
@@ -85,15 +74,18 @@ public sealed class ServerBorerSystem : EntitySystem
SubscribeLocalEvent<BorerHostComponent, BorerReproduceEvent>(OnReproduce);
SubscribeLocalEvent<BorerHostComponent, BorerReproduceAfterEvent>(OnReproduceAfter);
SubscribeLocalEvent<InfestedBorerComponent, BorerBrainResistAfterEvent>(OnResistAfterControl);
}
private void OnReproduceAfter(EntityUid uid, BorerHostComponent component, BorerReproduceAfterEvent args)
{
if (args.Cancelled || !TryComp(component.BorerContainer.ContainedEntities[0], out InfestedBorerComponent? borerComp)
|| !WithrawPoints(component.BorerContainer.ContainedEntities[0], borerComp.ReproduceCost)
|| !TryComp(uid, out TransformComponent? targetTransform))
if (args.Cancelled
|| !TryComp(component.BorerContainer.ContainedEntities[0], out InfestedBorerComponent? borerComp)
|| !WithrawPoints(component.BorerContainer.ContainedEntities[0], borerComp.ReproduceCost)
|| !TryComp(uid, out TransformComponent? targetTransform))
{
return;
}
args.Handled = true;
_vomitSystem.Vomit(uid, -30, -30);
_entityManager.SpawnEntity("MobSimpleBorer", targetTransform.Coordinates);
@@ -103,32 +95,31 @@ public sealed class ServerBorerSystem : EntitySystem
{
if (!TryComp(component.BorerContainer.ContainedEntities[0], out InfestedBorerComponent? borerComp))
return;
if (GetPoints(component.BorerContainer.ContainedEntities[0]) < borerComp.ReproduceCost)
{
_popup.PopupEntity(Loc.GetString("borer-popup-lowchem"),
uid,
uid, PopupType.LargeCaution);
_popup.PopupEntity(Loc.GetString("borer-popup-lowchem"), uid, uid, PopupType.LargeCaution);
return;
}
args.Handled = true;
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager,
uid,
TimeSpan.FromSeconds(3),
new BorerReproduceAfterEvent(), uid)
{
Hidden = true
});
_doAfterSystem.TryStartDoAfter(
new DoAfterArgs(EntityManager, uid, TimeSpan.FromSeconds(3), new BorerReproduceAfterEvent(), uid)
{
Hidden = true
});
}
public void ReleaseControl(EntityUid borerUid)
{
if (!TryComp(borerUid, out ActionsComponent? wormActComp) ||
!TryComp(borerUid, out InfestedBorerComponent? borComp) ||
!borComp.Host.HasValue ||
!borComp.ControllingBrain)
if (!TryComp(borerUid, out ActionsComponent? wormActComp)
|| !TryComp(borerUid, out InfestedBorerComponent? borComp)
|| !borComp.Host.HasValue
|| !borComp.ControllingBrain)
{
return;
}
TryComp(borComp.Host.Value, out ActionsComponent? bodyActComp);
var wormHasMind = _mindSystem.TryGetMind(borerUid, out var hostMindId, out var hostMind);
@@ -138,10 +129,10 @@ public sealed class ServerBorerSystem : EntitySystem
if (wormHasMind)
_mindSystem.TransferTo(hostMindId, borComp.Host.Value, mind: hostMind);
if (bodyHasMind)
_mindSystem.TransferTo(mindId, borerUid, mind: mind);
_sharedBorerSystem.AddInfestedAbilities(borerUid, borComp);
_action.RemoveAction(borerUid, borComp.ActionBorerBrainResistEntity, wormActComp);
@@ -164,6 +155,7 @@ public sealed class ServerBorerSystem : EntitySystem
{
if (args.Cancelled)
return;
ReleaseControl(uid);
}
@@ -171,69 +163,69 @@ public sealed class ServerBorerSystem : EntitySystem
{
if (GetPoints(uid) < component.AssumeControlCost)
{
_popup.PopupEntity(Loc.GetString("borer-popup-lowchem"),
uid,
uid, PopupType.LargeCaution);
_popup.PopupEntity(Loc.GetString("borer-popup-lowchem"), uid, uid, PopupType.LargeCaution);
return;
}
if (GetSugarQuantityInHost(uid) > 0)
{
_popup.PopupEntity(Loc.GetString("borer-popup-toomuchsugar"), uid,
uid, PopupType.LargeCaution);
_popup.PopupEntity(Loc.GetString("borer-popup-toomuchsugar"), uid, uid, PopupType.LargeCaution);
}
if (TryComp(component.Host, out MobStateComponent? state) &&
state.CurrentState == MobState.Critical)
if (TryComp(component.Host, out MobStateComponent? state) && state.CurrentState == MobState.Critical)
{
_popup.PopupEntity(Loc.GetString("borer-popup-braintake-critical"), uid,
uid, PopupType.LargeCaution);
_popup.PopupEntity(Loc.GetString("borer-popup-braintake-critical"), uid, uid, PopupType.LargeCaution);
return;
}
args.Handled = true;
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager,
uid,
TimeSpan.FromSeconds(30),
new BorerBrainTakeAfterEvent(), uid)
{
Hidden = true
});
_doAfterSystem.TryStartDoAfter(
new DoAfterArgs(EntityManager, uid, TimeSpan.FromSeconds(30), new BorerBrainTakeAfterEvent(), uid)
{
Hidden = true
});
}
private void OnTakeControlAfter(EntityUid uid, InfestedBorerComponent component, BorerBrainTakeAfterEvent args)
{
if (!TryComp(uid, out ActionsComponent? comp) ||
!TryComp(component.Host, out ActionsComponent? hostComp))
if (args.Cancelled)
{
return;
}
else if (TryComp(component.Host, out MobStateComponent? state) &&
state.CurrentState == MobState.Critical)
if (!TryComp(uid, out ActionsComponent? comp) || !TryComp(component.Host, out ActionsComponent? hostComp))
{
_popup.PopupEntity(Loc.GetString("borer-popup-braintake-critical"), uid,
uid, PopupType.LargeCaution);
return;
}
else if (GetSugarQuantityInHost(uid) > 0)
if (TryComp(component.Host, out MobStateComponent? state) && state.CurrentState == MobState.Critical)
{
_popup.PopupEntity(Loc.GetString("borer-popup-toomuchsugar"), uid,
uid, PopupType.LargeCaution);
}
else if (args.Cancelled || !WithrawPoints(uid, component.AssumeControlCost))
_popup.PopupEntity(Loc.GetString("borer-popup-braintake-critical"), uid, uid, PopupType.LargeCaution);
return;
}
if (GetSugarQuantityInHost(uid) > 0)
{
_popup.PopupEntity(Loc.GetString("borer-popup-toomuchsugar"), uid, uid, PopupType.LargeCaution);
return;
}
if (!WithrawPoints(uid, component.AssumeControlCost))
{
return;
}
var borHasMind = _mindSystem.TryGetMind(uid, out var mindId, out var mind);
var hostHasMind = _mindSystem.TryGetMind(component.Host.Value, out var hostMindId, out var hostMind);
if (!borHasMind && !hostHasMind)
return;
if (borHasMind)
{
_mindSystem.TransferTo(mindId, component.Host, mind: mind);
_popup.PopupEntity(Loc.GetString("borer-popup-braintake-success"), component.Host.Value,
component.Host.Value, PopupType.Large);
}
if (hostHasMind)
@@ -260,12 +252,15 @@ public sealed class ServerBorerSystem : EntitySystem
_action.AddAction(component.Host.Value, ref component.ActionBorerBrainReleaseEntity,
component.ActionBorerBrainRelease, component: hostComp);
_action.AddAction(component.Host.Value, ref component.ActionBorerReproduceEntity,
component.ActionBorerReproduce, component: hostComp);
if(component.ActionBorerReproduceEntity.HasValue)
if (component.ActionBorerReproduceEntity.HasValue)
{
_metaData.SetEntityName(component.ActionBorerReproduceEntity.Value,
$"{Loc.GetString("borer-abilities-reproduce-name")} ([color=red]{component.ReproduceCost}c[/color])");
}
component.ControllingBrain = true;
Dirty(uid, component);
@@ -287,9 +282,10 @@ public sealed class ServerBorerSystem : EntitySystem
return;
}
if (TryComp(args.Target, out MobStateComponent? state) &&
state.CurrentState == MobState.Dead)
if (TryComp(args.Target, out MobStateComponent? state) && state.CurrentState == MobState.Dead)
{
return;
}
if (HasComp<BorerHostComponent>(args.Target))
{
@@ -305,7 +301,7 @@ public sealed class ServerBorerSystem : EntitySystem
return;
}
StartInfest(uid, args.Target, component);
StartInfest(uid, args.Target);
args.Handled = true;
}
@@ -316,9 +312,11 @@ public sealed class ServerBorerSystem : EntitySystem
if (!HasComp<HumanoidAppearanceComponent>(args.Target))
return;
if (TryComp(args.Target, out MobStateComponent? state) &&
state.CurrentState == MobState.Dead)
if (TryComp(args.Target, out MobStateComponent? state) && state.CurrentState == MobState.Dead)
{
return;
}
if (HasComp<BorerHostComponent>(args.Target))
{
@@ -348,29 +346,26 @@ public sealed class ServerBorerSystem : EntitySystem
RemComp<BorerComponent>(uid);
}
private void StartInfest(EntityUid user, EntityUid target, BorerComponent comp)
private void StartInfest(EntityUid user, EntityUid target)
{
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager,
user,
TimeSpan.FromSeconds(5),
new BorerInfestDoAfterEvent(), user, target)
{
BreakOnTargetMove = true,
BreakOnUserMove = true,
Hidden = true
});
_doAfterSystem.TryStartDoAfter(
new DoAfterArgs(EntityManager, user, TimeSpan.FromSeconds(5), new BorerInfestDoAfterEvent(), user, target)
{
BreakOnMove = true,
Hidden = true
});
}
private void OnBorerScan(EntityUid uid, InfestedBorerComponent component, BorerScanInstantActionEvent args)
{
if (!component.Host.HasValue)
return;
Dictionary<string, FixedPoint2> solution = new();
if (EntityManager.TryGetComponent(component.Host.Value,
out BloodstreamComponent? bloodContainer))
if (EntityManager.TryGetComponent(component.Host.Value, out BloodstreamComponent? bloodContainer))
{
if(_solutionContainerSystem.TryGetSolution(component.Host.Value, bloodContainer.ChemicalSolutionName,
out var sol))
if (_solutionContainerSystem.TryGetSolution(component.Host.Value, bloodContainer.ChemicalSolutionName,
out var sol))
{
foreach (var reagent in sol.Value.Comp.Solution)
{
@@ -414,7 +409,7 @@ public sealed class ServerBorerSystem : EntitySystem
private void OnTelepathicSpeech(EntityUid uid, InfestedBorerComponent component, BorerBrainSpeechActionEvent args)
{
if (!EntityManager.TryGetComponent(uid, out ActorComponent? actor))
if (!TryComp(uid, out ActorComponent? actor))
return;
_quickDialog.OpenDialog(actor.PlayerSession, Loc.GetString("borer-ui-converse-title"),
@@ -422,40 +417,40 @@ public sealed class ServerBorerSystem : EntitySystem
{
_popup.PopupEntity(message, uid, uid, PopupType.Medium);
if (EntityManager.TryGetComponent(component.Host, out ActorComponent? hostActor))
if (EntityManager.TryGetComponent(component.Host, out ActorComponent? _))
{
_popup.PopupEntity(message, component.Host.Value, component.Host.Value,
PopupType.Medium);
}
});
args.Handled = true;
}
private void OnInjectChemicals(BorerInjectActionEvent injectEvent, EntitySessionEventArgs eventArgs)
{
var borerEn = eventArgs.SenderSession.AttachedEntity;
if (EntityManager.TryGetComponent(borerEn,
out InfestedBorerComponent? infestedComponent) &&
infestedComponent.Host.HasValue)
if (!TryComp(borerEn, out InfestedBorerComponent? infestedComponent) || !infestedComponent.Host.HasValue)
{
if (!WithrawPoints(borerEn.Value, injectEvent.Cost))
return;
var solution = new Solution();
solution.AddReagent(injectEvent.ProtoId, 10);
_bloodstreamSystem.TryAddToChemicals(infestedComponent.Host.Value, solution);
_reactiveSystem.DoEntityReaction(infestedComponent.Host.Value, solution, ReactionMethod.Injection);
_popup.PopupEntity(Loc.GetString("borer-popup-injected", ("reagent", Loc.GetString("reagent-name-"+
injectEvent.ProtoId.ToLower().Replace("spacedrugs", "space-drugs")))),
borerEn.Value, borerEn.Value, PopupType.Medium);
return;
}
if (!WithrawPoints(borerEn.Value, injectEvent.Cost))
return;
var solution = new Solution();
solution.AddReagent(injectEvent.ProtoId, 10);
_bloodstreamSystem.TryAddToChemicals(infestedComponent.Host.Value, solution);
_reactiveSystem.DoEntityReaction(infestedComponent.Host.Value, solution, ReactionMethod.Injection);
_popup.PopupEntity(Loc.GetString("borer-popup-injected", ("reagent", Loc.GetString("reagent-name-" +
injectEvent.ProtoId.ToLower().Replace("spacedrugs", "space-drugs")))),
borerEn.Value, borerEn.Value, PopupType.Medium);
}
public bool AddPoints(EntityUid borerUid, int value)
{
if (!EntityManager.TryGetComponent(borerUid,
out InfestedBorerComponent? infestedComponent))
if (!TryComp(borerUid, out InfestedBorerComponent? infestedComponent))
return false;
infestedComponent.Points += value;
@@ -466,21 +461,16 @@ public sealed class ServerBorerSystem : EntitySystem
public int GetPoints(EntityUid borerUid)
{
if (!EntityManager.TryGetComponent(borerUid,
out InfestedBorerComponent? infestedComponent))
return 0;
return infestedComponent.Points;
return TryComp(borerUid, out InfestedBorerComponent? infestedComponent)
? infestedComponent.Points
: 0;
}
public bool WithrawPoints(EntityUid borerUid, int value)
{
if (!EntityManager.TryGetComponent(borerUid,
out InfestedBorerComponent? infestedComponent) || infestedComponent.Points < value)
if (!TryComp(borerUid, out InfestedBorerComponent? infestedComponent) || infestedComponent.Points < value)
{
_popup.PopupEntity(Loc.GetString("borer-popup-lowchem"),
borerUid,
borerUid, PopupType.LargeCaution);
_popup.PopupEntity(Loc.GetString("borer-popup-lowchem"), borerUid, borerUid, PopupType.LargeCaution);
return false;
}
@@ -499,7 +489,10 @@ public sealed class ServerBorerSystem : EntitySystem
{
if (!TryComp(uid, out InfestedBorerComponent? component) ||
!TryComp(component.Host, out BorerHostComponent? hostComponent))
{
return;
}
ReleaseControl(uid);
_vomitSystem.Vomit(component.Host.Value, -20, -20);
@@ -513,16 +506,17 @@ public sealed class ServerBorerSystem : EntitySystem
_godmodeSystem.DisableGodmode(uid);
RemComp<InfestedBorerComponent>(uid);
_action.SetCooldown(borerComponent.ActionStunEntity, _timing.CurTime, _timing.CurTime+TimeSpan.FromSeconds(20));
_action.SetCooldown(borerComponent.ActionInfestEntity, _timing.CurTime, _timing.CurTime+TimeSpan.FromSeconds(20));
_action.SetCooldown(borerComponent.ActionStunEntity, _timing.CurTime,
_timing.CurTime + TimeSpan.FromSeconds(20));
_action.SetCooldown(borerComponent.ActionInfestEntity, _timing.CurTime,
_timing.CurTime + TimeSpan.FromSeconds(20));
}
public int GetSugarQuantityInHost(EntityUid borerUid)
{
var sugarQuantity = 0;
if (EntityManager.TryGetComponent(borerUid,
out InfestedBorerComponent? component) &&
component.Host.HasValue)
if (TryComp(borerUid, out InfestedBorerComponent? component) && component.Host.HasValue)
{
sugarQuantity = GetSugarQuantityInEntity(component.Host.Value);
}
@@ -532,21 +526,20 @@ public sealed class ServerBorerSystem : EntitySystem
public int GetSugarQuantityInEntity(EntityUid uid)
{
if (EntityManager.TryGetComponent(uid,
out BloodstreamComponent? bloodContainer))
if (!TryComp(uid, out BloodstreamComponent? bloodContainer))
return 0;
if (!_solutionContainerSystem.TryGetSolution(uid, bloodContainer.ChemicalSolutionName, out var sol))
return 0;
foreach (var reagent in sol.Value.Comp.Solution)
{
if(_solutionContainerSystem.TryGetSolution(uid, bloodContainer.ChemicalSolutionName,
out var sol))
if (reagent.Reagent.ToString() == SugarPrototype)
{
foreach (var reagent in sol.Value.Comp.Solution)
{
if (reagent.Reagent.ToString() == "Sugar")
{
return reagent.Quantity.Int();
}
}
return reagent.Quantity.Int();
}
}
return 0;
}
}
}

View File

@@ -1,117 +1,121 @@
using Content.Server.Botany.Components;
using Content.Server.PowerCell;
using Content.Shared.FixedPoint;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Botany;
using Content.Shared.Mobs.Components; //probably useless
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
using Content.Shared.Interaction;
using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Player;
namespace Content.Server.Botany
namespace Content.Server.Botany.Systems;
public sealed class SeedAnalyzerSystem : EntitySystem
{
public sealed class SeedAnalyzerSystem : EntitySystem
[Dependency] private readonly PowerCellSystem _cell = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
public override void Initialize()
{
[Dependency] private readonly PowerCellSystem _cell = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SeedAnalyzerComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<SeedAnalyzerComponent, SeedAnalyzerDoAfterEvent>(OnDoAfter);
}
private void OnAfterInteract(EntityUid uid, SeedAnalyzerComponent seedAnalyzer, AfterInteractEvent args)
{
if (args.Target == null || !args.CanReach || !HasComp<PlantHolderComponent>(args.Target) || !_cell.HasActivatableCharge(uid, user: args.User))
return;
_audio.PlayPvs(seedAnalyzer.ScanningBeginSound, uid); // maybe healthAnalyzer.ScanningBeginSound
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, seedAnalyzer.ScanDelay, new SeedAnalyzerDoAfterEvent(), uid, target: args.Target, used: uid) //maybe healthAnalyzer.ScanDelay
{
BreakOnTargetMove = true,
BreakOnUserMove = true,
NeedHand = true
});
}
private void OnDoAfter(EntityUid uid, SeedAnalyzerComponent component, DoAfterEvent args)
{
if (args.Handled || args.Cancelled || args.Args.Target == null || !_cell.TryUseActivatableCharge(uid, user: args.User))
return;
_audio.PlayPvs(component.ScanningEndSound, args.Args.User);
UpdateScannedSeed(uid, args.Args.User, args.Args.Target.Value, component);
args.Handled = true;
}
private void OpenUserInterface(EntityUid user, EntityUid seedAnalyzer)
{
if (!TryComp<ActorComponent>(user, out var actor) || !_uiSystem.TryGetUi(seedAnalyzer, SeedAnalyzerUiKey.Key, out var ui))
return;
_uiSystem.OpenUi(ui, actor.PlayerSession);
}
public void UpdateScannedSeed(EntityUid uid, EntityUid user, EntityUid? target, SeedAnalyzerComponent? seedAnalyzer)
{
if (!Resolve(uid, ref seedAnalyzer))
return;
if (target == null || !_uiSystem.TryGetUi(uid, SeedAnalyzerUiKey.Key, out var ui))
return;
if (!TryComp<PlantHolderComponent>(target, out var plant))
return;
if (plant!.Seed == null)
{
return;
}
int zero = 0;
string nonameseed = "None";
Dictionary<string, FixedPoint2> emptydic = new Dictionary<string, FixedPoint2>();
var zero2 = FixedPoint2.New(zero);
emptydic?.Add("No chemicals", zero2!);
Dictionary<string, FixedPoint2> passchems = new Dictionary<string, FixedPoint2>();
if (plant?.Seed?.Chemicals != null)
{
foreach (var (chem, quantity) in plant.Seed.Chemicals)
{
var amount = FixedPoint2.New(quantity.Min);
amount += FixedPoint2.New(plant.Seed.Potency / quantity.PotencyDivisor);
amount = FixedPoint2.New((int) MathHelper.Clamp(amount.Float(), quantity.Min, quantity.Max));
passchems?.Add(chem, amount);
}
}
OpenUserInterface(user, uid);
_uiSystem.SendUiMessage(ui, new SeedAnalyzerScannedUserMessage(GetNetEntity(target),
plant!.Seed?.Yield,
plant != null ? plant.Seed?.Production : float.NaN,
plant != null ? plant.Seed?.Lifespan : float.NaN,
plant != null ? plant.Seed?.Maturation : float.NaN,
plant != null ? plant.Seed?.Endurance : float.NaN,
plant != null ? plant.Seed?.Potency : float.NaN,
plant != null ? plant.Seed?.Viable : false,
plant != null ? plant.Seed?.TurnIntoKudzu : false,
plant != null ? plant.Seed?.Seedless : false,
plant != null ? plant.Seed?.DisplayName : nonameseed,
passchems != null ? passchems : emptydic,
plant != null ? plant.Seed?.Ligneous : false,
plant != null ? plant.Seed?.CanScream : false,
plant != null ? plant.Seed?.Slip : false,
plant != null ? plant.Seed?.Bioluminescent : false,
plant != null ? plant.Seed?.Sentient : false));
}
base.Initialize();
SubscribeLocalEvent<SeedAnalyzerComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<SeedAnalyzerComponent, SeedAnalyzerDoAfterEvent>(OnDoAfter);
}
}
private void OnAfterInteract(EntityUid uid, SeedAnalyzerComponent seedAnalyzer, AfterInteractEvent args)
{
if (args.Target == null || !args.CanReach || !HasComp<PlantHolderComponent>(args.Target) ||
!_cell.HasActivatableCharge(uid, user: args.User))
{
return;
}
_audio.PlayPvs(seedAnalyzer.ScanningBeginSound, uid);
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, seedAnalyzer.ScanDelay,
new SeedAnalyzerDoAfterEvent(), uid, target: args.Target, used: uid)
{
BreakOnMove = true,
NeedHand = true
});
}
private void OnDoAfter(EntityUid uid, SeedAnalyzerComponent component, DoAfterEvent args)
{
if (args.Handled || args.Cancelled || args.Args.Target == null ||
!_cell.TryUseActivatableCharge(uid, user: args.User))
return;
_audio.PlayPvs(component.ScanningEndSound, args.Args.User);
UpdateScannedSeed(uid, args.Args.User, args.Args.Target.Value, component);
args.Handled = true;
}
private void OpenUserInterface(EntityUid user, EntityUid seedAnalyzer)
{
if (!TryComp<ActorComponent>(user, out var actor) ||
!_uiSystem.TryGetUi(seedAnalyzer, SeedAnalyzerUiKey.Key, out var ui))
return;
_uiSystem.OpenUi(ui, actor.PlayerSession);
}
public void UpdateScannedSeed(
EntityUid uid,
EntityUid user,
EntityUid? target,
SeedAnalyzerComponent? seedAnalyzer = null)
{
if (!Resolve(uid, ref seedAnalyzer))
return;
if (target == null || !_uiSystem.TryGetUi(uid, SeedAnalyzerUiKey.Key, out var ui))
return;
if (!TryComp<PlantHolderComponent>(target, out var plant))
return;
if (plant.Seed == null)
{
return;
}
var zero2 = FixedPoint2.Zero;
var emptydic = new Dictionary<string, FixedPoint2> { { "No chemicals", zero2 } };
var passchems = new Dictionary<string, FixedPoint2>();
if (plant.Seed?.Chemicals != null)
{
foreach (var (chem, quantity) in plant.Seed.Chemicals)
{
var amount = FixedPoint2.New(quantity.Min);
amount += FixedPoint2.New(plant.Seed.Potency / quantity.PotencyDivisor);
amount = FixedPoint2.New((int) MathHelper.Clamp(amount.Float(), quantity.Min, quantity.Max));
passchems?.Add(chem, amount);
}
}
OpenUserInterface(user, uid);
_uiSystem.SendUiMessage(ui, new SeedAnalyzerScannedUserMessage(GetNetEntity(target),
plant.Seed?.Yield,
plant.Seed?.Production,
plant.Seed?.Lifespan,
plant.Seed?.Maturation,
plant.Seed?.Endurance,
plant.Seed?.Potency,
plant.Seed?.Viable,
plant.Seed?.TurnIntoKudzu,
plant.Seed?.Seedless,
plant.Seed?.DisplayName,
passchems ?? emptydic,
plant.Seed?.Ligneous,
plant.Seed?.CanScream,
plant.Seed?.Slip,
plant.Seed?.Bioluminescent,
plant.Seed?.Sentient));
}
}

View File

@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server.Antag;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules;
@@ -160,6 +161,21 @@ public sealed class ChangelingRuleSystem : GameRuleSystem<ChangelingRuleComponen
}
}
public void AdminMakeChangeling(EntityUid entity)
{
var changelingRule = EntityQuery<ChangelingRuleComponent>().FirstOrDefault();
if (changelingRule == null)
{
GameTicker.StartGameRule("Changeling", out var ruleEntity);
changelingRule = Comp<ChangelingRuleComponent>(ruleEntity);
}
if (HasComp<ChangelingRuleComponent>(entity))
return;
MakeChangeling(entity, changelingRule);
}
public bool MakeChangeling(EntityUid changeling, ChangelingRuleComponent rule, bool giveObjectives = true)
{
if (!_mindSystem.TryGetMind(changeling, out var mindId, out var mind))

View File

@@ -69,9 +69,8 @@ namespace Content.Server.Chemistry.EntitySystems
_doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, actualDelay, new PatchDoAfterEvent(), patch.Owner, target: target, used: patch.Owner)
{
BreakOnUserMove = true,
BreakOnMove = true,
BreakOnDamage = true,
BreakOnTargetMove = true
});
}

View File

@@ -51,18 +51,17 @@ public sealed partial class EnergyDomeSystem : EntitySystem
SubscribeLocalEvent<EnergyDomeGeneratorComponent, GetVerbsEvent<ActivationVerb>>(AddToggleDomeVerb);
SubscribeLocalEvent<EnergyDomeGeneratorComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<EnergyDomeGeneratorComponent, ComponentRemove>(OnComponentRemove);
//Dome events
SubscribeLocalEvent<EnergyDomeComponent, DamageChangedEvent>(OnDomeDamaged);
}
private void OnInit(Entity<EnergyDomeGeneratorComponent> generator, ref MapInitEvent args)
{
if (generator.Comp.CanDeviceNetworkUse)
_signalSystem.EnsureSinkPorts(generator, generator.Comp.TogglePort, generator.Comp.OnPort, generator.Comp.OffPort);
_signalSystem.EnsureSinkPorts(generator, generator.Comp.TogglePort, generator.Comp.OnPort,
generator.Comp.OffPort);
}
//different ways of use
@@ -76,10 +75,12 @@ public sealed partial class EnergyDomeSystem : EntitySystem
{
AttemptToggle(generator, true);
}
if (args.Port == generator.Comp.OffPort)
{
AttemptToggle(generator, false);
}
if (args.Port == generator.Comp.TogglePort)
{
AttemptToggle(generator, !generator.Comp.Enabled);
@@ -102,17 +103,18 @@ public sealed partial class EnergyDomeSystem : EntitySystem
{
args.PushMarkup(Loc.GetString(
(generator.Comp.Enabled)
? "energy-dome-on-examine-is-on-message"
: "energy-dome-on-examine-is-off-message"
));
? "energy-dome-on-examine-is-on-message"
: "energy-dome-on-examine-is-off-message"
));
}
private void AddToggleDomeVerb(Entity<EnergyDomeGeneratorComponent> generator, ref GetVerbsEvent<ActivationVerb> args)
private void AddToggleDomeVerb(
Entity<EnergyDomeGeneratorComponent> generator,
ref GetVerbsEvent<ActivationVerb> args)
{
if (!args.CanAccess || !args.CanInteract || !generator.Comp.CanInteractUse)
return;
var @event = args;
ActivationVerb verb = new()
{
Text = Loc.GetString("energy-dome-verb-toggle"),
@@ -121,6 +123,7 @@ public sealed partial class EnergyDomeSystem : EntitySystem
args.Verbs.Add(verb);
}
private void OnGetActions(Entity<EnergyDomeGeneratorComponent> generator, ref GetItemActionsEvent args)
{
if (generator.Comp.CanInteractUse)
@@ -155,6 +158,7 @@ public sealed partial class EnergyDomeSystem : EntitySystem
if (args.Charge == 0)
TurnOff(generator, true);
}
private void OnDomeDamaged(Entity<EnergyDomeComponent> dome, ref DamageChangedEvent args)
{
if (dome.Comp.Generator == null)
@@ -178,18 +182,19 @@ public sealed partial class EnergyDomeSystem : EntitySystem
_powerCell.TryGetBatteryFromSlot(generatorUid, out var cell);
if (cell != null)
{
_battery.UseCharge(cell.Owner, energyLeak);
_battery.UseCharge(generatorUid, energyLeak);
if (cell.Charge == 0)
if (cell.CurrentCharge == 0)
TurnOff((generatorUid, generatorComp), true);
}
}
//it seems to me it would not work well to hang both a powercell and an internal battery with wire charging on the object....
if (TryComp<BatteryComponent>(generatorUid, out var battery)) {
if (TryComp<BatteryComponent>(generatorUid, out var battery))
{
_battery.UseCharge(generatorUid, energyLeak);
if (battery.Charge == 0)
if (battery.CurrentCharge == 0)
TurnOff((generatorUid, generatorComp), true);
}
}
@@ -213,44 +218,37 @@ public sealed partial class EnergyDomeSystem : EntitySystem
public bool AttemptToggle(Entity<EnergyDomeGeneratorComponent> generator, bool status)
{
if (TryComp<UseDelayComponent>(generator, out var useDelay) && _useDelay.IsDelayed(new Entity<UseDelayComponent>(generator, useDelay)))
if (TryComp<UseDelayComponent>(generator, out var useDelay) &&
_useDelay.IsDelayed(new Entity<UseDelayComponent>(generator, useDelay)))
{
_audio.PlayPvs(generator.Comp.TurnOffSound, generator);
_popup.PopupEntity(
Loc.GetString("energy-dome-recharging"),
generator);
_popup.PopupEntity(Loc.GetString("energy-dome-recharging"), generator);
return false;
}
if (TryComp<PowerCellSlotComponent>(generator, out var powerCellSlot))
if (TryComp<PowerCellSlotComponent>(generator, out _))
{
if (!_powerCell.TryGetBatteryFromSlot(generator, out var cell) && !TryComp(generator, out cell))
if (!_powerCell.TryGetBatteryFromSlot(generator, out _) && !TryComp(generator, out BatteryComponent? _))
{
_audio.PlayPvs(generator.Comp.TurnOffSound, generator);
_popup.PopupEntity(
Loc.GetString("energy-dome-no-cell"),
generator);
_popup.PopupEntity(Loc.GetString("energy-dome-no-cell"), generator);
return false;
}
if (!_powerCell.HasDrawCharge(generator))
{
_audio.PlayPvs(generator.Comp.TurnOffSound, generator);
_popup.PopupEntity(
Loc.GetString("energy-dome-no-power"),
generator);
_popup.PopupEntity(Loc.GetString("energy-dome-no-power"), generator);
return false;
}
}
if (TryComp<BatteryComponent>(generator, out var battery))
{
if (battery.Charge == 0)
if (battery.CurrentCharge == 0)
{
_audio.PlayPvs(generator.Comp.TurnOffSound, generator);
_popup.PopupEntity(
Loc.GetString("energy-dome-no-power"),
generator);
_popup.PopupEntity(Loc.GetString("energy-dome-no-power"), generator);
return false;
}
}
@@ -284,7 +282,8 @@ public sealed partial class EnergyDomeSystem : EntitySystem
}
_powerCell.SetPowerCellDrawEnabled(generator, true);
if (TryComp<BatterySelfRechargerComponent>(generator, out var recharger)) {
if (TryComp<BatterySelfRechargerComponent>(generator, out var recharger))
{
recharger.AutoRecharge = true;
}
@@ -326,4 +325,4 @@ public sealed partial class EnergyDomeSystem : EntitySystem
? container.Owner
: entity;
}
}
}

View File

@@ -92,7 +92,7 @@ namespace Content.Server.Power.EntitySystems
}
if (comp.AutoRechargeRate < 0) //self discharging
{
if (batt.Charge == 0) continue;
if (batt.CurrentCharge == 0) continue;
UseCharge(uid, -comp.AutoRechargeRate * frameTime, batt);
}
}

View File

@@ -1,3 +1,4 @@
using Content.Server.SurveillanceCamera.Systems;
using Content.Shared.DeviceNetwork;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;

View File

@@ -1,4 +1,5 @@
using Content.Server.Popups;
using Content.Server.Power.EntitySystems;
using Content.Server.PowerCell;
using Content.Shared.Clothing.EntitySystems;
using Content.Shared.Examine;
@@ -7,7 +8,7 @@ using Content.Shared.Item;
using Content.Shared.PowerCell.Components;
using Content.Shared.Toggleable;
namespace Content.Server.SurveillanceCamera;
namespace Content.Server.SurveillanceCamera.Systems;
/// <summary>
/// This handles the bodycamera all itself. Activation, examine,init, powercell stuff.
@@ -20,6 +21,7 @@ public sealed class SurveillanceBodyCameraSystem : EntitySystem
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedItemSystem _item = default!;
[Dependency] private readonly ClothingSystem _clothing = default!;
[Dependency] private readonly BatterySystem _battery = default!;
public override void Initialize()
{
@@ -55,7 +57,7 @@ public sealed class SurveillanceBodyCameraSystem : EntitySystem
if (!surComp.Active)
continue;
if (!battery.TryUseCharge(cam.Wattage * frameTime))
if (!_battery.TryUseCharge(uid, cam.Wattage * frameTime))
{
_surveillanceCameras.SetActive(uid, false, surComp);
AppearanceChange(uid, surComp.Active);

View File

@@ -1,6 +1,5 @@
using System.Linq;
using System.Numerics;
using Content.Server.Administration.Logs;
using Content.Server.Cargo.Systems;
using Content.Server.Interaction;
using Content.Server.Power.EntitySystems;
@@ -161,7 +160,7 @@ public sealed partial class GunSystem : SharedGunSystem
{
if (dmg.Any())
{
_color.RaiseEffect(Color.Red, new List<EntityUid>() { hitEntity }, Filter.Pvs(hitEntity, entityManager: EntityManager));
_color.RaiseEffect(Color.Red, [hitEntity], Filter.Pvs(hitEntity, entityManager: EntityManager));
}
// TODO get fallback position for playing hit sound.
@@ -223,7 +222,7 @@ public sealed partial class GunSystem : SharedGunSystem
Audio.PlayPvs(clumsy.ClumsySound, gunUid);
PopupSystem.PopupEntity(Loc.GetString("gun-clumsy"), user.Value);
_adminLogger.Add(LogType.EntityDelete, LogImpact.Medium, $"{Loc.GetString("clumsy-gun-delete-log", ("prettyUser", ToPrettyString(user.Value)), ("prettyGun", ToPrettyString(gunUid)))}");
Logs.Add(LogType.EntityDelete, LogImpact.Medium, $"{Loc.GetString("clumsy-gun-delete-log", ("prettyUser", ToPrettyString(user.Value)), ("prettyGun", ToPrettyString(gunUid)))}");
Del(gunUid);
userImpulse = false;
return;
@@ -240,7 +239,7 @@ public sealed partial class GunSystem : SharedGunSystem
var angle = GetRecoilAngle(Timing.CurTime, gun, mapDirection.ToAngle());
// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
var fromEnt = MapManager.TryFindGridAt(fromMap, out var gridUid, out _)
var fromEnt = MapManager.TryFindGridAt(fromMap, out var gridUid, out var grid)
? fromCoordinates.WithEntityId(gridUid, EntityManager)
: new EntityCoordinates(MapManager.GetMapEntityId(fromMap.MapId), fromMap.Position);

View File

@@ -19,7 +19,7 @@ public sealed class ChairLeakAspect : AspectSystem<ChairLeakAspectComponent>
while (query.MoveNext(out var ent, out _))
{
if (TryComp(ent, out StrapComponent? strap))
_buckle.StrapRemoveAll(strap);
_buckle.StrapRemoveAll(ent, strap);
EntityManager.DeleteEntity(ent);
}

View File

@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server._Miracle.GulagSystem;
using Content.Server.Actions;
using Content.Server.Antag;
@@ -321,6 +322,21 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
return potentialTargets;
}
public void AdminMakeCultist(EntityUid entity)
{
var cultistRule = EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultistRule == null)
{
GameTicker.StartGameRule("Cult", out var ruleEntity);
cultistRule = Comp<CultRuleComponent>(ruleEntity);
}
if (HasComp<CultistComponent>(entity))
return;
MakeCultist(entity, cultistRule);
}
public bool MakeCultist(EntityUid cultist, CultRuleComponent rule)
{
if (!_mindSystem.TryGetMind(cultist, out var mindId, out var mind))

View File

@@ -94,7 +94,8 @@ public partial class CultSystem
private void OnTeleport(EntityUid uid, CultistComponent component, CultTeleportTargetActionEvent args)
{
if (!TryComp<BloodstreamComponent>(args.Performer, out var bloodstream) || !TryComp<ActorComponent>(uid, out var actor))
if (!TryComp<BloodstreamComponent>(args.Performer, out var bloodstream) ||
!TryComp<ActorComponent>(uid, out var actor))
return;
if (!TryComp<CultistComponent>(args.Target, out _) &&
@@ -246,8 +247,7 @@ public partial class CultSystem
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.Performer, TimeSpan.FromSeconds(2),
new ShacklesEvent(), args.Performer, args.Target)
{
BreakOnTargetMove = true,
BreakOnUserMove = true,
BreakOnMove = true,
BreakOnDamage = true
});
@@ -304,4 +304,4 @@ public partial class CultSystem
_handsSystem.TryPickupAnyHand(args.Performer, dagger);
args.Handled = true;
}
}
}

View File

@@ -1,12 +1,12 @@
using System.Linq;
using System.Numerics;
using Content.Server._White.Cult.GameRule;
using Content.Server._White.Cult.Runes.Comps;
using Content.Shared.Alert;
using Content.Shared.Maps;
using Content.Shared._White.Cult;
using Content.Shared._White.Cult.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
namespace Content.Server._White.Cult.Runes.Systems;
@@ -16,6 +16,7 @@ public partial class CultSystem
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly ITileDefinitionManager _tileDefinition = default!;
[Dependency] private readonly MapSystem _map = default!;
public void InitializeBuffSystem()
{
@@ -32,12 +33,10 @@ public partial class CultSystem
private void AnyCultistNearTile()
{
var cultists = EntityQuery<CultistComponent>();
var cultistsQuery = EntityQueryEnumerator<CultistComponent>();
foreach (var cultist in cultists)
while (cultistsQuery.MoveNext(out var uid, out _))
{
var uid = cultist.Owner;
if (HasComp<CultBuffComponent>(uid))
continue;
@@ -56,16 +55,15 @@ public partial class CultSystem
private void UpdateBuffTimers(float frameTime)
{
var buffs = EntityQuery<CultBuffComponent>();
var buffsQuery = EntityQueryEnumerator<CultBuffComponent>();
foreach (var buff in buffs)
while (buffsQuery.MoveNext(out var uid, out var buff))
{
var uid = buff.Owner;
var remainingTime = buff.BuffTime;
remainingTime -= TimeSpan.FromSeconds(frameTime);
if (TryComp<CultistComponent>(uid, out var cultist))
if (HasComp<CultistComponent>(uid))
{
if (remainingTime < CultBuffComponent.CultTileBuffTime && AnyCultTilesNearby(uid))
remainingTime = CultBuffComponent.CultTileBuffTime;
@@ -75,21 +73,35 @@ public partial class CultSystem
}
}
private bool AnyCultTilesNearby(EntityUid uid)
{
var localpos = Transform(uid).Coordinates.Position;
if (!TryComp<CultistComponent>(uid, out var cultist))
if (!TryComp<CultistComponent>(uid, out _))
return false;
var radius = CultBuffComponent.NearbyTilesBuffRadius;
if (!_mapManager.TryGetGrid(Transform(uid).GridUid, out var grid))
var gridUid = Transform(uid).GridUid;
if (!gridUid.HasValue)
{
return false;
}
if (!TryComp(gridUid, out MapGridComponent? grid))
return false;
var tilesRefs = grid.GetLocalTilesIntersecting(new Box2(localpos + new Vector2(-radius, -radius), localpos + new Vector2(radius, radius)));
var cultTileDef = (ContentTileDefinition) _tileDefinition[$"{CultRuleComponent.CultFloor}"];
var tilesRefs = _map.GetLocalTilesIntersecting(gridUid.Value, grid, new Box2(
localpos + new Vector2(-radius, -radius),
localpos + new Vector2(radius, radius)));
var cultRule = EntityManager.EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultRule is null)
{
return false;
}
var cultTileDef = (ContentTileDefinition) _tileDefinition[$"{cultRule.CultFloor}"];
var cultTile = new Tile(cultTileDef.TileId);
return tilesRefs.Any(tileRef => tileRef.Tile.TypeId == cultTile.TypeId);
@@ -97,11 +109,10 @@ public partial class CultSystem
private void RemoveExpiredBuffs()
{
var buffs = EntityQuery<CultBuffComponent>();
var buffsQuery = EntityQueryEnumerator<CultBuffComponent>();
foreach (var buff in buffs)
while (buffsQuery.MoveNext(out var uid, out var buff))
{
var uid = buff.Owner;
var remainingTime = buff.BuffTime;
if (remainingTime <= TimeSpan.Zero)
@@ -111,4 +122,4 @@ public partial class CultSystem
}
}
}
}
}

View File

@@ -112,10 +112,8 @@ public sealed partial class CultSystem : EntitySystem
InitializeConstructs();
InitializeBarrierSystem();
InitializeConstructsAbilities();
InitializeCultists();
InitializeActions();
InitializeVerb();
}
private float _timeToDraw;
@@ -325,9 +323,15 @@ public sealed partial class CultSystem : EntitySystem
return;
}
var cultRule = EntityManager.EntityQuery<CultRuleComponent>().FirstOrDefault();
if (cultRule is null)
{
return;
}
var solutions = _solutionContainerSystem.EnumerateSolutions((args.OtherEntity, solution));
if (solutions.Any(x => x.Solution.Comp.Solution.ContainsPrototype(CultRuleComponent.HolyWaterReagent)))
if (solutions.Any(x => x.Solution.Comp.Solution.ContainsPrototype(cultRule.HolyWaterReagent)))
{
Del(uid);
}
@@ -522,10 +526,7 @@ public sealed partial class CultSystem : EntitySystem
return false;
}
if (!_entityManager.TryGetComponent<ActorComponent>(target, out var actorComponent))
return false;
_ruleSystem.MakeCultist(actorComponent.PlayerSession);
_ruleSystem.AdminMakeCultist(target);
_stunSystem.TryStun(target, TimeSpan.FromSeconds(2f), false);
HealCultist(target);

View File

@@ -67,7 +67,7 @@ public sealed partial class CultSystem
new DoAfterArgs(_entityManager, ent, creationTime, new SpellCreatedEvent {Spell = action}, ent)
{
BreakOnDamage = true,
BreakOnUserMove = true
BreakOnMove = true
});
}

View File

@@ -4,39 +4,28 @@ using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Verbs;
using Content.Shared._White.Jukebox;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Server.GameStates;
using Robust.Shared.Containers;
using Robust.Shared.ContentPack;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server._White.Jukebox;
public sealed class JukeboxSystem : EntitySystem
{
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly IResourceManager _resourceManager = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly PvsOverrideSystem _pvsOverrideSystem = default!;
private readonly List<JukeboxComponent> _playingJukeboxes = [];
private readonly List<JukeboxComponent> _playingJukeboxes = new();
private float _updateTimerDefaultTime = 1f;
private const float UpdateTimerDefaultTime = 1f;
private float _updateTimer;
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<JukeboxRequestSongPlay>(OnSongRequestPlay);
SubscribeLocalEvent<JukeboxComponent, InteractUsingEvent>(OnInteract);
SubscribeLocalEvent<JukeboxComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<JukeboxComponent, JukeboxStopRequest>(OnRequestStop);
SubscribeLocalEvent<JukeboxComponent, JukeboxRepeatToggled>(OnRepeatToggled);
SubscribeLocalEvent<JukeboxComponent, JukeboxEjectRequest>(OnEjectRequest);
@@ -57,13 +46,13 @@ public sealed class JukeboxSystem : EntitySystem
private void OnEjectRequest(EntityUid uid, JukeboxComponent component, JukeboxEjectRequest args)
{
if(component.PlayingSongData != null) return;
if (component.PlayingSongData != null) return;
var containedEntities = component.TapeContainer.ContainedEntities;
if (containedEntities.Count > 0)
{
_containerSystem.EmptyContainer(component.TapeContainer, true).ToList();
_containerSystem.EmptyContainer(component.TapeContainer, true);
}
}
@@ -73,7 +62,7 @@ public sealed class JukeboxSystem : EntitySystem
if (jukeboxComponent.PlayingSongData != null) return;
if (jukeboxComponent.TapeContainer.ContainedEntities.Count == 0) return;
var removeTapeVerb = new Verb()
var removeTapeVerb = new Verb
{
Text = "Вытащить касету",
Priority = 10000,
@@ -95,77 +84,78 @@ public sealed class JukeboxSystem : EntitySystem
private void OnRepeatToggled(EntityUid uid, JukeboxComponent component, JukeboxRepeatToggled args)
{
component.Repeating = args.NewState;
Dirty(component);
component.Playing = args.NewState;
Dirty(uid, component);
}
private void OnRequestStop(EntityUid uid, JukeboxComponent component, JukeboxStopRequest args)
{
component.PlayingSongData = null;
Dirty(component);
Dirty(uid, component);
}
private void OnInteract(EntityUid uid, JukeboxComponent component, InteractUsingEvent args)
{
if(component.PlayingSongData != null) return;
if (component.PlayingSongData != null) return;
if (TryComp<TapeComponent>(args.Used, out var tape))
if (!HasComp<TapeComponent>(args.Used))
return;
var containedEntities = component.TapeContainer.ContainedEntities;
if (containedEntities.Count >= 1)
{
var containedEntities = component.TapeContainer.ContainedEntities;
var removedTapes = _containerSystem.EmptyContainer(component.TapeContainer, true).ToList();
_containerSystem.Insert(args.Used, component.TapeContainer);
if (containedEntities.Count >= 1)
foreach (var tapeUid in removedTapes)
{
var removedTapes = _containerSystem.EmptyContainer(component.TapeContainer, true).ToList();
component.TapeContainer.Insert(args.Used);
foreach (var tapeUid in removedTapes)
{
_handsSystem.PickupOrDrop(args.User, tapeUid);
}
}
else
{
component.TapeContainer.Insert(args.Used);
_handsSystem.PickupOrDrop(args.User, tapeUid);
}
}
else
{
_containerSystem.Insert(args.Used, component.TapeContainer);
}
}
private void OnSongRequestPlay(JukeboxRequestSongPlay msg, EntitySessionEventArgs args)
{
var jukebox = Comp<JukeboxComponent>(GetEntity(msg.Jukebox!.Value));
jukebox.Repeating = true;
var entity = GetEntity(msg.Jukebox!.Value);
var jukebox = Comp<JukeboxComponent>(entity);
jukebox.Playing = true;
var songData = new PlayingSongData()
var songData = new PlayingSongData
{
SongName = msg.SongName,
SongPath = msg.SongPath,
ActualSongLengthSeconds = msg.SongDuration,
PlaybackPosition = 0f
};
jukebox.PlayingSongData = songData;
_playingJukeboxes.Add(jukebox);
Dirty(jukebox);
Dirty(entity, jukebox);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
if (_updateTimer <= _updateTimerDefaultTime)
if (_updateTimer <= UpdateTimerDefaultTime)
{
_updateTimer += frameTime;
return;
}
ProcessPlayingJukeboxes(frameTime);
ProcessPlayingJukeboxes();
}
private void ProcessPlayingJukeboxes(float frameTime)
private void ProcessPlayingJukeboxes()
{
for (int i = _playingJukeboxes.Count - 1; i >= 0; i--)
for (var i = _playingJukeboxes.Count - 1; i >= 0; i--)
{
var playingJukeboxData = _playingJukeboxes[i];
@@ -177,9 +167,10 @@ public sealed class JukeboxSystem : EntitySystem
playingJukeboxData.PlayingSongData.PlaybackPosition += _updateTimer;
if (playingJukeboxData.PlayingSongData.PlaybackPosition >= playingJukeboxData.PlayingSongData.ActualSongLengthSeconds)
if (playingJukeboxData.PlayingSongData.PlaybackPosition >=
playingJukeboxData.PlayingSongData.ActualSongLengthSeconds)
{
if (playingJukeboxData.Repeating)
if (playingJukeboxData.Playing)
{
playingJukeboxData.PlayingSongData.PlaybackPosition = 0;
}
@@ -195,14 +186,4 @@ public sealed class JukeboxSystem : EntitySystem
_updateTimer = 0;
}
private void OnGetState(EntityUid uid, JukeboxComponent component, ref ComponentGetState args)
{
args.State = new JukeboxComponentState()
{
SongData = component.PlayingSongData,
Playing = component.Repeating,
Volume = component.Volume
};
}
}
}

View File

@@ -31,7 +31,7 @@ public sealed class ServerJukeboxSongsSyncManager : JukeboxSongsSyncManager
}
}
public (string songName, ResPath path) SyncSongData(string songName, List<byte> bytes)
public (string SongName, ResPath Path) SyncSongData(string songName, List<byte> bytes)
{
if (ContentRoot.TryGetFile(new ResPath(songName + ".ogg"), out _))
{

View File

@@ -1,13 +1,13 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Shared.CCVar;
using Content.Server.Popups;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Tag;
using Content.Shared.Verbs;
using Content.Shared._White.Jukebox;
using Robust.Shared.Configuration;
using Content.Shared.Popups;
using Robust.Server.Containers;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Utility;
@@ -16,16 +16,15 @@ namespace Content.Server._White.Jukebox;
public sealed class TapeCreatorSystem : EntitySystem
{
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly ServerJukeboxSongsSyncManager _songsSyncManager = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly TagSystem _tagSystem = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly TagSystem _tag = default!;
private const int RecordTime = 25;
private readonly int _recordTime = 25;
private static string TapeCreatorContainerName = "tape_creator_container";
private const string TapeCreatorContainerName = "tape_creator_container";
public override void Initialize()
{
@@ -44,7 +43,7 @@ public sealed class TapeCreatorSystem : EntitySystem
if (ev.Hands == null) return;
if (component.TapeContainer.ContainedEntities.Count == 0) return;
var removeTapeVerb = new Verb()
var removeTapeVerb = new Verb
{
Text = "Вытащить касету",
Priority = 10000,
@@ -52,15 +51,15 @@ public sealed class TapeCreatorSystem : EntitySystem
Act = () =>
{
var tapes = component.TapeContainer.ContainedEntities.ToList();
_containerSystem.EmptyContainer(component.TapeContainer, true);
_container.EmptyContainer(component.TapeContainer, true);
foreach (var tape in tapes)
{
_handsSystem.PickupOrDrop(ev.User, tape);
_hands.PickupOrDrop(ev.User, tape);
}
component.InsertedTape = null;
Dirty(component);
Dirty(uid, component);
}
};
@@ -69,7 +68,7 @@ public sealed class TapeCreatorSystem : EntitySystem
private void OnTapeStateChanged(EntityUid uid, TapeComponent component, ref ComponentGetState args)
{
args.State = new TapeComponentState()
args.State = new TapeComponentState
{
Songs = component.Songs
};
@@ -87,95 +86,105 @@ public sealed class TapeCreatorSystem : EntitySystem
private void OnComponentInit(EntityUid uid, TapeCreatorComponent component, ComponentInit args)
{
component.TapeContainer = _containerSystem.EnsureContainer<Container>(uid, TapeCreatorContainerName);
component.TapeContainer = _container.EnsureContainer<Container>(uid, TapeCreatorContainerName);
}
private void OnInteract(EntityUid uid, TapeCreatorComponent component, InteractUsingEvent args)
{
if(component.Recording) return;
if (component.Recording)
{
return;
}
if (TryComp<TapeComponent>(args.Used, out var tape))
if (HasComp<TapeComponent>(args.Used))
{
var containedEntities = component.TapeContainer.ContainedEntities;
if (containedEntities.Count > 1)
{
var removedTapes = _containerSystem.EmptyContainer(component.TapeContainer, true).ToList();
component.TapeContainer.Insert(args.Used);
var removedTapes = _container.EmptyContainer(component.TapeContainer, true).ToList();
_container.Insert(args.Used, component.TapeContainer);
foreach (var tapes in removedTapes)
{
_handsSystem.PickupOrDrop(args.User, tapes);
_hands.PickupOrDrop(args.User, tapes);
}
}
else
{
component.TapeContainer.Insert(args.Used);
_container.Insert(args.Used, component.TapeContainer);
}
component.InsertedTape = GetNetEntity(tape.Owner);
Dirty(component);
component.InsertedTape = GetNetEntity(args.Used);
Dirty(uid, component);
return;
}
if (_tagSystem.HasTag(args.Used, "TapeRecorderCoin"))
if (_tag.HasTag(args.Used, "TapeRecorderCoin"))
{
Del(args.Used);
component.CoinBalance += 1;
Dirty(component);
return;
Dirty(uid, component);
}
}
private void OnSongUploaded(JukeboxSongUploadRequest ev)
{
if(!TryComp<TapeCreatorComponent>(GetEntity(ev.TapeCreatorUid), out var tapeCreatorComponent)) return;
var tapeCreator = GetEntity(ev.TapeCreatorUid);
if (!TryComp<TapeCreatorComponent>(tapeCreator, out var tapeCreatorComponent))
{
return;
}
if (!tapeCreatorComponent.InsertedTape.HasValue || tapeCreatorComponent.CoinBalance <= 0)
{
_popupSystem.PopupEntity("Т# %ак@ э*^о сdf{ал б2я~b? Запись была прервана.", tapeCreatorComponent.Owner);
_popup.PopupEntity("Т# %ак@ э*^о сdf{ал б2я~b? Запись была прервана.", tapeCreator);
return;
}
tapeCreatorComponent.CoinBalance -= 1;
tapeCreatorComponent.Recording = true;
var tapeComponent = Comp<TapeComponent>(GetEntity(tapeCreatorComponent.InsertedTape.Value));
var insertedTape = GetEntity(tapeCreatorComponent.InsertedTape.Value);
var tapeComponent = Comp<TapeComponent>(insertedTape);
var songData = _songsSyncManager.SyncSongData(ev.SongName, ev.SongBytes);
var song = new JukeboxSong()
var song = new JukeboxSong
{
SongName = songData.songName,
SongPath = songData.path
SongName = songData.SongName,
SongPath = songData.Path
};
tapeComponent.Songs.Add(song);
_popupSystem.PopupEntity($"Запись началась, примерное время ожидания: {_recordTime} секунд", tapeCreatorComponent.Owner);
_popup.PopupEntity($"Запись началась, примерное время ожидания: {RecordTime} секунд", tapeCreator);
DirtyEntity(GetEntity(ev.TapeCreatorUid));
Dirty(tapeComponent);
StartRecordDelayAsync(tapeCreatorComponent, _popupSystem, _containerSystem);
Dirty(insertedTape, tapeComponent);
StartRecordDelayAsync(tapeCreator, tapeCreatorComponent, _popup, _container);
}
private async void StartRecordDelayAsync(TapeCreatorComponent component, SharedPopupSystem popupSystem, SharedContainerSystem containerSystem)
private async void StartRecordDelayAsync(
EntityUid uid,
TapeCreatorComponent component,
SharedPopupSystem popupSystem,
SharedContainerSystem containerSystem)
{
var recordTimeDelay = _recordTime * 1000 / 10;
const int recordTimeDelay = RecordTime * 1000 / 10;
await Task.Delay(1000);
for (int i = 0; i < 10; i++)
for (var i = 0; i < 10; i++)
{
popupSystem.PopupEntity($"Запись мозговой активности выполнена на {i * 10}%", component.Owner);
popupSystem.PopupEntity($"Запись мозговой активности выполнена на {i * 10}%", uid);
await Task.Delay(recordTimeDelay);
}
containerSystem.EmptyContainer(component.TapeContainer, force: true).ToList();
containerSystem.EmptyContainer(component.TapeContainer, force: true);
component.Recording = false;
component.InsertedTape = null;
popupSystem.PopupEntity($"Запись мозговой активности завершена", component.Owner);
Dirty(component);
popupSystem.PopupEntity("Запись мозговой активности завершена", uid);
Dirty(uid, component);
}
}
}

View File

@@ -15,7 +15,6 @@ namespace Content.Server._White.Keyhole;
public sealed partial class KeyholeSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
@@ -37,6 +36,11 @@ public sealed partial class KeyholeSystem : EntitySystem
private void OnKeyInsert(EntityUid uid, KeyComponent component, AfterInteractEvent ev)
{
if (!ev.Target.HasValue)
{
return;
}
if (TryComp<KeyformComponent>(ev.Target, out var keyformComponent))
OnKeyInsertForm(uid, component, keyformComponent, ev);
@@ -45,24 +49,24 @@ public sealed partial class KeyholeSystem : EntitySystem
keyholeComponent.FormId ??= component.FormId;
if (!CanLock(keyholeComponent.Owner, keyholeComponent, component))
if (!CanLock(ev.Target.Value, keyholeComponent, component))
return;
var doAfterEventArgs =
new DoAfterArgs(EntityManager, ev.User, keyholeComponent.Delay, new KeyInsertDoAfterEvent(), ev.Target, ev.Used)
{
BreakOnTargetMove = true,
BreakOnUserMove = true,
BreakOnDamage = true
};
var doAfterEventArgs = new DoAfterArgs(EntityManager, ev.User, keyholeComponent.Delay,
new KeyInsertDoAfterEvent(), ev.Target, ev.Used)
{
BreakOnMove = true,
BreakOnDamage = true
};
_doAfter.TryStartDoAfter(doAfterEventArgs);
}
private bool CanLock(EntityUid uid, KeyholeComponent keyholeComponent, KeyComponent keyComponent)
{
var can = TryComp<DoorComponent>(uid, out var doorComponent) &&
keyholeComponent.FormId == keyComponent.FormId &&
doorComponent.State == DoorState.Closed;
keyholeComponent.FormId == keyComponent.FormId &&
doorComponent.State == DoorState.Closed;
return can;
}
@@ -80,13 +84,14 @@ public sealed partial class KeyholeSystem : EntitySystem
private bool IsStateChanging(EntityUid uid)
{
return TryComp<DoorComponent>(uid, out var doorComponent) &&
(doorComponent.State == DoorState.Closing || doorComponent.State == DoorState.Opening);
(doorComponent.State == DoorState.Closing || doorComponent.State == DoorState.Opening);
}
private void Lock(EntityUid uid, KeyholeComponent component, EntityUid user)
{
var sound = component.Locked ? component.UnlockSound : component.LockSound;
var message = Loc.GetString(component.Locked ? "key-unlock-message" : "key-lock-message", ("name", user), ("door", uid));
var message = Loc.GetString(component.Locked ? "key-unlock-message" : "key-lock-message", ("name", user),
("door", uid));
var audioParams = new AudioParams().WithVolume(-5f);
@@ -96,7 +101,11 @@ public sealed partial class KeyholeSystem : EntitySystem
component.Locked = !component.Locked;
}
private void OnKeyInsertForm(EntityUid uid, KeyComponent keyComponent, KeyformComponent keyformComponent, AfterInteractEvent args)
private void OnKeyInsertForm(
EntityUid uid,
KeyComponent keyComponent,
KeyformComponent keyformComponent,
AfterInteractEvent args)
{
if (!keyformComponent.IsUsed)
{
@@ -104,16 +113,16 @@ public sealed partial class KeyholeSystem : EntitySystem
_appearance.SetData(keyformComponent.Owner, KeyformVisuals.IsUsed, true);
_audio.PlayPvs(keyformComponent.PressSound, uid);
_popupSystem.PopupEntity(Loc.GetString("key-pressed-in-keyform-message-first", ("user", args.User), ("key", uid)), uid);
_popupSystem.PopupEntity(
Loc.GetString("key-pressed-in-keyform-message-first", ("user", args.User), ("key", uid)), uid);
keyformComponent.IsUsed = true;
}
else
{
keyComponent.FormId = keyformComponent.FormId;
_popupSystem.PopupEntity(Loc.GetString("key-pressed-in-keyform-message", ("user", args.User), ("key", uid)), uid);
_popupSystem.PopupEntity(Loc.GetString("key-pressed-in-keyform-message", ("user", args.User), ("key", uid)),
uid);
}
}
}
}

View File

@@ -1,14 +1,11 @@
using Content.Server.Chat.Managers;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using Content.Server.Chat.Managers;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules;
using Content.Server.Mind;
using Content.Server.Popups;
using Content.Server.Roles;
using Content.Server.Popups;
using Content.Server.Roles;
using Content.Server.Store.Components;
using Content.Server.Store.Systems;
using Content.Server._White.Sponsors;
@@ -17,18 +14,11 @@ using Content.Shared.GameTicking;
using Content.Shared.Humanoid;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Roles.Jobs;
using Content.Shared.Popups;
using Content.Shared.Verbs;
using Content.Shared._White;
using Content.Shared._White.MeatyOre;
using Content.Shared.Verbs;
using Content.Shared._White;
using Content.Shared._White.MeatyOre;
using Newtonsoft.Json.Linq;
using Robust.Server.GameObjects;
using Robust.Server.GameStates;
using Robust.Server.Player;
using Robust.Shared.Configuration;
@@ -49,21 +39,19 @@ public sealed class MeatyOreStoreSystem : EntitySystem
[Dependency] private readonly SponsorsManager _sponsorsManager = default!;
[Dependency] private readonly PvsOverrideSystem _pvsOverrideSystem = default!;
[Dependency] private readonly RoleSystem _roleSystem = default!;
[Dependency] private readonly MindSystem _mindSystem = default!;
[Dependency] private readonly SharedJobSystem _jobSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
private HttpClient _httpClient = default!;
private string _apiUrl = default!;
private static readonly string StorePresetPrototype = "StorePresetMeatyOre";
private static readonly string MeatyOreCurrencyPrototype = "MeatyOreCoin";
private const string StorePresetPrototype = "StorePresetMeatyOre";
private const string MeatyOreCurrencyPrototype = "MeatyOreCoin";
private bool _meatyOrePanelEnabled;
private bool _antagGrantEnabled;
private readonly Dictionary<NetUserId, StoreComponent> _meatyOreStores = new();
private readonly Dictionary<NetUserId, (EntityUid Entity, StoreComponent Component)> _meatyOreStores = new();
public override void Initialize()
{
@@ -73,17 +61,16 @@ public sealed class MeatyOreStoreSystem : EntitySystem
_configurationManager.OnValueChanged(WhiteCVars.MeatyOrePanelEnabled, OnPanelEnableChanged, true);
_configurationManager.OnValueChanged(WhiteCVars.OnlyInOhio, s => _apiUrl = s, true);
_configurationManager.OnValueChanged(WhiteCVars.EnableGrantAntag, b => _antagGrantEnabled = b, true );
_configurationManager.OnValueChanged(WhiteCVars.EnableGrantAntag, b => _antagGrantEnabled = b, true);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnPostRoundCleanup);
SubscribeNetworkEvent<MeatyOreShopRequestEvent>(OnShopRequested);
SubscribeLocalEvent<GetVerbsEvent<Verb>>(MeatyOreVerbs);
}
private void MeatyOreVerbs(GetVerbsEvent<Verb> ev)
{
if(!_antagGrantEnabled)
if (!_antagGrantEnabled)
return;
if (!EntityManager.TryGetComponent<ActorComponent>(ev.User, out var actorComponent))
@@ -95,23 +82,22 @@ public sealed class MeatyOreStoreSystem : EntitySystem
if (!HasComp<HumanoidAppearanceComponent>(ev.Target))
return;
if (!TryGetStore(actorComponent.PlayerSession, out var store))
if (!TryGetStore(actorComponent.PlayerSession, out var store, out var storeEntity))
return;
var verb = new Verb()
var verb = new Verb
{
Text = $"Выдать роль.",
Text = "Выдать роль.",
ConfirmationPopup = true,
Message = $"Цена - {MeatyOreCurrencyPrototype}:10",
Act = () =>
{
TryAddRole(ev.User, ev.Target, store);
TryAddRole(ev.User, ev.Target, store, storeEntity.Value);
},
Category = VerbCategory.MeatyOre
};
ev.Verbs.Add(verb);
}
private void OnPanelEnableChanged(bool enabled)
@@ -120,57 +106,66 @@ public sealed class MeatyOreStoreSystem : EntitySystem
{
foreach (var meatyOreStoreData in _meatyOreStores)
{
var session = _playerManager.GetSessionByUserId(meatyOreStoreData.Key);
var session = _playerManager.GetSessionById(meatyOreStoreData.Key);
var playerEntity = session.AttachedEntity;
if(!playerEntity.HasValue)
if (!playerEntity.HasValue)
continue;
_storeSystem.CloseUi(playerEntity.Value, meatyOreStoreData.Value);
_storeSystem.CloseUi(playerEntity.Value, meatyOreStoreData.Value.Component);
}
}
_meatyOrePanelEnabled = enabled;
}
private void OnShopRequested(MeatyOreShopRequestEvent msg, EntitySessionEventArgs args)
{
var playerSession = args.SenderSession;
if (!_meatyOrePanelEnabled)
{
_chatManager.DispatchServerMessage(playerSession!, "Мясная панель отключена на данном сервере! Приятной игры!");
_chatManager.DispatchServerMessage(playerSession,
"Мясная панель отключена на данном сервере! Приятной игры!");
return;
}
var playerEntity = args.SenderSession.AttachedEntity;
if(!playerEntity.HasValue)
if (!playerEntity.HasValue)
return;
if(!HasComp<HumanoidAppearanceComponent>(playerEntity.Value))
if (!HasComp<HumanoidAppearanceComponent>(playerEntity.Value))
return;
if(!TryGetStore(playerSession!, out var storeComponent))
if (!TryGetStore(playerSession, out var storeComponent, out var storeEntity))
return;
_pvsOverrideSystem.AddSessionOverride(storeComponent.Owner, playerSession!);
_storeSystem.ToggleUi(playerEntity.Value, storeComponent.Owner, storeComponent);
_pvsOverrideSystem.AddSessionOverride(storeEntity.Value, playerSession);
_storeSystem.ToggleUi(playerEntity.Value, storeEntity.Value, storeComponent);
}
private bool TryGetStore(ICommonSession session, out StoreComponent store)
private bool TryGetStore(ICommonSession session, out StoreComponent store, [NotNullWhen(true)] out EntityUid? storeEntity)
{
store = null!;
storeEntity = null!;
if (!_sponsorsManager.TryGetInfo(session.UserId, out var sponsorInfo))
return false;
if (_meatyOreStores.TryGetValue(session.UserId, out store!))
if (_meatyOreStores.TryGetValue(session.UserId, out var pair))
{
storeEntity = pair.Entity;
store = pair.Component;
return true;
}
if (sponsorInfo.MeatyOreCoin == 0)
return false;
store = CreateStore(session.UserId, sponsorInfo.MeatyOreCoin);
(storeEntity, store) = CreateStore(session.UserId, sponsorInfo.MeatyOreCoin);
return true;
}
@@ -178,29 +173,31 @@ public sealed class MeatyOreStoreSystem : EntitySystem
{
foreach (var store in _meatyOreStores.Values)
{
Del(store.Owner);
Del(store.Entity);
}
_meatyOreStores.Clear();
}
private StoreComponent CreateStore(NetUserId userId, int balance)
private (EntityUid, StoreComponent) CreateStore(NetUserId userId, int balance)
{
var session = _playerManager.GetSessionByUserId(userId);
var shopEntity = _entityManager.SpawnEntity("StoreMeatyOreEntity", MapCoordinates.Nullspace);
var storeComponent = Comp<StoreComponent>(shopEntity);
var session = _playerManager.GetSessionById(userId);
var storeEntity = _entityManager.SpawnEntity("StoreMeatyOreEntity", MapCoordinates.Nullspace);
var storeComponent = Comp<StoreComponent>(storeEntity);
_storeSystem.InitializeFromPreset(StorePresetPrototype, shopEntity, storeComponent);
_storeSystem.InitializeFromPreset(StorePresetPrototype, storeEntity, storeComponent);
storeComponent.Balance.Clear();
_storeSystem.TryAddCurrency(new Dictionary<string, FixedPoint2>() { { MeatyOreCurrencyPrototype, balance } }, storeComponent.Owner, storeComponent);
_meatyOreStores[userId] = storeComponent;
_pvsOverrideSystem.AddSessionOverride(shopEntity, session);
_storeSystem.TryAddCurrency(new Dictionary<string, FixedPoint2> { { MeatyOreCurrencyPrototype, balance } },
storeEntity, storeComponent);
return storeComponent;
_meatyOreStores[userId] = (storeEntity, storeComponent);
_pvsOverrideSystem.AddSessionOverride(storeEntity, session);
return (storeEntity, storeComponent);
}
private async void TryAddRole(EntityUid user, EntityUid target, StoreComponent store)
private async void TryAddRole(EntityUid user, EntityUid target, StoreComponent store, EntityUid storeEntity)
{
if (!EntityManager.TryGetComponent<ActorComponent>(user, out var userActorComponent))
return;
@@ -217,10 +214,9 @@ public sealed class MeatyOreStoreSystem : EntitySystem
if (!store.Balance.TryGetValue(MeatyOreCurrencyPrototype, out var currency))
return;
if(currency - 10 < 0)
if (currency - 10 < 0)
return;
var fake = _roleSystem.MindIsAntagonist(targetMind.Mind.Value) || !_jobSystem.CanBeAntag(mindComponent.Session);
var ckey = userActorComponent.PlayerSession.Name;
@@ -229,21 +225,23 @@ public sealed class MeatyOreStoreSystem : EntitySystem
if (result)
{
_storeSystem.TryAddCurrency(new Dictionary<string, FixedPoint2> { { MeatyOreCurrencyPrototype, -10 } }, store.Owner, store);
_storeSystem.TryAddCurrency(new Dictionary<string, FixedPoint2> { { MeatyOreCurrencyPrototype, -10 } },
storeEntity, store);
if (!fake)
{
_traitorRuleSystem.MakeTraitor(targetActorComponent.PlayerSession);
_traitorRuleSystem.MakeTraitorAdmin(target, true, true);
var msg = $"Игрок с сикеем {ckey} выдал антажку {targetActorComponent.PlayerSession.Name}";
_chatManager.SendAdminAnnouncement(msg);
}
else
{
var msg = $"Игрок с сикеем {ckey} попытался выдать антажку {targetActorComponent.PlayerSession.Name}. Но обосрался. Была выдана фейковая антажка.";
var msg =
$"Игрок с сикеем {ckey} попытался выдать антажку {targetActorComponent.PlayerSession.Name}. Но обосрался. Была выдана фейковая антажка.";
_chatManager.SendAdminAnnouncement(msg);
}
}
else
{
@@ -301,9 +299,7 @@ public sealed class MeatyOreStoreSystem : EntitySystem
url = $"{_apiUrl}/api/Antagonist/cooldownFriend?userId={ckey}";
}
HttpResponseMessage response;
response = await _httpClient.GetAsync(url);
var response = await _httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
@@ -311,7 +307,8 @@ public sealed class MeatyOreStoreSystem : EntitySystem
if (!string.IsNullOrEmpty(responseData))
{
var jsonObject = JObject.Parse(responseData);
if (jsonObject.TryGetValue("remainingTime", out var remainingTimeToken) && TimeSpan.TryParse(remainingTimeToken.ToString(), out var remainingTime))
if (jsonObject.TryGetValue("remainingTime", out var remainingTimeToken) &&
TimeSpan.TryParse(remainingTimeToken.ToString(), out var remainingTime))
{
var time = new TimeSpan(remainingTime.Hours, remainingTime.Minutes, 0);
return time;
@@ -330,4 +327,4 @@ public sealed class MeatyOreStoreSystem : EntitySystem
return TimeSpan.Zero;
}
}
}

View File

@@ -14,7 +14,7 @@ using Robust.Shared.Audio.Systems;
namespace Content.Server._White.SelfHeal;
public sealed class SelfHealSystem: EntitySystem
public sealed class SelfHealSystem : EntitySystem
{
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
@@ -49,7 +49,6 @@ public sealed class SelfHealSystem: EntitySystem
private void OnDoAfter(EntityUid uid, DamageableComponent component, SelfHealDoAfterEvent args)
{
var dontRepeat = false;
if (!TryComp(args.User, out SelfHealComponent? healing) || args.Target == null)
return;
@@ -57,9 +56,9 @@ public sealed class SelfHealSystem: EntitySystem
if (args.Handled || args.Cancelled)
return;
if (healing.DamageContainers is not null &&
component.DamageContainerID is not null &&
!healing.DamageContainers.Contains(component.DamageContainerID))
if (healing.DamageContainers is not null
&& component.DamageContainerID is not null
&& !healing.DamageContainers.Contains(component.DamageContainerID))
{
return;
}
@@ -70,12 +69,11 @@ public sealed class SelfHealSystem: EntitySystem
Heal(args.Target.Value, healing, args);
// Logic to determine the whether or not to repeat the healing action
args.Repeat = (HasDamage(component, healing) && !dontRepeat);
if (!args.Repeat && !dontRepeat)
args.Repeat = HasDamage(component, healing);
if (!args.Repeat)
_popupSystem.PopupEntity(Loc.GetString("self-heal-finished-using", ("name", uid)), uid, args.User);
args.Handled = true;
}
private void Heal(EntityUid uid, SelfHealComponent component, SelfHealDoAfterEvent args)
@@ -92,6 +90,7 @@ public sealed class SelfHealSystem: EntitySystem
var healMessage = uid != args.User
? $"{userString:user} healed {targetString:target} for {total:damage} by licking"
: $"{userString:user} healed themselves for {total:damage} by licking";
_adminLogger.Add(LogType.Healed, $"{healMessage}");
if (TryComp<SelfHealComponent>(args.User, out var selfHealComponent))
@@ -100,13 +99,15 @@ public sealed class SelfHealSystem: EntitySystem
var audioParams = new AudioParams().WithVariation(2f).WithVolume(-5f);
_audio.PlayPvs(audio, args.User, audioParams);
_popupSystem.PopupEntity(Loc.GetString("self-heal-using-other", ("user", args.Args.User), ("target", uid)), uid);
_popupSystem.PopupEntity(Loc.GetString("self-heal-using-other", ("user", args.Args.User), ("target", uid)),
uid);
}
}
private bool CanHeal(EntityUid user, EntityUid target, SelfHealComponent component)
{
if (!TryComp<DamageableComponent>(target, out var targetDamage) || !HasComp<HumanoidAppearanceComponent>(target))
if (!TryComp<DamageableComponent>(target, out var targetDamage) ||
!HasComp<HumanoidAppearanceComponent>(target))
return false;
if (user != target && !_interactionSystem.InRangeUnobstructed(user, target, popup: true))
@@ -140,7 +141,9 @@ public sealed class SelfHealSystem: EntitySystem
{
if (_inventorySystem.TryGetSlotEntity(target, clothing, out var blockedClothing))
{
var popup = Loc.GetString("self-heal-cant-use-clothing-other", ("name", target), ("clothing", blockedClothing));
var popup = Loc.GetString("self-heal-cant-use-clothing-other", ("name", target),
("clothing", blockedClothing));
_popupSystem.PopupEntity(popup, user, user);
return false;
}
@@ -158,10 +161,10 @@ public sealed class SelfHealSystem: EntitySystem
var doAfterEventArgs =
new DoAfterArgs(EntityManager, user, component.Delay, new SelfHealDoAfterEvent(), target, target)
{
BreakOnTargetMove = true,
BreakOnUserMove = true,
BreakOnMove = true,
BreakOnDamage = true,
};
_doAfter.TryStartDoAfter(doAfterEventArgs);
}
@@ -177,4 +180,4 @@ public sealed class SelfHealSystem: EntitySystem
return false;
}
}
}

View File

@@ -1,9 +1,7 @@
using System.Linq;
using Lidgren.Network;
using Lidgren.Network;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
@@ -21,45 +19,46 @@ public enum TapeCreatorUIKey : byte
Key
}
[NetworkedComponent, RegisterComponent]
[NetworkedComponent, RegisterComponent, AutoGenerateComponentState]
public sealed partial class JukeboxComponent : Component
{
public static string JukeboxContainerName = "jukebox_tapes";
public static string JukeboxDefaultSongsName = "jukebox_default_tapes";
[ViewVariables(VVAccess.ReadOnly)]
public Container TapeContainer = default!;
[DataField("defaultTapes")]
public List<string> DefaultTapes = new();
[DataField]
public List<string> DefaultTapes = [];
[ViewVariables(VVAccess.ReadOnly)]
public Container DefaultSongsContainer = default!;
[ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
public bool Playing { get; set; } = true;
[ViewVariables(VVAccess.ReadOnly)]
public bool Repeating { get; set; } = true;
[DataField("volume") ,ViewVariables(VVAccess.ReadOnly)]
[DataField, ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
public float Volume { get; set; }
[DataField("maxAudioRange")]
[DataField]
public float MaxAudioRange { get; set; } = 20f;
[DataField("rolloffFactor")]
[DataField]
public float RolloffFactor { get; set; } = 0.3f;
[AutoNetworkedField]
public PlayingSongData? PlayingSongData { get; set; }
}
public sealed partial class TapeContainerComponent : Component
{
public int MaxTapeCount = 1;
public Container TapeContainer { get; set; } = new();
}
[Serializable, NetSerializable]
public class PlayingSongData
public sealed class PlayingSongData
{
public ResPath? SongPath;
public string? SongName;
@@ -67,59 +66,56 @@ public class PlayingSongData
public float ActualSongLengthSeconds;
}
[Serializable, NetSerializable]
public class JukeboxComponentState : ComponentState
{
public bool Playing { get; set; }
public PlayingSongData? SongData { get; set; }
public float Volume { get; set; }
}
[Serializable, NetSerializable, DataDefinition]
public sealed partial class JukeboxSong
{
[DataField("songName")]
[DataField]
public string? SongName;
[DataField("path")]
public ResPath? SongPath;
}
[Serializable, NetSerializable]
public class JukeboxRequestSongPlay : EntityEventArgs
public sealed class JukeboxRequestSongPlay : EntityEventArgs
{
public string? SongName { get; set; }
public ResPath? SongPath { get; set; }
public NetEntity? Jukebox { get; set; }
public float SongDuration { get; set; }
}
[Serializable, NetSerializable]
public class JukeboxRequestStop : EntityEventArgs
public sealed class JukeboxRequestStop : EntityEventArgs
{
public NetEntity? JukeboxUid { get; set; }
}
[Serializable, NetSerializable]
public class JukeboxStopPlaying : EntityEventArgs
public sealed class JukeboxStopPlaying : EntityEventArgs
{
public NetEntity? JukeboxUid { get; set; }
}
[Serializable, NetSerializable]
public class JukeboxSongUploadRequest : EntityEventArgs
public sealed class JukeboxSongUploadRequest : EntityEventArgs
{
public string SongName = string.Empty;
public List<byte> SongBytes = new();
public List<byte> SongBytes = [];
public NetEntity TapeCreatorUid = default!;
}
public class JukeboxSongUploadNetMessage : NetMessage
public sealed class JukeboxSongUploadNetMessage : NetMessage
{
public override NetDeliveryMethod DeliveryMethod => NetDeliveryMethod.ReliableUnordered;
public override MsgGroups MsgGroup => MsgGroups.Command;
public ResPath RelativePath { get; set; } = ResPath.Self;
public byte[] Data { get; set; } = Array.Empty<byte>();
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
@@ -136,4 +132,4 @@ public class JukeboxSongUploadNetMessage : NetMessage
buffer.Write(RelativePath.ToString());
buffer.Write(ResPath.Separator);
}
}
}

View File

@@ -56,7 +56,6 @@
ClothingNeckCloakMoth: 2
ClothingOuterDogi: 1
ClothingHeadHatMagician: 1
ClothingHeadHatBeretFrench: 2
ClothingHeadHatRedRacoon: 2
ClothingOuterRedRacoon: 2
ClothingHeadHatGladiator: 1