(I have stumbled and mumbled through jtbalogh's AutoHotKey logic for several days, now. And then I finally got lucky with the start of something that some might want to play-test, hopefully?)
I am using T3 standards, pretty much, with Run as the normal default.
But some of the normal keys, in my options.ini, are set to "None".
While some other slightly hidden NumPad ones are being used, now.
(And I never need to use those NumPad keys, BTW.) 
Code:
Shift=None
Ctrl=None
Alt=None
NumPad1=Walk
NumPad2=Creep
NumPad3=Crouch
My T3-Shift_Ctrl_Toggles.ahk, for AutoHotKey, from jtbalogh's logic.
(BTW, I used double Sends to help guarantee a key's change.)
Code:
#SingleInstance force ;force a single instance
#HotkeyInterval 0 ;disable the warning dialog if a key is held down
#MaxHotkeysPerInterval 500 ;help respond to mouse
#MaxThreads 20 ;use 20 (the max) instead of 10 threads
#InstallKeybdHook ;forces the unconditional installation of the keyboard hook
#UseHook On ;not interfere with numpad, and increase responsiveness
SetBatchLines, -1 ;makes the script run at max speed
SetKeyDelay, -1, -1 ;fastest response (might be better with -1, 0)
SetMouseDelay, -1
SetWinDelay, -1
mMoveRun := 0
mMoveWalk := 1
mMoveCreep := 1
mMoveMax = 1
isShift := False
mMoveState1 := 0
isCtrl := False
mMoveState2 := 0
; reset stuck keys
Send, {NumPad1 up}
Send, {NumPad2 up}
Send, {NumPad3 up}
return
ExitSub:
ExitApp ;The only way for an OnExit script to terminate itself is to use ExitApp
#ifWinActive, Thief - Deadly Shadows ; name of game in taskbar
Shift::
if (isShift == False) {
isShift := True ; run once
mMoveState1 := mMoveState1 + 1
if (mMoveState1 > mMoveMax)
mMoveState1 := 0
if (mMoveState1 == mMoveRun) {
Send, {NumPad1 up}{NumPad1 up} ; releasing walk
} else if (mMoveState1 == mMoveWalk) {
Send, {NumPad1 down}{NumPad1 down} ; holding walk
Send, {NumPad2 up}{NumPad2 up} ; releasing creep
mMoveState2 := 0
}
}
Shift up::
isShift := False ; reset
return
Ctrl::
if (isCtrl == False) {
isCtrl := True ; run once
mMoveState2 := mMoveState2 + 1
if (mMoveState2 > mMoveMax)
mMoveState2 := 0
if (mMoveState2 == mMoveRun) {
Send, {NumPad2 up}{NumPad2 up} ; releasing creep
} else if (mMoveState2 == mMoveCreep) {
Send, {NumPad2 down}{NumPad2 down} ; holding creep
Send, {NumPad1 up}{NumPad1 up} ; releasing walk
mMoveState1 := 0
}
}
Ctrl up::
isCtrl := False ; reset
return
Alt::
Send, {NumPad1 up}{NumPad1 up} ; releasing walk
mMoveState1 := 0
Send, {NumPad2 up}{NumPad2 up} ; releasing creep
mMoveState2 := 0
Send, {NumPad3 down}{NumPad3 down}{NumPad3 up}{NumPad3 up} ; toggle crouch
return
Also you might notice, during your gameplay, that Crouch resets my Walk or Creep back to a normal Run mode. (But you can still use my Walk or Creep, with Crouch, if you want much slower crouching movements.) You can switch between Walk and Creep rather freely. But pressing Walk or Creep, twice in a row, will return you back to Run mode, just like a normal toggle-key should react.
Jumping will get you out of a normal Crouch, but not with the Walk or Creep modes included while crouching. Plus carrying anything seems to do the very same thing.
So, now, I need an opinion about these play-oriented situations with jumping or carrying and about my rather shabby AutoHotKey logic, of course.
Thanks! 
... Jim ...