Локализация фотоаппарата и выделение системы PhotoOverlay.

This commit is contained in:
Vigers Ray 2026-01-30 06:22:34 +01:00
parent 5f3f836fe5
commit 0000e6a222
7 changed files with 97 additions and 55 deletions

View file

@ -10,21 +10,19 @@ namespace Content.Client._Sunrise.CartridgeLoader.Cartridges;
public sealed class PhotoCaptureOverlay : Overlay
{
private readonly IPlayerManager _playerManager;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
private readonly SharedTransformSystem _transformSystem;
private readonly IStateManager _stateManager;
private readonly IEyeManager _eyeManager;
private readonly IEntityManager _entityManager;
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
public PhotoCaptureOverlay(IPlayerManager playerManager, SharedTransformSystem transformSystem, IStateManager stateManager, IEyeManager eyeManager, IEntityManager entityManager)
public PhotoCaptureOverlay()
{
_playerManager = playerManager;
_transformSystem = transformSystem;
_stateManager = stateManager;
_eyeManager = eyeManager;
_entityManager = entityManager;
IoCManager.InjectDependencies(this);
_transformSystem = _entityManager.System<SharedTransformSystem>();
}
protected override void Draw(in OverlayDrawArgs args)
@ -38,17 +36,24 @@ public sealed class PhotoCaptureOverlay : Overlay
var screenHandle = args.ScreenHandle;
var viewportControl = (Control)viewportState.Viewport;
if (_playerManager.LocalPlayer?.ControlledEntity is not { } player)
return;
var overlaySystem = _entityManager.System<PhotoOverlaySystem>();
var photoSystem = _entityManager.System<PhotoCartridgeClientSystem>();
var playerPos = _transformSystem.GetWorldPosition(player);
var source = overlaySystem.ActiveCameraEntity;
var system = _entityManager.System<PhotoCartridgeClientSystem>();
var targetPos = system.GetCameraPosition(player, system.CaptureDistance);
if (source == null || !_entityManager.EntityExists(source.Value))
{
if (_playerManager.LocalSession?.AttachedEntity is not { } player)
return;
source = player;
}
var sourcePos = _transformSystem.GetWorldPosition(source.Value);
var targetPos = photoSystem.GetCameraPosition(source.Value, photoSystem.CaptureDistance);
var targetScreen = _eyeManager.WorldToScreen(targetPos);
var playerScreen = _eyeManager.WorldToScreen(playerPos);
var offsetScreen = _eyeManager.WorldToScreen(playerPos + new Vector2(1, 0));
var playerScreen = _eyeManager.WorldToScreen(sourcePos);
var offsetScreen = _eyeManager.WorldToScreen(sourcePos + new Vector2(1, 0));
var pixelsPerMeter = (offsetScreen - playerScreen).Length();
if (pixelsPerMeter < 1) return;

View file

@ -1,4 +1,3 @@
using System;
using System.IO;
using System.Linq;
using System.Numerics;
@ -12,12 +11,9 @@ using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Robust.Client.Player;
using Robust.Shared.Maths;
using Robust.Shared.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems;
using Content.Shared.Physics;
using Robust.Shared.Map.Components;
using Robust.Shared.Timing;
@ -25,7 +21,6 @@ namespace Content.Client._Sunrise.CartridgeLoader.Cartridges;
public sealed class PhotoCartridgeClientSystem : EntitySystem
{
[Dependency] private readonly IClyde _clyde = default!;
[Dependency] private readonly IClientNetManager _netManager = default!;
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;
@ -33,15 +28,11 @@ public sealed class PhotoCartridgeClientSystem : EntitySystem
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly IOverlayManager _overlayManager = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
private TimeSpan _nextCaptureTime = TimeSpan.Zero;
public bool CameraReady => _timing.CurTime >= _nextCaptureTime;
private PhotoCaptureOverlay? _overlay;
public bool OverlayEnabled { get; private set; }
public float CaptureDistance { get; set; } = 2.0f;
private ISawmill _sawmill = default!;
@ -53,26 +44,10 @@ public sealed class PhotoCartridgeClientSystem : EntitySystem
{
_sawmill = _logManager.GetSawmill("photo.cartridge.client");
_netManager.RegisterNetMessage<PdaPhotoCaptureMessage>(accept: NetMessageAccept.Server);
_overlay = new PhotoCaptureOverlay(_playerManager, _transformSystem, _stateManager, _eyeManager, _entityManager);
}
public void Shutdown()
{
_overlayManager.RemoveOverlay<PhotoCaptureOverlay>();
}
public void SetOverlayEnabled(bool enabled)
{
OverlayEnabled = enabled;
if (enabled)
{
if (!_overlayManager.HasOverlay<PhotoCaptureOverlay>())
_overlayManager.AddOverlay(_overlay!);
}
else
{
_overlayManager.RemoveOverlay<PhotoCaptureOverlay>();
}
}
public Vector2 GetCameraPosition(EntityUid source, float distance)

View file

@ -0,0 +1,40 @@
using Robust.Client.Graphics;
namespace Content.Client._Sunrise.CartridgeLoader.Cartridges;
public sealed class PhotoOverlaySystem : EntitySystem
{
[Dependency] private readonly IOverlayManager _overlayManager = default!;
private PhotoCaptureOverlay? _overlay;
public bool OverlayEnabled { get; private set; }
public EntityUid? ActiveCameraEntity { get; set; }
public override void Initialize()
{
base.Initialize();
_overlay = new PhotoCaptureOverlay();
}
public void SetOverlayEnabled(bool enabled, EntityUid? source = null)
{
OverlayEnabled = enabled;
ActiveCameraEntity = source;
if (enabled)
{
if (!_overlayManager.HasOverlay<PhotoCaptureOverlay>())
_overlayManager.AddOverlay(_overlay!);
}
else
{
_overlayManager.RemoveOverlay<PhotoCaptureOverlay>();
}
}
public override void Shutdown()
{
base.Shutdown();
_overlayManager.RemoveOverlay<PhotoCaptureOverlay>();
}
}

View file

@ -4,12 +4,12 @@
Orientation="Vertical">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0,0,0,4">
<Button Name="CameraTabBtn" Text="Камера" HorizontalExpand="True" ToggleMode="True" Pressed="True"/>
<Button Name="GalleryTabBtn" Text="Галерея" HorizontalExpand="True" ToggleMode="True"/>
<Button Name="CameraTabBtn" Text="{Loc 'photo-cartridge-tab-camera'}" HorizontalExpand="True" ToggleMode="True" Pressed="True"/>
<Button Name="GalleryTabBtn" Text="{Loc 'photo-cartridge-tab-gallery'}" HorizontalExpand="True" ToggleMode="True"/>
</BoxContainer>
<Label Name="ErrorMessageLabel" Text="" StyleClasses="Danger" Visible="False"/>
<Label Name="PhotoCountLabel" Text="Фотографий: 0/50" Align="Right" StyleClasses="LabelSubText"/>
<Label Name="PhotoCountLabel" Text="" Align="Right" StyleClasses="LabelSubText"/>
<BoxContainer Name="CameraView" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Visible="True">
<PanelContainer Name="CameraPreviewContainer" HorizontalExpand="True" VerticalExpand="True" Margin="0,0,0,4">
@ -17,14 +17,14 @@
</PanelContainer>
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0,0,0,4">
<Label Text="Зум:" Margin="0,0,8,0" VerticalAlignment="Center"/>
<Label Text="{Loc 'photo-cartridge-zoom-label'}" Margin="0,0,8,0" VerticalAlignment="Center"/>
<Slider Name="ZoomSlider" HorizontalExpand="True" MinValue="0" MaxValue="1" Value="0" Margin="0,0,8,0"/>
<CheckBox Name="FlashCheckBox" Text="{Loc 'messenger-photo-flash-label'}" Pressed="True"/>
<CheckBox Name="FlashCheckBox" Text="{Loc 'photo-cartridge-flash-label'}" Pressed="True"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Button Name="CaptureButton" Text="Сделать фото" HorizontalExpand="True" MinHeight="40"/>
<Button Name="ToggleOverlayButton" Text="👁 Оверлей" MinWidth="80" MinHeight="40"
<Button Name="CaptureButton" Text="{Loc 'photo-cartridge-capture-button'}" HorizontalExpand="True" MinHeight="40"/>
<Button Name="ToggleOverlayButton" Text="{Loc 'photo-cartridge-overlay-button'}" MinWidth="80" MinHeight="40"
ToggleMode="True" Margin="4,0,0,0"/>
</BoxContainer>
</BoxContainer>
@ -37,9 +37,9 @@
<BoxContainer Name="ImageViewOverlay" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Visible="False" Margin="4">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Button Name="BackFromImageParams" Text="Назад" HorizontalAlignment="Left"/>
<Button Name="BackFromImageParams" Text="{Loc 'photo-cartridge-back-button'}" HorizontalAlignment="Left"/>
<Control HorizontalExpand="True"/>
<Button Name="DeleteImageBtn" Text="Удалить" StyleClasses="Caution" HorizontalAlignment="Right"/>
<Button Name="DeleteImageBtn" Text="{Loc 'photo-cartridge-delete-button'}" StyleClasses="Caution" HorizontalAlignment="Right"/>
</BoxContainer>
<PanelContainer HorizontalExpand="True" VerticalExpand="True" Margin="0,4,0,0">
<TextureRect Name="FullImageRect" HorizontalExpand="True" VerticalExpand="True" Stretch="KeepAspectCentered"/>

View file

@ -60,7 +60,7 @@ public sealed partial class PhotoUiFragment : BoxContainer
FlashCheckBox.OnToggled += args => OnToggleFlash?.Invoke(args.Pressed);
ToggleOverlayButton.OnPressed += _ => ToggleCaptureAreaOverlay();
ToggleOverlayButton.Pressed = _entityManager.System<PhotoCartridgeClientSystem>().OverlayEnabled;
ToggleOverlayButton.Pressed = _entityManager.System<PhotoOverlaySystem>().OverlayEnabled;
CameraTabBtn.OnPressed += _ => SwitchTab(true);
GalleryTabBtn.OnPressed += _ => SwitchTab(false);
@ -86,7 +86,7 @@ public sealed partial class PhotoUiFragment : BoxContainer
base.Dispose(disposing);
if (disposing)
{
_entityManager.System<PhotoCartridgeClientSystem>().SetOverlayEnabled(false);
_entityManager.System<PhotoOverlaySystem>().SetOverlayEnabled(false);
}
}
@ -153,8 +153,8 @@ public sealed partial class PhotoUiFragment : BoxContainer
/// </summary>
private void ToggleCaptureAreaOverlay()
{
var system = _entityManager.System<PhotoCartridgeClientSystem>();
system.SetOverlayEnabled(!system.OverlayEnabled);
var system = _entityManager.System<PhotoOverlaySystem>();
system.SetOverlayEnabled(!system.OverlayEnabled, _ownerEntity);
ToggleOverlayButton.Pressed = system.OverlayEnabled;
}

View file

@ -0,0 +1,14 @@
photo-cartridge-photos-count = Photos: {$count}/{$max}
photo-cartridge-limit-reached = Photo limit reached
photo-cartridge-photo-not-found = Photo not found
photo-cartridge-messenger-unavailable = Messenger server unavailable
photo-cartridge-recipient-not-specified = Recipient not specified
photo-cartridge-photo-text = [Photo]
photo-cartridge-tab-camera = Camera
photo-cartridge-tab-gallery = Gallery
photo-cartridge-zoom-label = Zoom:
photo-cartridge-capture-button = Take Photo
photo-cartridge-overlay-button = 👁 Overlay
photo-cartridge-back-button = Back
photo-cartridge-delete-button = Delete
photo-cartridge-flash-label = Flash

View file

@ -9,3 +9,11 @@ photo-cartridge-photo-not-found = Фотография не найдена
photo-cartridge-messenger-unavailable = Сервер мессенджера недоступен
photo-cartridge-recipient-not-specified = Не указан получатель
photo-cartridge-photo-text = [Фото]
photo-cartridge-tab-camera = Камера
photo-cartridge-tab-gallery = Галерея
photo-cartridge-zoom-label = Зум:
photo-cartridge-capture-button = Сделать фото
photo-cartridge-overlay-button = 👁 Оверлей
photo-cartridge-back-button = Назад
photo-cartridge-delete-button = Удалить
photo-cartridge-flash-label = Вспышка