Posts filed under 'Game Programming'

WoW addon – Russian Translit

         During my playing in World of Warcraft, many times I have to communicate with Russian speaking players (especially now, when I in Russian guild). For me, typing Russian is a challenge: as for one who was grown in Israel, typing speed in Russian is about a word per minute. This is when I got an idea: translit addon. First of all, what translit is about: translit is solution for people like me, with have no ability to type Russian (sometimes the reason could be no Russian keyboard installed on the computer). Translit is a mapping of English letters to Russian – people typing Russian words using English letters. For example, “Zdravstvuy Mir” – “Здравствуй Мир” means in Russian “Hello World”. The idea is when a user pressing English “Z”, Russian “З” is actually being typed.
      How to use it: after installing addin, you will have new added dialog with two buttons: “eng” and “rus”. First means translit off, second means translit on. Also in key bindings menu, under “Russian Translit” header you can bind some key to activate / deactivate translit. As a mapping rules, I used well known combinations with are used in online Russian translit – www.translit.ru
      Implementation: the basic idea – somehow I have to intercept “OnKeyDown” event from chat edit box, and replace it by Russian letter, according to mapping rules. I accomplish this by hooking my script to the chat edit box:

local frame = getglobal(“ChatFrameEditBox”); //get pointer to chat edit box
frame:SetScript(“OnChar”, onTextChanged); //hook my script

      Now, for some reason the “OnKeyDown” event is not being fired, and Blizzard still have me an answer for that. So I used “OnChar” event, which means “OnKeyUp”. Obviously, my algorithm have to take in account this when performing string calculations: when the event is fired, the pressed character already located inside the string. This means first I have to delete it, and then add on it place mapped Russian character. And this means, I have to track letter position inside of the message string.

   In addition, sometimes combination of English letters means one single Russian letter. For example, “sh” means Russian “ш”. As a result, on each receiving letter I have to check previous one for possible combinations. So my algorithm going to be as the following:
1. Create new string
2. Copy all chars until current one (or until one before current one).
3. Add Russian letter with is representing pressed English key.
4. Copy all chars after current char (user could edit text in the middle of the exist string).

     So far all sounds easy. Now this starts to be more complicated: as I discovered, Russian letters advancing cursor position by 2 (!!!), while English letters and numbers by 1. This is bad (and unexpected as well), because this way I have no idea how many chars I have to copy before current one (step 2). It seems this is how WoW encoding its strings: every non English letter combined from two letters (one of them is invisible) – the code of the letter and some kind of marker, which has code 209 or 208. The workaround I doing: I checking letter before current. If it has code 208 or 209 (greater than 200) – then it means I have Russian letter there, and I have to step one more position left to take it (again, Russian letter combined from two characters):

if(strbyte(charBefore) > 200) then
charBefore = strsub(currentText, cursorPosition-2, cursorPosition-1); //take 2 chars
else
charBefore = strsub(currentText, cursorPosition-1, cursorPosition-1); //take 1 char
end

That was the trickiest part of the addon, which took me a while to understand, due to lack of documentation.

   One more interesting point: when I creating letter from combination (something like “sh”) – I have to delete two English chars, and replace it by single Russian. I achieving this by storing position offset: if single English char, then the offset is 1 (copy all characters until one position before current) or else offset is 3 (additional 2 characters representing single Russian letter).

result = strsub(currentText, 0, cursorPosition – offset); //copy all but 1 or 2 characters before current

result = result .. newChar; //add mapped russian character

if (cursorPosition < textLength) then //if we are not in the end of string, copy all rest of the letters.
result = result .. strsub(currentText, cursorPosition + 1);
end

    Key Bindings: probably I would like to activate / deactivate translit by pressing some key from keyboard, not only by clicking on the proper button using mouse. For this purpose I created Bindings.xml file. It contains pretty straightforward xml:

<Binding name=”TRANSONOFF” header = “RUSTRANS”>

      SwitchLang();

 </Binding>

Inside frame.lua, I defined meanings for name and header:

BINDING_HEADER_RUSTRANS = “Russian Translit”;
BINDING_NAME_TRANSONOFF = “Translit On/Off”;

   Now, if you will go to key bindings menu inside the game, you will find under “Russian Translit” section key bindings for “Translit On/Off” option. Each time this key will be pressed, ‘SwitchLang’ method will be called.

That’s all. You welcome to send me your feedback/suggestions/bugs.

Download addon from here.

16 comments June 2, 2008

Visual Studio addon for World of Warcraft released!!!

