4343using System . Linq ;
4444using Content . Shared . Silicons . Laws . Components ;
4545using Content . Shared . DeviceLinking ;
46- using System . Numerics ;
4746using Content . Shared . _Starlight ;
47+ using Content . Shared . NameModifier . EntitySystems ;
4848#endregion Starlight
4949
5050namespace Content . Shared . Silicons . StationAi ;
@@ -79,6 +79,7 @@ public abstract partial class SharedStationAiSystem : EntitySystem
7979 [ Dependency ] private MobStateSystem _mobState = default ! ;
8080 [ Dependency ] private SharedDeviceLinkSystem _deviceLinkSystem = default ! ; // Starlight
8181 [ Dependency ] private StarlightEntitySystem _entitySystem = default ! ; // Starlight
82+ [ Dependency ] private NameModifierSystem _nameModifier = default ! ; // Starlight-edit
8283
8384 // StationAiHeld is added to anything inside of an AI core.
8485 // StationAiHolder indicates it can hold an AI positronic brain (e.g. holocard / core).
@@ -284,15 +285,24 @@ private void IntellicardTransfer(EntityUid uid, StationAiHolderComponent? compon
284285 if ( args . Args . Target == null ) // Starlight-edit
285286 return ;
286287
287- if ( ! TryComp ( args . Args . Target . Value , out StationAiHolderComponent ? targetHolder ) ) // Starlight-edit
288+ var target = args . Args . Target . Value ;
289+ if ( TryComp < BorgChassisComponent > ( target , out var chassis ) && chassis . BrainEntity is { } chassisBrain )
290+ target = chassisBrain ;
291+
292+ if ( ! TryComp ( target , out StationAiHolderComponent ? targetHolder ) &&
293+ ! HasComp < BorgBrainComponent > ( target ) ) // Starlight-edit
288294 return ;
289295
290296 // Starlight-start
291297
292298 var isBorg = HasComp < BorgBrainComponent > ( uid ) ;
293- var borgHaveMind = TryComp < MindContainerComponent > ( uid , out var mindContainer ) && _mind . GetMind ( uid , mindContainer ) != null ;
294- var isBorgTarget = HasComp < BorgBrainComponent > ( args . Args . Target . Value ) ;
295- var borgHaveMindTarget = TryComp < MindContainerComponent > ( args . Args . Target . Value , out var targetMindContainer ) && _mind . GetMind ( args . Args . Target . Value , targetMindContainer ) != null ;
299+ var borgMind = uid ; // Starlight-edit
300+ if ( isBorg && _containers . TryGetContainingContainer ( uid , out var borgContainer ) &&
301+ TryComp < BorgChassisComponent > ( borgContainer . Owner , out _ ) ) // Starlight-edit
302+ borgMind = borgContainer . Owner ; // Starlight-edit
303+ var borgHaveMind = TryComp < MindContainerComponent > ( borgMind , out var mindContainer ) && _mind . GetMind ( borgMind , mindContainer ) != null ; // Starlight-edit
304+ var isBorgTarget = HasComp < BorgBrainComponent > ( target ) ;
305+ var borgHaveMindTarget = TryComp < MindContainerComponent > ( target , out var targetMindContainer ) && _mind . GetMind ( target , targetMindContainer ) != null ;
296306
297307 // basically if the AI is off shunting we wanna force them BACK. simplest way to do that is to fake the event to send them back.
298308 var slot = component ? . Slot ;
@@ -301,43 +311,74 @@ private void IntellicardTransfer(EntityUid uid, StationAiHolderComponent? compon
301311 // Starlight-end
302312
303313 // Try to insert our thing into them
304- if ( slot != null && _slots . CanEject ( uid , args . User , slot ) ) // Starlight-edit
314+ if ( targetHolder != null && slot != null && _slots . CanEject ( uid , args . User , slot ) ) // Starlight-edit
305315 {
306- if ( ! _slots . TryInsert ( args . Args . Target . Value , targetHolder . Slot , slot . Item ! . Value , args . User , excludeUserAudio : true ) ) // Starlight-edit
307- {
316+ if ( ! _slots . TryInsert ( target , targetHolder . Slot , slot . Item ! . Value , args . User , excludeUserAudio : true ) ) // Starlight-edit
308317 return ;
309- }
310318
311319 args . Handled = true ;
312320 return ;
313321 }
314322 // Starlight-start: borgs can be downloaded/uploaded
315- else if ( isBorgTarget && borgHaveMindTarget && slot ? . ContainerSlot is { } containerSlot && containerSlot . ContainedEntity != null )
323+ else if ( isBorgTarget && ! borgHaveMindTarget && slot ? . ContainerSlot is { } containerSlot &&
324+ containerSlot . ContainedEntity is { } aiEntity )
316325 {
317- _mind . ControlMob ( args . Args . Target . Value , uid ) ;
318- Del ( containerSlot . ContainedEntity ) ;
326+ if ( ! _mind . TryGetMind ( aiEntity , out var mindId , out var mind ) )
327+ return ;
328+
329+ _mind . TransferTo ( mindId , target , ghostCheckOverride : true , mind : mind ) ;
330+ Del ( aiEntity ) ;
331+ args . Handled = true ;
332+ return ;
319333 }
320334 // Starlight-end
321335
322- // Otherwise try to take from them
323- if ( slot != null && _slots . CanEject ( args . Args . Target . Value , args . User , targetHolder . Slot ) ) // Starlight-edit
336+ // Starlight-start: Otherwise try to take from them
337+ if ( targetHolder != null && slot != null && _slots . CanEject ( target , args . User , targetHolder . Slot ) )
338+ {
339+ var held = targetHolder . Slot . Item ! . Value ;
340+ _metadata . SetEntityName ( held , _nameModifier . GetBaseName ( held ) , raiseEvents : false ) ;
341+ if ( ! _slots . TryInsert ( uid , slot , held , args . User , excludeUserAudio : true ) )
342+ return ;
343+ args . Handled = true ;
344+ }
345+ // Starlight: borgs can be downloaded/uploaded
346+ else if ( targetHolder != null && isBorg && ! borgHaveMind && targetHolder . Slot . Item is { } aiEntity )
324347 {
325- if ( ! _slots . TryInsert ( uid , slot , targetHolder . Slot . Item ! . Value , args . User , excludeUserAudio : true ) ) // Starlight-edit
348+ if ( ! _mind . TryGetMind ( aiEntity , out var mindId , out var mind ) )
326349 {
327350 return ;
328351 }
329352
353+ var name = _nameModifier . GetBaseName ( aiEntity ) ;
354+ _metadata . SetEntityName ( uid , name ) ;
355+ _metadata . SetEntityName ( borgMind , name ) ;
356+ _mind . TransferTo ( mindId , uid , ghostCheckOverride : true , mind : mind ) ;
357+ Del ( aiEntity ) ;
330358 args . Handled = true ;
359+ return ;
331360 }
332- // Starlight-start: borgs can be downloaded/uploaded
333- else if ( isBorg && borgHaveMind && targetHolder . Slot . ContainerSlot != null )
361+ else if ( targetHolder != null && isBorg && borgHaveMind && targetHolder . Slot . ContainerSlot != null )
334362 {
335- var brain = SpawnInContainerOrDrop ( DefaultAi , args . Args . Target . Value , targetHolder . Slot . ContainerSlot . ID ) ;
336- _mind . ControlMob ( uid , brain ) ;
363+ var brain = SpawnInContainerOrDrop ( DefaultAi , target , targetHolder . Slot . ContainerSlot . ID ) ;
364+ if ( ! _mind . TryGetMind ( borgMind , out var mindId , out var mind ) )
365+ return ;
366+ var name = _nameModifier . GetBaseName ( borgMind ) ;
367+ _metadata . SetEntityName ( brain , name ) ;
368+ _metadata . SetEntityName ( target , name ) ;
369+ _mind . TransferTo ( mindId , brain , ghostCheckOverride : true , mind : mind ) ;
370+ ResetNameToPrototype ( uid ) ;
337371 }
338372 // Starlight-end
339373 }
340374
375+ // Starlight: wipe the name of the entity to the prototype name, used for entities when they are downloaded/uploaded
376+ private void ResetNameToPrototype ( EntityUid entity )
377+ {
378+ if ( MetaData ( entity ) . EntityPrototype is { } prototype )
379+ _metadata . SetEntityName ( entity , prototype . Name ) ;
380+ }
381+
341382 private void OnHolderInteract ( Entity < StationAiHolderComponent > ent , ref AfterInteractEvent args )
342383 {
343384 if ( args . Handled || ! args . CanReach || args . Target == null )
@@ -359,9 +400,22 @@ private void OnHolderInteract(Entity<StationAiHolderComponent> ent, ref AfterInt
359400
360401 // Starlight-start: Downloadable borgs
361402
362- var isBorg = HasComp < BorgBrainComponent > ( args . Target . Value ) ;
363- var isShunted = TryComp < StationAIShuntComponent > ( args . Target . Value , out var shunt ) && shunt . Return != null ;
364- var borgHaveMind = TryComp < MindContainerComponent > ( args . Target . Value , out var mindContainer ) && mindContainer . HasMind ;
403+ var borgTarget = args . Target . Value ;
404+ var borgMindTarget = borgTarget ; // Starlight-edit
405+ if ( TryComp < BorgChassisComponent > ( borgTarget , out var chassis ) && chassis . BrainEntity is { } chassisBrain )
406+ borgTarget = chassisBrain ;
407+
408+ var isBorg = HasComp < BorgBrainComponent > ( borgTarget ) ;
409+ var isShunted = TryComp < StationAIShuntComponent > ( borgTarget , out var shunt ) && shunt . Return != null ;
410+ var borgHaveMind = TryComp < MindContainerComponent > ( borgMindTarget , out var mindContainer ) && mindContainer . HasMind ; // Starlight-edit
411+
412+ if ( targetHolder == null && ! isBorg )
413+ {
414+ var message = cardHasAi ? "intellicard-cannot-transfer-to" : "intellicard-core-empty" ;
415+ _popup . PopupClient ( Loc . GetString ( message ) , args . User , args . User , PopupType . Medium ) ;
416+ args . Handled = true ;
417+ return ;
418+ }
365419
366420 // Starlight-end
367421
@@ -399,7 +453,11 @@ private void OnHolderInteract(Entity<StationAiHolderComponent> ent, ref AfterInt
399453 }
400454 // Starlight-end
401455
402- var doAfterArgs = new DoAfterArgs ( EntityManager , args . User , cardHasAi ? intelliComp . UploadTime : intelliComp . DownloadTime , new IntellicardDoAfterEvent ( ) , args . Target , ent . Owner )
456+ var doAfterTarget = args . Target . Value ;
457+ if ( TryComp < BorgChassisComponent > ( doAfterTarget , out var doAfterChassis ) && doAfterChassis . BrainEntity is { } doAfterBrain )
458+ doAfterTarget = doAfterBrain ;
459+
460+ var doAfterArgs = new DoAfterArgs ( EntityManager , args . User , cardHasAi ? intelliComp . UploadTime : intelliComp . DownloadTime , new IntellicardDoAfterEvent ( ) , doAfterTarget , ent . Owner )
403461 {
404462 BreakOnDamage = true ,
405463 BreakOnMove = true ,
@@ -433,7 +491,7 @@ private void OnHolderConInsert(Entity<StationAiHolderComponent> ent, ref EntInse
433491 UpdateAppearance ( ( ent . Owner , ent . Comp ) ) ;
434492
435493 if ( ent . Comp . RenameOnInsert )
436- _metadata . SetEntityName ( ent . Owner , MetaData ( args . Entity ) . EntityName ) ;
494+ _metadata . SetEntityName ( ent . Owner , _nameModifier . GetBaseName ( args . Entity ) ) ; // Starlight-edit
437495 }
438496
439497 private void OnHolderConRemove ( Entity < StationAiHolderComponent > ent , ref EntRemovedFromContainerMessage args )
0 commit comments