@@ -550,7 +550,18 @@ void CKeyBinds::RemoveDeletedBinds()
550
550
void CKeyBinds::ClearCommandsAndControls ()
551
551
{
552
552
const auto predicate = [](const KeyBindPtr& bind) {
553
- return !bind->isBeingDeleted && bind->type != KeyBindType::FUNCTION && bind->type != KeyBindType::CONTROL_FUNCTION;
553
+ if (bind->isBeingDeleted )
554
+ return false ;
555
+
556
+ if (bind->type == KeyBindType::COMMAND)
557
+ {
558
+ auto commandBind = static_cast <const CCommandBind*>(bind.get ());
559
+ // Only remove resource bindings, preserve user bindings
560
+ return commandBind->context == BindingContext::RESOURCE;
561
+ }
562
+
563
+ // Remove all control bindings (GTA_CONTROL)
564
+ return bind->type == KeyBindType::GTA_CONTROL;
554
565
};
555
566
RemoveBinds (m_binds, !m_bProcessingKeyStroke, predicate);
556
567
}
@@ -612,9 +623,11 @@ bool CKeyBinds::AddCommand(const char* szKey, const char* szCommand, const char*
612
623
CCommandBind* pUserAddedBind = FindCommandMatch (NULL , szCommand, szArguments, szResource, szKey, true , bState, true , false );
613
624
if (pUserAddedBind)
614
625
{
615
- // Upgrade
626
+ // Upgrade user binding to resource binding
616
627
pUserAddedBind->wasCreatedByScript = true ;
617
628
pUserAddedBind->isReplacingScriptKey = true ;
629
+ pUserAddedBind->context = BindingContext::RESOURCE;
630
+ pUserAddedBind->sourceResource = szResource;
618
631
assert (pUserAddedBind->originalScriptKey == szKey);
619
632
return true ;
620
633
}
@@ -631,13 +644,20 @@ bool CKeyBinds::AddCommand(const char* szKey, const char* szCommand, const char*
631
644
if (szResource)
632
645
{
633
646
bind->resource = szResource;
647
+ bind->sourceResource = szResource;
634
648
bind->wasCreatedByScript = bScriptCreated;
649
+ bind->context = BindingContext::RESOURCE;
635
650
636
651
if (bScriptCreated)
637
652
bind->originalScriptKey = szKey;
638
653
else if (szOriginalScriptKey)
639
654
bind->originalScriptKey = szOriginalScriptKey; // Will wait for script to addcommand before doing replace
640
655
}
656
+ else
657
+ {
658
+ // User-created binding (via /bind command)
659
+ bind->context = BindingContext::USER;
660
+ }
641
661
642
662
m_binds.emplace_back (bind.release ());
643
663
return true ;
@@ -2632,3 +2652,147 @@ bool CKeyBinds::TriggerKeyStrokeHandler(const SString& strKey, bool bState, bool
2632
2652
}
2633
2653
return true ;
2634
2654
}
2655
+
2656
+ bool CKeyBinds::CommandExistsInContext (const char * key, const char * command, BindingContext context, bool checkState, bool state, const char * arguments, const char * resource)
2657
+ {
2658
+ if (!key || !command)
2659
+ return false ;
2660
+
2661
+ for (const KeyBindPtr& bind : m_binds)
2662
+ {
2663
+ if (bind->isBeingDeleted || bind->type != KeyBindType::COMMAND)
2664
+ continue ;
2665
+
2666
+ auto commandBind = static_cast <const CCommandBind*>(bind.get ());
2667
+
2668
+ if (commandBind->context != context)
2669
+ continue ;
2670
+
2671
+ if (stricmp (commandBind->boundKey ->szKey , key) != 0 )
2672
+ continue ;
2673
+
2674
+ if (stricmp (commandBind->command .c_str (), command) != 0 )
2675
+ continue ;
2676
+
2677
+ if (checkState && commandBind->triggerState != state)
2678
+ continue ;
2679
+
2680
+ if (arguments && commandBind->arguments != arguments)
2681
+ continue ;
2682
+
2683
+ if (resource && commandBind->resource != resource)
2684
+ continue ;
2685
+
2686
+ return true ;
2687
+ }
2688
+
2689
+ return false ;
2690
+ }
2691
+
2692
+ bool CKeyBinds::RemoveCommandFromContext (const char * key, const char * command, BindingContext context, bool checkState, bool state, const char * arguments, const char * resource)
2693
+ {
2694
+ if (!key || !command)
2695
+ return false ;
2696
+
2697
+ const auto predicate = [&](const KeyBindPtr& bind) {
2698
+ if (bind->isBeingDeleted || bind->type != KeyBindType::COMMAND)
2699
+ return false ;
2700
+
2701
+ auto commandBind = static_cast <const CCommandBind*>(bind.get ());
2702
+
2703
+ if (commandBind->context != context)
2704
+ return false ;
2705
+
2706
+ if (stricmp (commandBind->boundKey ->szKey , key) != 0 )
2707
+ return false ;
2708
+
2709
+ if (stricmp (commandBind->command .c_str (), command) != 0 )
2710
+ return false ;
2711
+
2712
+ if (checkState && commandBind->triggerState != state)
2713
+ return false ;
2714
+
2715
+ if (arguments && commandBind->arguments != arguments)
2716
+ return false ;
2717
+
2718
+ if (resource && commandBind->resource != resource)
2719
+ return false ;
2720
+
2721
+ return true ;
2722
+ };
2723
+
2724
+ return RemoveBinds (m_binds, !m_bProcessingKeyStroke, predicate);
2725
+ }
2726
+
2727
+ bool CKeyBinds::HasAnyBindingForKey (const char * key, bool checkState, bool state)
2728
+ {
2729
+ if (!key)
2730
+ return false ;
2731
+
2732
+ for (const KeyBindPtr& bind : m_binds)
2733
+ {
2734
+ if (bind->isBeingDeleted )
2735
+ continue ;
2736
+
2737
+ if (bind->type == KeyBindType::COMMAND)
2738
+ {
2739
+ auto commandBind = static_cast <const CCommandBind*>(bind.get ());
2740
+ if (stricmp (commandBind->boundKey ->szKey , key) == 0 )
2741
+ {
2742
+ if (!checkState || commandBind->triggerState == state)
2743
+ return true ;
2744
+ }
2745
+ }
2746
+ else if (bind->type == KeyBindType::FUNCTION)
2747
+ {
2748
+ auto functionBind = static_cast <const CKeyFunctionBind*>(bind.get ());
2749
+ if (stricmp (functionBind->boundKey ->szKey , key) == 0 )
2750
+ {
2751
+ if (!checkState || functionBind->triggerState == state)
2752
+ return true ;
2753
+ }
2754
+ }
2755
+ else if (bind->type == KeyBindType::CONTROL_FUNCTION)
2756
+ {
2757
+ auto controlBind = static_cast <const CControlFunctionBind*>(bind.get ());
2758
+ if (stricmp (controlBind->boundKey ->szKey , key) == 0 )
2759
+ {
2760
+ if (!checkState || controlBind->triggerState == state)
2761
+ return true ;
2762
+ }
2763
+ }
2764
+ else if (bind->type == KeyBindType::GTA_CONTROL)
2765
+ {
2766
+ auto gtaBind = static_cast <const CGTAControlBind*>(bind.get ());
2767
+ if (stricmp (gtaBind->boundKey ->szKey , key) == 0 )
2768
+ return true ;
2769
+ }
2770
+ }
2771
+
2772
+ return false ;
2773
+ }
2774
+
2775
+ bool CKeyBinds::HasBindingInContext (const char * key, BindingContext context, bool checkState, bool state)
2776
+ {
2777
+ if (!key)
2778
+ return false ;
2779
+
2780
+ for (const KeyBindPtr& bind : m_binds)
2781
+ {
2782
+ if (bind->isBeingDeleted || bind->type != KeyBindType::COMMAND)
2783
+ continue ;
2784
+
2785
+ auto commandBind = static_cast <const CCommandBind*>(bind.get ());
2786
+
2787
+ if (commandBind->context != context)
2788
+ continue ;
2789
+
2790
+ if (stricmp (commandBind->boundKey ->szKey , key) != 0 )
2791
+ continue ;
2792
+
2793
+ if (!checkState || commandBind->triggerState == state)
2794
+ return true ;
2795
+ }
2796
+
2797
+ return false ;
2798
+ }
0 commit comments