Recently, released addon for VS2008, which allowing creation of addins for WoW (yes, this is an addon to create addons – confusing a bit ;-) ). So, as a hardly addicted WoW player and professional programmer, I felt a personal duty to test it and see what is all about. Prior to this addin, WoW addins were done primarily using Notepad (although there is an entire community of developers who advancing to abandon Visual Studio and develop using notepad – I’m not sure it is a good idea). With the VS WoW addon it is easier than ever to create addons for WoW. It takes an advantage of  powerful VS designer and providing many components to create any GUI you want, such as frames, buttons and text boxes.  It has an Intellisense support for almost every function you have in your disposal (later I will talk about this “almost”). Personally I love Visual Studio, and I think many WoW developers will appriciate this wonderful tool.

Ok, enough talking – lets do some example! Initially my task was to create Orcish - Human translator. In WoW Alliance cannot understand Horde talking, and vice versa. So, many times killing started because of misunderstanding :-) What I really wanted to do, is to create addin, which will translate from Orcish to Human. Sounds easy - all I need to do is register somehow to ‘new message’ event in chat window, pass message text to translating function, and print translated text back to the chat window. Unfortunately, for now I not able to translate Orcish, and according to this article i doubt I ever will. Therefore I just printing the original text – echo addin. Here are the steps to create this addin:

  • Install WoW addin for Visual Studio – get it from here. I installed it successfully with VS2008 Express Edition (free version of VS which is available on www.microsoft.com).
  • Create new project – Basic WoW Addon. It creates for you Frame.xml and Frame.lua. Xml file describes GUI, and lua file holds all logic behind.
  • Double click on xml file will open VS designer. You can drag and drop components from toolbox on the left. The designer will generate all xml for you – no coding needed.
  • As far as I know, you can catch events only from GUI objects such as frames. For this purpose, we will use frame which was generated by wizard on project creation.
  • Locate it in designer and click on it left click. Properties grid on the right should appear.
  • Locate ‘name’ property and change it to ‘_invisibleFrame’.
  • Locate ‘hidden’ property and set it to True.
  • Locate OnLoad property. Name it ‘OnLoad()’ and press Create. Stub for this method will be created in the lua file.
  • Inside it, write the following code:
    function
    OnLoad()
    this:RegisterEvent(“CHAT_MSG_SAY”);
    end
  • CHAT_MSG_SAY – is event which is fired on new ’say’ message. How I know that? Well, this is the part about “almost” of Intellisense. It is not provides support for events, and you have to discover name of the right event on your own. I used Internet, and found it in 2 minutes. It missing many other things, as you will see soon.
  • Now we need to catch fired event. Go back to designer. In property grid, locate ‘OnEvent’ property. Name it ‘_invisibleFrame_OnEvent()’ and press Create button.
  • About event mechanics: WoW has 8 predefined variables for holding event arguments (maybe not only) – arg1, arg2, … arg8. If some event has arguments, they stored in these variables. As I discovered, CHAT_MSG_SAY event has 3 arguments: arg1 is text of the message, arg2 is the name of speaking person, arg3 says if the language is Common or Orcish. All other args are nil. This addin meant to be translator, therefore I had to check speaking language – I want translate only Orcish:
    function _invisibleFrame_OnEvent()
    if(event == “CHAT_MSG_SAY”) then
    if(arg3 == “Orcish”) then
    local translated = Translate(arg1);
    AddMessage(translated);
    end
    end
    end
  • Translate function have to translate text (for now it returns original text). AddMessage function prints specified text in the chat window. Here these 2 functions:

    function AddMessage(msg, r, g, b)
     if ( not msg ) then
      msg = ” {NIL Value Passed}”;
     end
     msg = “Translated : “..msg;
     if ( not r ) then
      r, g, b = 0.64, 0.21, 0.93;
     end
     if DEFAULT_CHAT_FRAME then
      DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b);
     end
    end 

function Translate(orcishText)
 return orcishText;
end

  • DEFAULT_CHAT_FRAME is another example of what you can’t find with Intellisense. I searched for function to print my text to chat window, and finally found this one in other addin.

That’s all! After you building solution, it will itself deploy your addin in WoW folder. In general, I very impressed with the work done by developers of this addin. Creating complex UI was never easy as now, and there is no need to mess with xml. Neverless it’s Intellisense needs future improvements, I think this is an awesome tool with great potential, and hope this project will continue evolve.

3 comments February 3, 2008


Categories

Top Posts

Tags

.NET addin app.config ArrayList bug CAB Configuration ConfigurationManager ConfigurationSection ContentControl ContextMenu CTime; DateTime custom keys DataBinding DataContext Data templates debugging equals gethashcode GUI Hashtable interlocked Invoke lock lock free memcpy MFC multithreading multithreading; lock free override performance SCSF serialization Smart Client Software Factory Styles System.Configuration unsafe virtual functions Visual Studio wait free WinAPI WinForms WinForms\WPF Integration World of Warcraft World of Warcraft; Addon

Archives