@@ -44,7 +44,10 @@ public sealed class ShockOsc
44
44
"CooldownPercentage" ,
45
45
"IShock" ,
46
46
"IVibrate" ,
47
- "ISound"
47
+ "ISound" ,
48
+ "CShock" ,
49
+ "NextIntensity" ,
50
+ "NextDuration" ,
48
51
} ;
49
52
50
53
public readonly Dictionary < string , object ? > ShockOscParams = new ( ) ;
@@ -302,6 +305,50 @@ private async Task ReceiveLogic()
302
305
var value = received . Arguments . ElementAtOrDefault ( 0 ) ;
303
306
switch ( action )
304
307
{
308
+ case "NextIntensity" :
309
+ if ( value is not float nextIntensity )
310
+ {
311
+ programGroup . NextIntensity = 0 ;
312
+ return ;
313
+ }
314
+
315
+ programGroup . NextIntensity = Convert . ToByte ( MathUtils . Saturate ( nextIntensity ) * 100f ) ;
316
+ break ;
317
+
318
+ case "NextDuration" :
319
+ if ( value is not float nextDuration )
320
+ {
321
+ programGroup . NextDuration = 0 ;
322
+ return ;
323
+ }
324
+
325
+ programGroup . NextDuration = nextDuration ;
326
+ break ;
327
+
328
+ case "CShock" :
329
+ if ( value is not float intensity )
330
+ {
331
+ programGroup . ConcurrentIntensity = 0 ;
332
+ programGroup . ConcurrentType = ControlType . Stop ;
333
+ return ;
334
+ }
335
+
336
+ var scaledIntensity = intensity * 100f ;
337
+ if ( scaledIntensity > 127 ) break ;
338
+
339
+ programGroup . ConcurrentIntensity = Convert . ToByte ( intensity * 100f ) ;
340
+
341
+ var ctype = action switch
342
+ {
343
+ "CShock" => ControlType . Shock ,
344
+ "CVibrate" => ControlType . Vibrate ,
345
+ "CSound" => ControlType . Sound ,
346
+ _ => ControlType . Vibrate
347
+ } ;
348
+
349
+ programGroup . ConcurrentType = ctype ;
350
+ break ;
351
+
305
352
case "IShock" :
306
353
case "IVibrate" :
307
354
case "ISound" :
@@ -413,26 +460,30 @@ private async Task SenderLoopAsync()
413
460
}
414
461
}
415
462
416
- private async Task InstantAction ( ProgramGroup programGroup , uint duration , byte intensity , ControlType type ,
463
+ private async Task InstantAction ( ProgramGroup programGroup , ushort duration , byte intensity , ControlType type ,
417
464
bool exclusive = false )
418
465
{
466
+ // Intensity is pre scaled to 0 - 100
467
+ var actualIntensity = programGroup . NextIntensity == 0 ? intensity : programGroup . NextIntensity ;
468
+ var actualDuration = programGroup . NextDuration == 0 ? duration : GetScaledDuration ( programGroup , programGroup . NextDuration ) ;
469
+
419
470
if ( type == ControlType . Shock )
420
471
{
421
472
programGroup . LastExecuted = DateTime . UtcNow ;
422
- programGroup . LastDuration = duration ;
423
- programGroup . LastIntensity = intensity ;
473
+ programGroup . LastDuration = actualDuration ;
474
+ programGroup . LastIntensity = actualIntensity ;
424
475
_oscHandler . ForceUnmute ( ) ;
425
476
_oscHandler . SendParams ( ) ;
426
477
}
427
478
428
479
programGroup . TriggerMethod = TriggerMethod . None ;
429
- var inSeconds = MathF . Round ( duration / 1000f , 1 ) . ToString ( CultureInfo . InvariantCulture ) ;
480
+ var inSeconds = MathF . Round ( actualDuration / 1000f , 1 ) . ToString ( CultureInfo . InvariantCulture ) ;
430
481
_logger . LogInformation (
431
482
"Sending {Type} to {GroupName} Intensity: {Intensity} Length:{Length}s Exclusive: {Exclusive}" , type ,
432
- programGroup . Name , intensity , inSeconds , exclusive ) ;
483
+ programGroup . Name , actualIntensity , inSeconds , exclusive ) ;
433
484
434
- await _backendHubManager . ControlGroup ( programGroup . Id , duration , intensity , type , exclusive ) ;
435
- await _chatboxService . SendLocalControlMessage ( programGroup . Name , intensity , duration , type ) ;
485
+ await _backendHubManager . ControlGroup ( programGroup . Id , actualDuration , actualIntensity , type , exclusive ) ;
486
+ await _chatboxService . SendLocalControlMessage ( programGroup . Name , actualIntensity , actualDuration , type ) ;
436
487
}
437
488
438
489
private async Task CheckLoop ( )
@@ -463,6 +514,20 @@ private async Task CheckLogic()
463
514
464
515
private async Task CheckProgramGroup ( ProgramGroup programGroup , Guid pos , BehaviourConf config )
465
516
{
517
+ if ( programGroup . ConcurrentIntensity != 0 )
518
+ {
519
+ _liveControlManager . ControlGroupFrameCheckLoop ( programGroup , GetScaledIntensity ( programGroup , programGroup . ConcurrentIntensity ) , programGroup . ConcurrentType ) ;
520
+ programGroup . LastConcurrentIntensity = programGroup . ConcurrentIntensity ;
521
+ return ;
522
+ }
523
+
524
+ if ( programGroup . LastConcurrentIntensity != 0 )
525
+ {
526
+ _liveControlManager . ControlGroupFrameCheckLoop ( programGroup , 0 , ControlType . Stop ) ;
527
+ programGroup . LastConcurrentIntensity = 0 ;
528
+ _logger . LogInformation ( "Stopping" ) ;
529
+ }
530
+
466
531
var cooldownTime = _configManager . Config . Behaviour . CooldownTime ;
467
532
if ( programGroup . ConfigGroup is { OverrideCooldownTime : true } )
468
533
cooldownTime = programGroup . ConfigGroup . CooldownTime ;
@@ -483,7 +548,9 @@ private async Task CheckProgramGroup(ProgramGroup programGroup, Guid pos, Behavi
483
548
484
549
_logger . LogDebug ( "Vibrating/Shocking {Shocker} at {Intensity}" , pos , pullIntensityTranslated ) ;
485
550
486
- _liveControlManager . ControlGroupFramePhysbonePull ( programGroup , pullIntensityTranslated ) ;
551
+ _liveControlManager . ControlGroupFrameCheckLoop ( programGroup , pullIntensityTranslated , _configManager . Config . Behaviour . WhileBoneHeld == BehaviourConf . BoneHeldAction . Shock
552
+ ? ControlType . Shock
553
+ : ControlType . Vibrate ) ;
487
554
}
488
555
489
556
if ( programGroup . TriggerMethod == TriggerMethod . None )
@@ -528,6 +595,50 @@ private async Task CheckProgramGroup(ProgramGroup programGroup, Guid pos, Behavi
528
595
529
596
InstantAction ( programGroup , GetDuration ( programGroup ) , intensity , ControlType . Shock , exclusive ) ;
530
597
}
598
+
599
+ private ushort GetScaledDuration ( ProgramGroup programGroup , float scale )
600
+ {
601
+ scale = MathUtils . Saturate ( scale ) ;
602
+
603
+ if ( programGroup . ConfigGroup is not { OverrideDuration : true } )
604
+ {
605
+ // Use global config
606
+ var config = _configManager . Config . Behaviour ;
607
+
608
+ if ( ! config . RandomDuration ) return ( ushort ) ( config . FixedDuration * scale ) ;
609
+ var rdr = config . DurationRange ;
610
+ return ( ushort )
611
+ ( MathUtils . LerpUShort (
612
+ ( ushort ) ( rdr . Min / DurationStep ) , ( ushort ) ( rdr . Max / DurationStep ) , scale )
613
+ * DurationStep ) ;
614
+ }
615
+
616
+ // Use group config
617
+ var groupConfig = programGroup . ConfigGroup ;
618
+
619
+ if ( ! groupConfig . RandomDuration ) return ( ushort ) ( groupConfig . FixedDuration * scale ) ;
620
+ var groupRdr = groupConfig . DurationRange ;
621
+ return ( ushort ) ( MathUtils . LerpUShort ( ( ushort ) ( groupRdr . Min / DurationStep ) ,
622
+ ( ushort ) ( groupRdr . Max / DurationStep ) , scale ) * DurationStep ) ;
623
+ }
624
+
625
+ private byte GetScaledIntensity ( ProgramGroup programGroup , byte intensity )
626
+ {
627
+ if ( programGroup . ConfigGroup is not { OverrideIntensity : true } )
628
+ {
629
+ // Use global config
630
+ var config = _configManager . Config . Behaviour ;
631
+
632
+ if ( ! config . RandomIntensity ) return ( byte ) MathUtils . LerpFloat ( 0 , config . FixedIntensity , intensity / 100f ) ;
633
+ return ( byte ) MathUtils . LerpFloat ( config . IntensityRange . Min , config . IntensityRange . Max , intensity / 100f ) ;
634
+ }
635
+
636
+ // Use group config
637
+ var groupConfig = programGroup . ConfigGroup ;
638
+
639
+ if ( ! groupConfig . RandomIntensity ) return ( byte ) MathUtils . LerpFloat ( 0 , groupConfig . FixedIntensity , intensity / 100f ) ;
640
+ return ( byte ) MathUtils . LerpFloat ( groupConfig . IntensityRange . Min , groupConfig . IntensityRange . Max , intensity / 100f ) ;
641
+ }
531
642
532
643
private byte GetPhysbonePullIntensity ( ProgramGroup programGroup , float stretch )
533
644
{
@@ -548,9 +659,9 @@ private byte GetPhysbonePullIntensity(ProgramGroup programGroup, float stretch)
548
659
return ( byte ) MathUtils . LerpFloat ( groupConfig . IntensityRange . Min , groupConfig . IntensityRange . Max , stretch ) ;
549
660
}
550
661
551
- private const uint DurationStep = 100 ;
662
+ private const ushort DurationStep = 100 ;
552
663
553
- private uint GetDuration ( ProgramGroup programGroup )
664
+ private ushort GetDuration ( ProgramGroup programGroup )
554
665
{
555
666
if ( programGroup . ConfigGroup is not { OverrideDuration : true } )
556
667
{
@@ -559,17 +670,17 @@ private uint GetDuration(ProgramGroup programGroup)
559
670
560
671
if ( ! config . RandomDuration ) return config . FixedDuration ;
561
672
var rdr = config . DurationRange ;
562
- return ( uint ) ( Random . Next ( ( int ) ( rdr . Min / DurationStep ) ,
563
- ( int ) ( rdr . Max / DurationStep ) ) * DurationStep ) ;
673
+ return ( ushort ) ( Random . Next ( rdr . Min / DurationStep ,
674
+ rdr . Max / DurationStep ) * DurationStep ) ;
564
675
}
565
676
566
677
// Use group config
567
678
var groupConfig = programGroup . ConfigGroup ;
568
679
569
680
if ( ! groupConfig . RandomDuration ) return groupConfig . FixedDuration ;
570
681
var groupRdr = groupConfig . DurationRange ;
571
- return ( uint ) ( Random . Next ( ( int ) ( groupRdr . Min / DurationStep ) ,
572
- ( int ) ( groupRdr . Max / DurationStep ) ) * DurationStep ) ;
682
+ return ( ushort ) ( Random . Next ( groupRdr . Min / DurationStep ,
683
+ groupRdr . Max / DurationStep ) * DurationStep ) ;
573
684
}
574
685
575
686
private byte GetIntensity ( ProgramGroup programGroup )
@@ -581,7 +692,7 @@ private byte GetIntensity(ProgramGroup programGroup)
581
692
582
693
if ( ! config . RandomIntensity ) return config . FixedIntensity ;
583
694
var rir = config . IntensityRange ;
584
- var intensityValue = Random . Next ( ( int ) rir . Min , ( int ) rir . Max ) ;
695
+ var intensityValue = Random . Next ( rir . Min , rir . Max ) ;
585
696
return ( byte ) intensityValue ;
586
697
}
587
698
@@ -590,7 +701,7 @@ private byte GetIntensity(ProgramGroup programGroup)
590
701
591
702
if ( ! groupConfig . RandomIntensity ) return groupConfig . FixedIntensity ;
592
703
var groupRir = groupConfig . IntensityRange ;
593
- var groupIntensityValue = Random . Next ( ( int ) groupRir . Min , ( int ) groupRir . Max ) ;
704
+ var groupIntensityValue = Random . Next ( groupRir . Min , groupRir . Max ) ;
594
705
return ( byte ) groupIntensityValue ;
595
706
}
596
707
}
0 commit comments