TABname Completion
TABname Completion mimics that uncommonly-known mIRC command that fills in a person's name, depending on what text they enter (when you press the TAB key).
This code is/will be in a version of Esc sometime soon – I have placed this in my UTConsole class, in the 'Typing' state, under the 'KeyEvent' function. When entering part of any Player's name (case-sensitive), it will complete the Player's name.
To Do
- Thanks to Mychaeel's code, it now cycles through similar names. And it works perfectly - no-one prove me wrong.
Implementation
The following implementation in UnrealScript has been created by DJPaul and Mychaeel for the Esc mod. Feel free to use and modify.
state Typing { //Process 'String' from right-to-left, looking for the first 'LookFor'. function int FindRightMost(string String, string LookFor) { local int i; for (i=len(String)-1; i>=0; i--) { if ( mid(String, i, 1) == LookFor ) { return i+1; } } //Rogue-value. return 667; } event bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta ) { local string TextNameCompletedFirst, TextNameCompletedSuccessor; local string ThisPlayerName; //To cut down on long statements below. local int RightSpace, i; if (Action!=IST_Press) return false; if ((Key == IK_Tab) && (Viewport.Actor != none)) { // String comparisons (equality, alphabetical order) shall be case-insensitive. // Use ~= for equality and Caps() for alphabetical order in UnrealScript. RightSpace = FindRightMost(TypedStr, " "); if (RightSpace == 667) return false; if (TextNamePrefix == "") { TextNamePrefix = Right(TypedStr, len(TypedStr)-RightSpace); TextNameCompletedPrev = ""; } if (Viewport.Actor.GameReplicationInfo != none) { for (i=0; i<32; i++) { if (Viewport.Actor.GameReplicationInfo.PRIArray[i] != none) { ThisPlayerName = Viewport.Actor.GameReplicationInfo.PRIArray[i].PlayerName; if (left(ThisPlayerName, len(TextNamePrefix)) == TextNamePrefix) { // Save the first matching player name in alphabetical order in case we don't // find an alphabetical successor of TextNameCompletedPrev. if ((TextNameCompletedFirst == "") || (ThisPlayerName < TextNameCompletedFirst)) TextNameCompletedFirst = ThisPlayerName; if (TextNameCompletedPrev != "") { // Save the player name we're looking at if it is one of TextNameCompletedPrev's // alphabetical successors (and a better match than the last one we found). if (ThisPlayerName > TextNameCompletedPrev) if ((TextNameCompletedSuccessor == "") || (ThisPlayerName < TextNameCompletedSuccessor)) TextNameCompletedSuccessor = ThisPlayerName; } } } } if (TextNameCompletedSuccessor == "") // no alphabetical successor found? TextNameCompletedSuccessor = TextNameCompletedFirst; // start over from first TextNameCompletedPrev = TextNameCompletedSuccessor; // save for next iteration // TextNameCompletedSuccessor now contains the next matching name. Replace the // partially entered name by the content of TextNameCompletedSuccessor. TypedStr = left(TypedStr, (RightSpace-1)) $ " " $ TextNameCompletedSuccessor; return true; } else { return false; } } else { TextNamePrefix = ""; //Make code reevaluate the entered prefix. return Super.KeyEvent(Key, Action, Delta); } } }
Mychaeel: Wouldn't you like case-insensitivity for that? (That's why I mentioned a ~= b
and Caps(a) < Caps(b)
in that comment – it would be handy.)
DJPaul: Good point - will make it so that it converts them both to uppercase first, just as easy as using a ~# b
. I'll upload the tested code this evening.
Mychaeel: ~=
strikes me as more elegant (and more concise), that's all. After all its express purpose is to compare strings without case sensitivity.
xX)(Xx: Clearer instructions for where to place the code would be nice or if anyone has the time, a proper .u file, as this is something which a lot of the UT community will want
DJPaul: This went into Esc, a UT1998 mod. IIRC, I put it into our custom Console class. As to where you want it to go, if it's in a dialogue box, you're going to want to do put it in the equivalent of a onKeyEvent method. If you want it from the "T"alk line, you're going to have to replace the class that is done in; I don't know if this is still in Console, I never looked.
El Muerte: it's ExtendedConsole? for UT200x. Btw, UT1998 mod? I hope you mean UT'99 My UTelAdSE and UnGateway mods also have tab completion to complete commands, but it works more like the Bash shell (prints a list of available options).
xX)(Xx: Will this work server side? Or will the latest anti-cheats scream HACK! ?
EricBlade: I had to change all occurences of "Viewport" to "ViewportOwner", and add "local string TextNamePrefix, TextNameCompletedPrev;" to the KeyEvent function
Category ... erm. Useful Function? Function? Snippet? something, anyway