//============================================================================= // KFGFxOptionsContainer_Keybinding //============================================================================= // Class Description //============================================================================= // Killing Floor 2 // Copyright (C) 2015 Tripwire Interactive LLC // Greg Felber - 9/10/2014 //============================================================================= class KFGFxControlsContainer_Keybinding extends KFGFxObject_Container config(UI); var KFGfxMoviePlayer_Manager Manager; /** Populated from DefaultUI.ini */ var config array MovementBindList; var config array CombatBindList; var config array WeaponSelectBindList; var config array InteractionBindList; var config array VoiceCommBindList; var KeyBind PendingKeyBind; var KeyBind OldKeyBind; /** The name of the command we are trying to bind */ var string BindCommand; var byte CurrentlySelectedSection; /** These are set true if ctrl, shift, or alt are being held down */ var bool bModCtrl; var bool bModShift; var bool bModAlt; var bool bWaitForInput; var const string SectionName; const MAX_SECTIONS = 5; var byte TotalBindSections; var localized array SectionHeaders; var localized string ResetString, ApplyString, KeyAlreadyBoundString, PressKeyString; var localized string WarningString, RebindString, ClearedString, CancelString, AcceptString, IgnoredKeyString; function Initialize( KFGFxObject_Menu NewParentMenu ) { local GFxObject LocalizedObject; super.Initialize( NewParentMenu ); Manager = NewParentMenu.Manager; LocalizedObject = CreateObject( "Object" ); LocalizedObject.SetString("resetLabel", ResetString); LocalizedObject.SetString("applyLabel", ApplyString); SetObject("localizedText", LocalizedObject); LocalizedObject = CreateObject( "Object" ); LocalizedObject.SetString("warningLabel", WarningString); LocalizedObject.SetString("rebindLabel", RebindString); LocalizedObject.SetString("clearedLabel", ClearedString); LocalizedObject.SetString("cancelLabel", CancelString); LocalizedObject.SetString("acceptLabel", AcceptString); SetObject("localizedPopup", LocalizedObject); InitalizeCommandList(MovementBindList); InitalizeCommandList(InteractionBindList); InitalizeCommandList(CombatBindList); InitalizeCommandList(WeaponSelectBindList); InitalizeCommandList(VoiceCommBindList); UpdateAllBindings(); } function InitalizeCommandList( out array BindList ) { local byte i; local GFxObject CommandSlot; local GFxObject DataProvider; if( TotalBindSections < MAX_SECTIONS ) { DataProvider = CreateArray(); DataProvider.SetInt("sectionIndex", TotalBindSections); DataProvider.SetString("bindingHeader", SectionHeaders[TotalBindSections]); DataProvider.SetString("pressKeyString", PressKeyString); for (i = 0; i < BindList.Length; i++) { CommandSlot = CreateObject( "Object" ); CommandSlot.SetString("label", Localize(SectionName, BindList[i], "KFGame")); DataProvider.SetElementObject(i, CommandSlot); } SetObject("commandList", DataProvider); TotalBindSections++; } } function UpdateAllBindings() { UpdateBindList( MovementBindList, 0 ); UpdateBindList( InteractionBindList, 1 ); UpdateBindList( CombatBindList, 2 ); UpdateBindList( WeaponSelectBindList, 3 ); UpdateBindList( VoiceCommBindList, 4 ); Manager.UpdateDynamicIgnoreKeys(); } /************************************************************************ * Binding *************************************************************************/ /** Populates the binding list */ function UpdateBindList( out array BindList, int SectionIndex ) { local byte i; local GFxObject DataProvider; local GFxObject BindSlot; local KeyBind MyKeyBind; local KFPlayerInput KFInput; if (GetPC() == None || KFPlayerInput(GetPC().PlayerInput) == none) { return; } DataProvider = CreateArray(); KFInput = KFPlayerInput(GetPC().PlayerInput); for (i = 0; i < BindList.Length; i++) { BindSlot = CreateObject("Object"); KFInput.GetKeyBindFromCommand(MyKeyBind, BindList[i], false); BindSlot.SetString("command", BindList[i]); if (MyKeyBind.Name != 'None') { BindSlot.SetString("label", KFInput.GetBindDisplayName(MyKeyBind)); } else { BindSlot.SetString("label", ""); } DataProvider.SetElementObject(i, BindSlot); } SetSectionBindings( SectionIndex, DataProvider ); } function SetSectionBindings( int i, GFxObject bindData ) { ActionscriptVoid("setSectionBindings"); } /** Wait for player input to modify the current bind command */ function ChangeBind( string ChangedCommand, byte SelectedSection ) { BindCommand = ChangedCommand; CurrentlySelectedSection = SelectedSection; bWaitForInput = true; } /** Receives the key we want to bind for a particular command and adds any modifiers (ctrl, shift ) */ function BindKey( name KeyPressed, EInputEvent EventType) { local KeyBind NewKeyBind; if ( !bWaitForInput ) { return; } NewKeyBind.Name = KeyPressed; if (EventType == EInputEvent.IE_Pressed) { // If Ctrl, shift, or alt are pressed wait for a second input to modify the binding UpdateModKeys(KeyPressed, EventType); } // If we release a mod key before pressing anything else if (EventType == EInputEvent.IE_Released) { // If Ctrl, shift, or alt are pressed wait for a second input to modify the binding UpdateModKeys(KeyPressed, EventType); NewKeyBind.Control = bModCtrl; NewKeyBind.Shift = bModShift; NewKeyBind.Alt = bModAlt; bWaitForInput = false; SetKeyBind( NewKeyBind ); ResetModKeys(); } //reset ignores Manager.ClearFocusIgnoreKeys(); } function UpdateModKeys(name KeyPressed, EInputEvent EventType) { switch (KeyPressed) { case 'LeftControl': ResetModKeys(); bModCtrl = EventType == EInputEvent.IE_Pressed; break; case 'LeftShift': ResetModKeys(); bModShift = EventType == EInputEvent.IE_Pressed; break; case 'LeftAlt': ResetModKeys(); bModAlt = EventType == EInputEvent.IE_Pressed; break; } } function ResetModKeys() { bModCtrl = false; bModShift = false; bModAlt = false; } function SetKeyBind(KeyBind NewKeyBind) { local KFPlayerInput KFInput; local string OldKeyCommand; if ( GetPC() == None || KFPlayerInput(GetPC().PlayerInput) == none ) { return; } //The escape key does not have a gba. We want it to be a constant command. Esc cancels bind. if(NewKeyBind.name == 'Escape') { UpdateAllBindings(); return; } //prevent loss of mouse click or controller selection if( (NewKeyBind.name == 'XboxTypeS_A' || NewKeyBind.name == 'LeftMouseButton') && Manager.IsFocusIgnoreKey(BindCommand)) { //reject and show pop up Manager.DelayedOpenPopup(ENotification, EDPPID_Misc, default.WarningString, NewKeyBind.name @default.IgnoredKeyString, class'KFCommon_LocalizedStrings'.default.OKString); UpdateAllBindings(); return; } KFInput = KFPlayerInput( GetPC().PlayerInput ); OldKeyCommand = KFInput.GetGameBindableAction( NewKeyBind.Name ); // If this key is already bound, create a popup to confirm we want to switch if ( NewKeyBind.Name != 'Delete' && OldKeyCommand != "" && OldKeyCommand != BindCommand ) { PendingKeyBind = NewKeyBind; OldKeyBind.Command = OldKeyCommand; OldKeyBind.Name = 'Delete'; SetConflictMessage( string(NewKeyBind.Name), OldKeyCommand, BindCommand, CurrentlySelectedSection ); } else { KFInput.BindKey( NewKeyBind, BindCommand, false ); UpdateAllBindings(); } } function SetConflictMessage( String KeyString, String OldCommand, String NewCommand, byte SelectedSection ) { KeyString = Repl(KeyAlreadyBoundString, "%x%", KeyString, true); OldCommand = Localize(SectionName, OldCommand, "KFGame"); NewCommand = Localize(SectionName, NewCommand, "KFGame"); ActionscriptVoid("setConflictMessage"); } function AcceptBind() { KFPlayerInput( GetPC().PlayerInput ).BindKey( OldKeyBind, OldKeyBind.Command, false ); KFPlayerInput( GetPC().PlayerInput ).BindKey( PendingKeyBind, BindCommand, false ); UpdateAllBindings(); } function ResetControls() { if (GetPC() != None && GetPC().PlayerInput != None) { KFPlayerInput(GetPC().PlayerInput).ResetKeysToDefault(); UpdateAllBindings(); } } function ClearInputOnContainer() { UpdateAllBindings(); bWaitForInput = false; } DefaultProperties { SectionName="LocalizedControls" }