@@ -143,6 +143,8 @@ public static void TrackActor(ReferenceHub h)
143143 public static void StartRecord ( ReferenceHub h )
144144 {
145145 StopRecord ( ) ;
146+ int fps = global ::Causality0 . Causality0 . Instance ? . Config ? . DefaultRecordFps ?? 60 ;
147+ CurrentFps = Mathf . Clamp ( fps , 1 , 240 ) ;
146148 MapSeed = MapGeneration . SeedSynchronizer . Seed ;
147149 RecordStartTime = Time . time ;
148150 RecFrame = 0 ;
@@ -524,6 +526,61 @@ private static bool TryGetLockerChamber(Vector3 p, byte id, out LockerChamber c)
524526 return false ;
525527 }
526528
529+ private static void MarkLockerFilled ( Locker lk )
530+ {
531+ if ( lk ? . Base == null )
532+ {
533+ return ;
534+ }
535+
536+ var f = typeof ( MapGeneration . Distributors . Locker ) . GetField ( "_serverChambersFilled" , System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic ) ;
537+ if ( f != null )
538+ {
539+ f . SetValue ( lk . Base , true ) ;
540+ }
541+ }
542+
543+ private static void SyncMicroPedestal ( Locker lk )
544+ {
545+ if ( lk ? . Base is not InventorySystem . Items . MicroHID . MicroHIDPedestal mp || lk . Chambers . Count < 1 )
546+ {
547+ return ;
548+ }
549+
550+ InventorySystem . Items . MicroHID . MicroHIDPickup p = null ;
551+ for ( int i = 0 ; i < lk . Chambers [ 0 ] . Base . Content . Count ; i ++ )
552+ {
553+ if ( lk . Chambers [ 0 ] . Base . Content [ i ] is InventorySystem . Items . MicroHID . MicroHIDPickup x )
554+ {
555+ p = x ;
556+ break ;
557+ }
558+ }
559+
560+ var tf = typeof ( InventorySystem . Items . MicroHID . MicroHIDPedestal ) . GetField ( "_trackedPickup" , System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic ) ;
561+ var ff = typeof ( InventorySystem . Items . MicroHID . MicroHIDPedestal ) . GetField ( "_isTrackingPickup" , System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic ) ;
562+ var hf = typeof ( InventorySystem . Items . MicroHID . MicroHIDPedestal ) . GetField ( "_hasHidDoorOpened" , System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic ) ;
563+ tf ? . SetValue ( mp , p != null ? p . transform : null ) ;
564+ ff ? . SetValue ( mp , p != null ) ;
565+ hf ? . SetValue ( mp , false ) ;
566+ if ( p == null )
567+ {
568+ return ;
569+ }
570+
571+ var m = typeof ( InventorySystem . Items . MicroHID . MicroHIDPedestal ) . GetMethod ( "ReleaseConnectionWithPickup" , System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic ) ;
572+ if ( m == null )
573+ {
574+ return ;
575+ }
576+
577+ var cb = ( System . Action ) System . Delegate . CreateDelegate ( typeof ( System . Action ) , mp , m , false ) ;
578+ if ( cb != null )
579+ {
580+ p . OnSelfDestroyed += cb ;
581+ }
582+ }
583+
527584 private static Pickup SpawnWorldPickup ( PickupData x )
528585 {
529586 Pickup p = Pickup . Create ( x . ItemType , x . Pos , x . Rot ) ;
@@ -539,29 +596,61 @@ private static Pickup SpawnWorldPickup(PickupData x)
539596
540597 private static Pickup SpawnLockerPickup ( LockerChamber c , PickupData x , int idx , bool v )
541598 {
542- c . Base . GetSpawnpoint ( x . ItemType , idx , out Vector3 p0 , out Quaternion r0 , out Transform t0 ) ;
543- Pickup p = Pickup . Create ( x . ItemType , p0 , r0 ) ;
544- if ( p == null )
599+ Pickup p = null ;
600+ try
545601 {
546- return null ;
547- }
602+ object [ ] a = { x . ItemType , idx , null , null , null } ;
603+ var m = c . Base . GetType ( ) . GetMethod ( "GetSpawnpoint" , System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . Public | System . Reflection . BindingFlags . NonPublic , null , new [ ] { typeof ( ItemType ) , typeof ( int ) , typeof ( Vector3 ) . MakeByRefType ( ) , typeof ( Quaternion ) . MakeByRefType ( ) , typeof ( Transform ) . MakeByRefType ( ) } , null ) ;
604+ if ( m != null && InventoryItemLoader . AvailableItems . TryGetValue ( x . ItemType , out ItemBase it ) )
605+ {
606+ m . Invoke ( c . Base , a ) ;
607+ if ( a [ 2 ] is Vector3 p0 && a [ 3 ] is Quaternion r0 && a [ 4 ] is Transform t0 && t0 != null )
608+ {
609+ ItemPickupBase b = Object . Instantiate ( it . PickupDropModel , p0 , r0 ) ;
610+ if ( b != null )
611+ {
612+ b . transform . SetParent ( t0 ) ;
613+ b . NetworkInfo = new PickupSyncInfo ( x . ItemType , it . Weight , 0 , locked : true ) ;
614+ c . Base . Content . Add ( b ) ;
615+ if ( b is InventorySystem . Items . Pickups . IPickupDistributorTrigger trg )
616+ {
617+ trg . OnDistributed ( ) ;
618+ }
548619
549- p . Transform . SetParent ( t0 ) ;
550- p . Position = x . Pos ;
551- p . Rotation = x . Rot ;
552- c . Base . Content . Add ( p . Base ) ;
553- if ( p . Base is InventorySystem . Items . Pickups . IPickupDistributorTrigger trg )
554- {
555- trg . OnDistributed ( ) ;
556- }
620+ if ( b . TryGetComponent < Rigidbody > ( out var rb ) )
621+ {
622+ rb . isKinematic = true ;
623+ rb . transform . ResetLocalPose ( ) ;
624+ MapGeneration . Distributors . SpawnablesDistributorBase . BodiesToUnfreeze . Add ( rb ) ;
625+ }
557626
558- if ( c . Base . SpawnOnFirstChamberOpening && ! v )
627+ p = Pickup . Get ( b ) ;
628+ if ( p != null )
629+ {
630+ if ( c . Base . SpawnOnFirstChamberOpening && ! v )
631+ {
632+ c . Base . ToBeSpawned . Add ( b ) ;
633+ }
634+ else
635+ {
636+ MapGeneration . Distributors . ItemDistributor . SpawnPickup ( b ) ;
637+ }
638+ }
639+ }
640+ }
641+ }
642+ }
643+ catch
559644 {
560- c . Base . ToBeSpawned . Add ( p . Base ) ;
561645 }
562- else
646+
647+ if ( p == null )
563648 {
564- p . Spawn ( ) ;
649+ p = c . AddItem ( x . ItemType ) ;
650+ if ( p == null )
651+ {
652+ return null ;
653+ }
565654 }
566655
567656 ApplyPickupData ( p , x ) ;
@@ -680,6 +769,12 @@ public static void ApplyWorldState()
680769 c . IsOpen = x . Open ;
681770 }
682771
772+ foreach ( Locker lk in Locker . List )
773+ {
774+ MarkLockerFilled ( lk ) ;
775+ SyncMicroPedestal ( lk ) ;
776+ }
777+
683778 for ( int i = 0 ; i < WorldPickups . Count ; i ++ )
684779 {
685780 Pickup p = SpawnWorldPickup ( WorldPickups [ i ] ) ;
@@ -1041,12 +1136,12 @@ private static void ReplayInteract(InteractFrame x)
10411136 }
10421137 }
10431138
1044- if ( ! Tracks . TryGetValue ( x . PlayerId , out var t ) || t . Dummy == null )
1139+ if ( ! x . CanOpen )
10451140 {
10461141 return ;
10471142 }
10481143
1049- d . ServerInteract ( t . Dummy , 0 ) ;
1144+ d . NetworkTargetState = ! d . TargetState ;
10501145 }
10511146
10521147 public static void TrackProjectile ( ThrownProjectile p , ItemType t , ReferenceHub h )
@@ -1381,6 +1476,18 @@ private static IEnumerator<float> RunPlay()
13811476 live = true ;
13821477 }
13831478
1479+ while ( d < Interacts . Count && Interacts [ d ] . Timestamp <= e )
1480+ {
1481+ ReplayInteract ( Interacts [ d ] ) ;
1482+ d ++ ;
1483+ live = true ;
1484+ }
1485+
1486+ if ( d < Interacts . Count )
1487+ {
1488+ live = true ;
1489+ }
1490+
13841491 foreach ( ActorTrack t in Tracks . Values )
13851492 {
13861493 int sf = t . StartFrame < 0 ? 0 : t . StartFrame ;
@@ -1589,18 +1696,6 @@ private static IEnumerator<float> RunPlay()
15891696 live = true ;
15901697 }
15911698
1592- while ( d < Interacts . Count && Interacts [ d ] . Timestamp <= e )
1593- {
1594- ReplayInteract ( Interacts [ d ] ) ;
1595- d ++ ;
1596- live = true ;
1597- }
1598-
1599- if ( d < Interacts . Count )
1600- {
1601- live = true ;
1602- }
1603-
16041699 if ( ! live )
16051700 {
16061701 yield break ;
0 commit comments