Jump to content

need help getting mcm menu to work that binds a key chosen by player and allows alt, shift, and shift to be used


Recommended Posts

Found the youtube video that shows how to do this, but after two days figured out that some things were left out. I do not want to use states, unless i really have to.  here is my script so far, any help appreciated. The whole purpose is for the player to pick a hotkey bind, and then use it in game to toggle a global variable from 0 to 5, then 5 to 0m on key press.  This is for a mod I am almost done with that highlights enemies in red shader.  In game the menu look ok but keypresses never take place...

 

Link to comment
Share on other sites

yup.  just found that out.    posting revised script with more changes above.  I have F working so far in game, trying to get alt, shift and control to work:

 

edit: working!!!!!!!!  i can assign alt, shift, or control!!!!  yes!!  why don't more modders offer the combo?

 

This sample script does not exist on the web.  Took me 2 days to figure it out, after watching the only how to video on you tube for shift, alt, control.  And that video was incomplete.  

 

Scriptname FriendorFoeMCM extends SKI_ConfigBase

; Keymap Value

int AddKeyMapOptionST
int Property CastSpellKeycode = 33 Auto
bool RequireCtrlKey = True
 int KeyPressed = 29
bool RequireShiftKey = False
bool RequireAltKey = False
int AddToggleOptionCtrl
int AddToggleOptionAlt
int AddToggleOptionShift
int inputGOkey



int oid_KeyMapOption


 Event OnConfigInit()
 
 ModName = "Friend or Foe"
 Pages = new string [1]
 Pages[0] = "Settings"
 Registerforkey(CastSpellKeycode)
 
 
 EndEvent


Event OnKeyDown(Int KeyCode)

if KeyCode == CastSpellKeycode && Input.IsKeyPressed(KeyPressed) || KeyCode == CastSpellKeycode && KeyPressed == 0

if FoeToggle.GetValueInt() == 0

FoeToggle.SetValueInt(5)

else

FoeToggle.SetValueInt(0)

endIf


endIf


EndEvent
 
 
 Event OnPageReset(string page)
 
If (page == "Settings")



SetCursorFillMode(TOP_TO_BOTTOM)  ; we start menu on top
inputGOkey=AddKeyMapOption("ToggleEnemyIdentify", CastSpellKeycode)

AddToggleOptionCtrl = AddToggleOption("Ctrl", RequireCtrlKey)
AddToggleOptionAlt = AddToggleOption("Alt", RequireAltKey)
AddToggleOptionShift = AddToggleOption("Shift", RequireShiftKey)
 
 EndIf
 
 EndEvent
 

 
 
 
 event OnOptionKeyMapChange(int option,  int a_keyCode,  string a_conflictControl, string a_conflictName)
 
  bool continue = true
 
 if (a_conflictControl != "")
			string msg

			if (a_conflictName != "")
				msg = "This key is already mapped to:\n'" + a_conflictControl + "'\n(" + a_conflictName + ")\n\nAre you sure you want to continue?"
			else
				msg = "This key is already mapped to:\n'" + a_conflictControl + "'\n\nAre you sure you want to continue?"
			endIf

			continue = ShowMessage(msg, true, "$Yes", "$No")
		endIf
		
if (continue)

 ;
 UnregisterForKey(CastSpellKeycode)
 CastSpellKeycode = a_keyCode
 Registerforkey(CastSpellKeycode)
SetKeymapOptionValue(inputGOkey, a_keyCode)
ForcePageReset()
else
debug.Notification("failed")
endIf
 
 EndEvent
 
; Event OnHighlightST()
 
; SetInfoText("Keyboard key to toggle enemy highlighting - on and off")
 
 
; EndEvent

 

 
Event OnOptionSelect(Int a_option)    ; TOGGLE PROCESS SELECTION
 
 if a_option == AddToggleOptionCtrl
 RequireCtrlKey = !RequireCtrlKey 
 SetToggleOptionValueST(RequireCtrlKey)
 
 if RequireCtrlKey == true
 RequireAltKey = False
 RequireShiftKey = False
 KeyPressed = 29
 else
 KeyPressed = 0
 endIf
 
endIf




if a_option == AddToggleOptionAlt
 RequireAltKey = !RequireAltKey 
 SetToggleOptionValueST(RequireAltKey)

if RequireAltKey == true
RequireCtrlKey = False
RequireShiftKey = False
KeyPressed = 56
else
KeyPressed = 0
endIf


 endIf



 
 if a_option == AddToggleOptionShift
 RequireShiftKey = !RequireShiftKey 
 SetToggleOptionValueST(RequireShiftKey)
 if RequireShiftKey == true
 RequireCtrlKey = False
 RequireAltKey = False
 KeyPressed = 42
 else
 KeyPressed = 0
 endIf
 
 
 endIf



ForcePageReset()





EndEvent
 
 

 
 
 
 

 

 
 

 
 
 

 

 
 

 
 
 
 
 
 
 
 

 
 
 
 

 
GlobalVariable Property FoeToggle  Auto  

 

Link to comment
Share on other sites

only thing not working now is getting a new key to stick.   whatever i pick changes to m1

Link to comment
Share on other sites

Thanks gang!  Made changes posted and a few more for proper key assignment and it works now!   Mod is live now.  "Friend or Foe"  .  I replaced the script above with the newest working version in case others can benefit.

https://www.nexusmods.com/skyrimspecialedition/mods/124455/?tab=description

