1- using Content . Shared . Hands . EntitySystems ;
1+ using Content . Client . Items ;
2+ using Content . Client . Items . UI ;
3+ using Content . Client . Message ;
4+ using Content . Client . Power . Visualizers ;
5+ using Content . Client . Stylesheets ;
6+ using Content . Shared . Atmos . Components ;
7+ using Content . Shared . Disposal . Components ;
8+ using Content . Shared . Input ;
29using Content . Shared . Inventory ;
310using Content . Shared . SubFloor ;
411using Robust . Client . Animations ;
512using Robust . Client . GameObjects ;
13+ using Robust . Client . Input ;
614using Robust . Client . Player ;
15+ using Robust . Client . UserInterface ;
16+ using Robust . Client . UserInterface . Controls ;
717using Robust . Shared . Timing ;
818
919namespace Content . Client . SubFloor ;
1020
11- public sealed partial class TrayScannerSystem : SharedTrayScannerSystem
21+ public sealed class TrayScannerSystem : SharedTrayScannerSystem
1222{
13- [ Dependency ] private IGameTiming _timing = default ! ;
14- [ Dependency ] private IPlayerManager _player = default ! ;
15- [ Dependency ] private AnimationPlayerSystem _animation = default ! ;
16- [ Dependency ] private EntityLookupSystem _lookup = default ! ;
17- [ Dependency ] private InventorySystem _inventory = default ! ;
18- [ Dependency ] private SharedAppearanceSystem _appearance = default ! ;
19- [ Dependency ] private SharedHandsSystem _hands = default ! ;
20- [ Dependency ] private SharedTransformSystem _transform = default ! ;
21- [ Dependency ] private SpriteSystem _sprite = default ! ;
22- [ Dependency ] private TrayScanRevealSystem _trayScanReveal = default ! ;
23+ [ Dependency ] private IGameTiming _timing = default ! ; // starlight edit: removed readonly
24+ [ Dependency ] private IPlayerManager _player = default ! ; // starlight edit: removed readonly
25+ [ Dependency ] private AnimationPlayerSystem _animation = default ! ; // starlight edit: removed readonly
26+ [ Dependency ] private EntityLookupSystem _lookup = default ! ; // starlight edit: removed readonly
27+ [ Dependency ] private InventorySystem _inventory = default ! ; // starlight edit: removed readonly
28+ [ Dependency ] private SharedAppearanceSystem _appearance = default ! ; // starlight edit: removed readonly
29+ [ Dependency ] private SharedTransformSystem _transform = default ! ; // starlight edit: removed readonly
30+ [ Dependency ] private SpriteSystem _sprite = default ! ; // starlight edit: removed readonly
31+ [ Dependency ] private TrayScanRevealSystem _trayScanReveal = default ! ; // starlight edit: removed readonly
32+ [ Dependency ] private IInputManager _inputManager = default ! ; // starlight edit: removed readonly
33+ [ Dependency ] private EntityQuery < TrayScannerComponent > _trayScannerQuery = default ! ; // starlight edit: removed readonly
34+ [ Dependency ] private EntityQuery < SubFloorHideComponent > _subFloorHideQuery = default ! ; // starlight edit: removed readonly
2335
2436 private const string TRayAnimationKey = "trays" ;
2537 private const double AnimationLength = 0.3 ;
2638
2739 public const LookupFlags Flags = LookupFlags . Static | LookupFlags . Sundries | LookupFlags . Approximate ;
2840
41+ public override void Initialize ( )
42+ {
43+ base . Initialize ( ) ;
44+ Subs . ItemStatus < TrayScannerComponent > ( OnCollectItemStatus ) ;
45+ }
46+
2947 public override void Update ( float frameTime )
3048 {
3149 base . Update ( frameTime ) ;
@@ -35,46 +53,27 @@ public override void Update(float frameTime)
3553
3654 // TODO: Multiple viewports or w/e
3755 var player = _player . LocalEntity ;
38- var xformQuery = GetEntityQuery < TransformComponent > ( ) ;
3956
40- if ( ! xformQuery . TryGetComponent ( player , out var playerXform ) )
57+ if ( ! TryComp ( player , out TransformComponent ? playerXform ) )
4158 return ;
4259
43- var playerPos = _transform . GetWorldPosition ( playerXform , xformQuery ) ;
60+ var playerPos = _transform . GetWorldPosition ( playerXform ) ;
4461 var playerMap = playerXform . MapID ;
4562 var range = 0f ;
63+ var mode = TrayScannerMode . All ;
4664 HashSet < Entity < SubFloorHideComponent > > inRange ;
47- var scannerQuery = GetEntityQuery < TrayScannerComponent > ( ) ;
4865
4966 // TODO: Should probably sub to player attached changes / inventory changes but inventory's
5067 // API is extremely skrungly. If this ever shows up on dottrace ping me and laugh.
5168 var canSee = false ;
5269
53- // TODO: Common iterator for both systems.
54- if ( _inventory . TryGetContainerSlotEnumerator ( player . Value , out var enumerator ) )
55- {
56- while ( enumerator . MoveNext ( out var slot ) )
57- {
58- foreach ( var ent in slot . ContainedEntities )
59- {
60- if ( ! scannerQuery . TryGetComponent ( ent , out var sneakScanner ) || ! sneakScanner . Enabled )
61- continue ;
62-
63- canSee = true ;
64- range = MathF . Max ( range , sneakScanner . Range ) ;
65- }
66- }
67- }
68-
69- foreach ( var hand in _hands . EnumerateHands ( player . Value ) )
70+ foreach ( var item in _inventory . GetHandOrInventoryEntities ( player . Value , SlotFlags . POCKET ) )
7071 {
71- if ( ! _hands . TryGetHeldItem ( player . Value , hand , out var heldEntity ) )
72- continue ;
73-
74- if ( ! scannerQuery . TryGetComponent ( heldEntity , out var heldScanner ) || ! heldScanner . Enabled )
72+ if ( ! _trayScannerQuery . TryGetComponent ( item , out var scanner ) || ! scanner . Enabled )
7573 continue ;
7674
77- range = MathF . Max ( heldScanner . Range , range ) ;
75+ range = MathF . Max ( scanner . Range , range ) ;
76+ mode = scanner . Mode ;
7877 canSee = true ;
7978 break ;
8079 }
@@ -83,23 +82,28 @@ public override void Update(float frameTime)
8382
8483 if ( canSee )
8584 {
86- _lookup . GetEntitiesInRange ( playerMap , playerPos , range , inRange , flags : Flags ) ;
85+ var entitiesInRange = new HashSet < Entity < SubFloorHideComponent > > ( ) ;
86+ _lookup . GetEntitiesInRange ( playerMap , playerPos , range , entitiesInRange , flags : Flags ) ;
8787
88- foreach ( var ( uid , comp ) in inRange )
88+ foreach ( var ( uid , comp ) in entitiesInRange )
8989 {
90+ if ( ! MatchesMode ( uid , mode ) )
91+ continue ;
92+
93+ inRange . Add ( ( uid , comp ) ) ;
94+
9095 if ( comp . IsUnderCover || _trayScanReveal . IsUnderRevealingEntity ( uid ) )
9196 EnsureComp < TrayRevealedComponent > ( uid ) ;
9297 }
9398 }
9499
95100 var revealedQuery = AllEntityQuery < TrayRevealedComponent , SpriteComponent > ( ) ;
96- var subfloorQuery = GetEntityQuery < SubFloorHideComponent > ( ) ;
97101
98102 while ( revealedQuery . MoveNext ( out var uid , out _ , out var sprite ) )
99103 {
100104 // Revealing
101105 // Add buffer range to avoid flickers.
102- if ( subfloorQuery . TryGetComponent ( uid , out var subfloor ) &&
106+ if ( _subFloorHideQuery . TryGetComponent ( uid , out var subfloor ) &&
103107 inRange . Contains ( ( uid , subfloor ) ) )
104108 {
105109 // Due to the fact client is predicting this server states will reset it constantly
@@ -174,4 +178,67 @@ private void SetRevealed(EntityUid uid, bool value)
174178 {
175179 _appearance . SetData ( uid , SubFloorVisuals . ScannerRevealed , value ) ;
176180 }
181+
182+ private bool MatchesMode ( EntityUid uid , TrayScannerMode mode )
183+ {
184+ return mode switch
185+ {
186+ TrayScannerMode . All => true ,
187+ TrayScannerMode . Wiring => HasComp < CableVisualizerComponent > ( uid ) ,
188+ // TODO: proper comp query after disposals refactor
189+ TrayScannerMode . Piping => HasComp < AtmosPipeLayersComponent > ( uid ) || _appearance . TryGetData ( uid , DisposalTubeVisuals . VisualState , out _ ) ,
190+ _ => false ,
191+ } ;
192+ }
193+
194+ #region UI
195+ private Control OnCollectItemStatus ( Entity < TrayScannerComponent > entity )
196+ {
197+ _inputManager . TryGetKeyBinding ( ( ContentKeyFunctions . AltUseItemInHand ) , out var binding ) ;
198+ return new StatusControl ( entity , binding ? . GetKeyString ( ) ?? "" ) ;
199+ }
200+
201+ private sealed class StatusControl : PollingItemStatusControl < StatusControl . TRayData >
202+ {
203+ private readonly RichTextLabel _label ;
204+ private readonly TrayScannerComponent _scanner ;
205+ private readonly string _keyBindingName ;
206+
207+ public StatusControl ( TrayScannerComponent scanner , string keyBindingName )
208+ {
209+ _scanner = scanner ;
210+ _keyBindingName = keyBindingName ;
211+ _label = new RichTextLabel { StyleClasses = { StyleClass . ItemStatus } } ;
212+ AddChild ( _label ) ;
213+ }
214+
215+ protected override TRayData PollData ( )
216+ {
217+ return new TRayData ( _scanner . Enabled , _scanner . Mode ) ;
218+ }
219+
220+ protected override void Update ( in TRayData data )
221+ {
222+ if ( ! data . Enabled )
223+ {
224+ _label . SetMarkup ( string . Empty ) ;
225+ return ;
226+ }
227+
228+ var modeLocString = data . Mode switch
229+ {
230+ TrayScannerMode . All => "tray-scanner-examine-mode-all" ,
231+ TrayScannerMode . Wiring => "tray-scanner-examine-mode-wiring" ,
232+ TrayScannerMode . Piping => "tray-scanner-examine-mode-piping" ,
233+ _ => "" ,
234+ } ;
235+
236+ _label . SetMarkup ( Robust . Shared . Localization . Loc . GetString ( "tray-scanner-item-status-label" ,
237+ ( "mode" , Robust . Shared . Localization . Loc . GetString ( modeLocString ) ) ,
238+ ( "keybinding" , _keyBindingName ) ) ) ;
239+ }
240+
241+ public readonly record struct TRayData ( bool Enabled , TrayScannerMode Mode ) ;
242+ }
243+ #endregion
177244}
0 commit comments