IsharaMeradinyou are amazing, you help so many people in this forum,  year after year.  A much better person than me by far, as well as much better scripter.  May I ask you a question?  I use states in my  bigger mods and I am comfortable with them, but in mcm scripting it does not seem to the same structure or requirements.  There seems to be no empty state, no setting of states, default states. Commands to change states.   How does it work with mcm ?  If you have a link to this subject i would happily read it.  Tried for along while and found nothing on the web.  

My daughter is having her first baby right now at the hospital, keeping my mind busy, I am a worrier.

Link to comment
Share on other sites

The following is the official documentation for the state method.  I still needed to examine an existing mod that used the state method.  Between the two, I figured things out. https://github.com/schlangster/skyui/wiki/MCM-State-Options

SkyUI does not expose the entirety of their source script(s) within the SkyUI SDK.  Only the bare minimum needed to ensure proper compilation is provided.  Thus, I cannot be certain, but it is safe to say that all of the state changes are taking place on one of SkyUI's other scripts.

Link to comment
Share on other sites

Not off the top of my head.  Though you are welcome to take a look at the MCM code in my Inventory Management Mod.  The SSE one uses the state method.  I think the LE version does too but it has been a while since I looked at that one.

Link to comment
Share on other sites

can I have a go))) let use the toggle state option

Self.AddToggleOptionST("TOGGLE_SHADER_FX", "$DQ3_UseShaderFXonPositioning", DQMain.bUseShaderFX)

above as both the Front End UI and the Back End business end  in it

it is a toggle button

It uses this State  >  "TOGGLE_SHADER_FX"

this the UI description  > "$DQ3_UseShaderFXonPositioning"

this is the value to set on or off depending on it value in the UI > DQMain.bUseShaderFX

when the gamer hit the toggle the MCM goes to THAT STATE

The appropriate event in the state then fires

State TOGGLE_SHADER_FX

	Event OnSelectST()
		DQMain.bUseShaderFX = !DQMain.bUseShaderFX
		Self.SetToggleOptionValueST(DQMain.bUseShaderFX)
	EndEvent
EndState

Then the business end of the mod allows Shader FX in the game 

@IsharaMeradin link is a wikki pages that explain how to write MCM configs both open and states, does not explain how it works under the hood.. 

I have never looked at the background working of SkyUI, to see how it works under the hood it will look like this

Spoiler


  /* PRIVATE FUNCTIONS */
  
	private function setState(a_state: Number): Void
	{
		switch (a_state) {
			case LIST_ACTIVE:
				modListFader.gotoAndStop("show");
				_modList.disableInput = false;
				_modList.disableSelection = false;
				var restored = _modList.listState.savedIndex;
				_modList.selectedIndex = (restored > -1) ? restored : 0;

				if (modListFader.getDepth() < subListFader.getDepth())
					modListFader.swapDepths(subListFader);
					
				dispatchEvent({type: "modListEnter"});
				break;
				
			case SUBLIST_ACTIVE:
				subListFader.gotoAndStop("show");
				_subList.disableInput = false;
				_subList.disableSelection = false;
				_subList.selectedIndex = -1;

				if (subListFader.getDepth() < modListFader.getDepth())
					subListFader.swapDepths(modListFader);

				decorTitle.onPress = function(): Void
				{
					if (!_parent.isDisabled)
						_parent.showList();
				};
				
				dispatchEvent({type: "subListEnter"});
				break;
				
			case TRANSITION_TO_SUBLIST:
				_titleText = _modList.selectedEntry.text;
				decorTitle._y = _modList.selectedClip._y;
				hideDecorTitle(false);
				decorTitle.gotoAndPlay("fadeIn");
				decorTitle.textHolder.textField.text = _titleText;
				modListFader.gotoAndPlay("fadeOut");

				_modList.listState.savedIndex = _modList.selectedIndex;
				_modList.disableInput = true;
				_modList.disableSelection = true;
				
				sublistIndicator._visible = false;
				
				dispatchEvent({type: "modListExit"});
				break;
				
			case TRANSITION_TO_LIST:
				decorTitle.gotoAndPlay("fadeOut");
				subListFader.gotoAndPlay("fadeOut");
				
				delete decorTitle.onPress;
				
				_subList.disableInput = true;
				_subList.disableSelection = true;
				
				dispatchEvent({type: "subListExit"});
				break;
				
			default:
				return;
		}
		
		_state = a_state;
	}

 

That real SkyUI code, and it not papyrus is it?

More examples of MCM configs... to learn how write them, so no need to check other mods

https://github.com/schlangster/skyui/wiki/MCM-Examples

BTW you do not need open states because you inherit them off the parent, all that you said is missing is there in plain sight, you just need to see..

https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)

https://en.wikipedia.org/wiki/State_pattern

https://en.wikipedia.org/wiki/Polymorphism_(computer_science)  another very important concept 

https://en.wikipedia.org/wiki/Interface_(computing) to help explain how it works

https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/Subsystems/  more to help explain

Best way to wrongly describe it is   https://github.com/schlangster/skyui is the sub-system, and papyrus is the interface, but I would take the software developer route, I do not care how it works, as long as I know how to use it.. FYI the papyrus bit

Study @IsharaMeradin link hard and long and take a superficial look at mine, you really do not want know how it works.. 

 https://github.com/schlangster/skyui the SkyUI code repository → do not look 😁😁😁 it is 100% there nothing is hidden, regarding the sub-system, but yeah the papyrus interface is somewhat protected in the SDK

but here it is so you do not need to decompile it 

https://github.com/schlangster/skyui/tree/master/dist/Data/Scripts/Source

careful what ask for cos you might get it))) 

Look at the MCM Config Base, can you see the events for the open states now, yes or no?

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...