Jump to content
Alloder.pro: about Allods with love
Search In
  • More options...
Find results that contain...
Find results in...

New program for writers

We turn from quantity to quality and tell you how we will supplement the Allods Team program with rewards in rubles.

More

The new Updater

Let us to introduce the new addon updater software and to share the details

Read more

Alloder 2.0

We have started the process of project evolve, and this relates not only, and not even primarily of the site's view

Read more

Developing CT_Total


SLA
 Share

Recommended Posts

Ciuine sent me a PM:

Ciuine wrote:
I don't know if any of the people of this site know but I've created a couple of add-ons, but I've never exactly had a RU client tester.

Do you think it would be possible for you to test out one of my add-ons on the RU client? It's an add-on that just replaces the damage visualizer with a cleaner scrolling combat text type deal.

I think, this discussion deserves a separate forum topic :)

So, you are the author of CT_Total addon, great! Nice to meet you! :) When you told "Hey, I'm an NA add-on author/modifier.", my first thought was - Is this the guy who have created CT_Total?

Yes, about 1-2 months ago somebody told there is a cool addon CT_Total on official US forum. I have found it, downloaded and tried it, and it was really a big surprise (even a shock), that somebody without having a properly translated API documentation have created such a full-featured addon! :)) I wanted to contact you then, to ask you to upload CT_Total to UI9, and I have even registered on US forum for this purpose. But I am very busy last time, a lot of important work is not done yet - I have to update AoTextureViewer and DarkDPSMeter, start building a DKP system for AO, etc, etc. I have installed CT_Total v 3.5 right now, and it constantly reminds me that I have to contact you. Btw, it was very easy to fix it for RU version - I had to change "common" to "userMods" in a couple of places. But since you got AO 1.1.02, you have already did this fix yourself. So, currently CT_Total works in all AO versions. I just tested the latest v3.6, it WORKS :)

But I suggest some upgrades, which will make it even better:

1) Localizations

There are several strings in your addon (like "Dodged", "Missed", etc), which can be translated to all 4 languages. There is a special technique, including a language detection function, to add multiple localizations into the addon, read this:

HOW-TO: Multilangual addon (use Google.Translate)

This localization method is used in such addons as DarkDPSMeter and GuildGui1b. Also there is another, different method of holding localized strings NOT in txt files, but in Lua file (it is possible since AO 1.1.02, because there is userMods.ToWString() function) , this method is used in some new addons like AddonManager and InspectStats.

2) Drag&Drop

I see you have added Drag&Drop in the last version. This is good, because, for example, your addon's icon looks in the right place only if screen is 16:9, but if the screen is 4:3, your icon overlaps the original game GUI. So, adding Drag&Drop was a good solution for this problem. But the code itself (DND_core.lua) is slightly outdated, better switch to the latest LibDnD.lua:

HOW-TO: LibDnD.lua - Drag&Drop Library (English translation included)

LibDnD is better, and simpler to use, just make some changes:

DNDInit( DNDOptions, MainPanel, 300 )

DNDInit( Options, Options, 301 )

to

DnD:Init( 300, DNDOptions, MainPanel, true )

DnD:Init( 301, Options, Options, true )

DNDReg( Options, 301 )

DNDUnreg( 301 )

to

DnD:Reg( Options )

DnD:Unreg( Options )

Btw, the 4-th DnD:Init() parameter (true) enables saving & restoring widget's position between game sessions.

3) AddonManager support

There is a new addon AddonManager - the "must-have" addon for everyone. Especially for addon developers. Besides loading/unloading addons, it have some extra features, like showing addons' allocated memory size, and locking/unlocking Drag&Drop in selected addons (and there will be even more features in future versions). Also, since Alt+Z don't send the SCRIPT_TOGGLE_UI event to user addons anymore, AddonManager got a "Hide All Addons" button which sends this event. But there is a bug in CT_Total - unfortunately, mainForm:Show( params.visible ) don't affect any widgets, those widgets always remains visible... And all those AddonManager features require addon to support some special events. It is very simple to implement, here is a guide:

AddonManager support in other addons (English translation included)

And most important, yes, of course I will help you to test any your addons on RU servers! :)

Also, if you have any questions regarding API or XDB files, feel free to ask :)

Link to comment
Share on other sites

Thanks for the response and appreciation. Tomorrow, (it's 3:21 AM now) I'll sit down and modify the add-on to include localization, the new DND library, and I'll fix the TOGGLE_UI switch.

The reason the toggle switch doesn't work is that I went through a number of testing phases to see if it was the game not passing the event or the add-on itself not reading it. While going through all these tests I converted the SCRIPT_TOGGLE_UI event registration into a reaction registration and didn't change it back since it didn't matter; it simply needs to be changed back to an event registration to work with the AddonManager. (Theoretically!)

I'm glad it works on all three clients; NA/EU/RU.

Link to comment
Share on other sites

Went through and wrote up all the changes necessary to localize it. Poor translations done through Google Translate, heh.

Switched DND libraries as suggested, and fixed the SCRIPT_TOGGLE_UI event registration to work with AddonManager. (Noticed something interesting while using AddonManager; "ContextLayoutManager", the add-on probably responsible for allowing user add-ons to receive Scripts from the game, no longer loads or exists. Or! It doesn't do any of that at all and just avoids interacting with user add-ons all together. Atleast in 1.1.02.)

I'd appreciate it if someone tested out the new version 3.7 before I upload it to UI9. Primarily for translation feedback, as the Russian translation had to be formatted in ANSI (so it looks more unreadable to me than usual).

Link to comment
Share on other sites

There is a small bug - instead of DnD:Unreg( 301 ) there must me DnD:Unreg( Options )

And there is unused global variable, you can remove it - Global( "UI_TOGGLE", true )

And where are AddonManager events? :) At least "U_EVENT_ADDON_MEM_USAGE_REQUEST". And maybe "U_EVENT_TOGGLE_DND" for locking CT_Total icon, if you want:

Code:
-- U_EVENT_ADDON_MEM_USAGE_REQUEST -- Sending memory usage info to "Addon Manager"

function OnEventAMMemUsageRequest()

userMods.SendEvent( "U_EVENT_ADDON_MEM_USAGE_RESPONSE", { sender = common.GetAddonName(), memUsage = gcinfo() } )

end

-- U_EVENT_TOGGLE_DND -- Locking/unlocking the button by "Addon Manager" request

function OnEventAMToggleDnD( params )

if params.target == common.GetAddonName() then

if params.state then

DnD:Reg( MainPanel )

else

DnD:Unreg( MainPanel )

end

end

end

and to the Init() function:

Code:
-- ADDONMANAGER EVENTS

common.RegisterEventHandler( OnEventAMMemUsageRequest, "U_EVENT_ADDON_MEM_USAGE_REQUEST" )

common.RegisterEventHandler( OnEventAMToggleDnD, "U_EVENT_TOGGLE_DND" )

Btw, since mainForm:Show( params.visible ) really works, and it even doesn't break the DnD system, then it is the BRILLIANT method of hiding/showing addons! I will use it myself, and recommend it to others. Thank you! :)

Also, isn't it better to hold all localization strings centralized? Currently, you waste a lot of code space, because localization strings are repeated several times in your code ( Glanced - 4 times, Dodge - twice, Missed - twice ). You can simplify it, and make it easier to maintain in the future, if you make a single table for holding all those localizations:

Code:
Global( "Texts", {

 [ "eng" ]  = {

 [ "Dodged" ]  = "Dodged",

 [ "Missed" ]  = "Missed",

 [ "Glanced" ]  = "(Glanced)",

},

 [ "rus" ]  = {

 [ "Dodged" ]  = "Увернулся",

 [ "Missed" ]  = "Промах",

 [ "Glanced" ]  = "(Вскользь)",

},

.....

} )

And then, instead of if-elseif-elseif-elseif-end, use just this single string:

Code:
Dodge:SetVal( "localet", userMods.ToWString( Texts [ localizer ] [ "Dodged" ]  ) )

I've forgot to tell you, that if you decide to hold localizations directly in Lua, then RU strings must be in Windows-1251 codepage, and DE/FR strings in Windows-1252 (a.k.a. iso-8859-1) codepage. Because Lua itself don't support Unicode, its "string" vars are 8-bit strings. But you already did everything correctly, congratulations :)

Russian localization (corrected):

Dodged = Увернулся

Missed = Промах

Glanced = Вскользь

The same, "converted" to Windows-1252:

Dodged = Óâåðíóëñÿ

Missed = Ïðîìàõ

Glanced = Âñêîëüçü

German is provided by Carnifex, and for French localization, there is neFAST. I'll PM him, and ask him to take a look at this thread. neFAST, can you confirm those strings are correct? :

French:

Dodged = Esquivé

Missed = Manquer

Glanced = Regards

neFAST is often here somewhere, so I think, he will reply very quickly.

Link to comment
Share on other sites

I think we can't rely on DarkDPSMeter localization very much, because its strings are all nouns (Dodge, Miss, Glance), and for CT we need probably verbs (Dodged, Missed, Glanced).

So, in DarkDPSMeter there are nouns (?):

Dodge = Ausgewichen

Miss = Verfehlt

Glance = Streiftreffer

And you proposed those strings for CT:

Dodged = Ausgewichen

Missed = Verfehlt

Glanced = Gestriffen

Link to comment
Share on other sites

No no, not "absorbed". Mmm... In DarkDPSMeter those 3 strings are NOT verbs, but nouns, and it sounds this way:

Dodge = Esquive

Miss = Raté

Glance = Réduit

So, how those nouns transforms to verbs?

Dodged = ?

Missed = ?

Glanced = ?

P.S. Btw, should I replace "Esquive" with "Esquivé" in DarkDPSMeter, or not?

P.S. Or maybe DarkDPSMeter French strings are totally wrong?

Link to comment
Share on other sites

Those strings differs from what Carnifex and neFAST proposed. Where did you get those strings?

Btw, we could just download a similar popular addon for WoW, and look into its localization strings. Since it is popular, its strings should be correct.

Link to comment
Share on other sites

I have downloaded a couple of addons from Curse, and look what I found inside:

ScrollingCombatText

RU

Dodges = Уклонение

Misses = Промахи

Glancing = Скольжение

DE

Dodges = Ausweichen

Misses = Fehlschlag

Glancing = ?

FR

Dodges = Déviés

Misses = Ratés

Glancing = ?

Recount

RU

Dodge = Уворот

Miss = Промах

Glancing = Скользящие

DE

Dodge = Ausgewichen

Miss = Verfehlt

Glancing = Gestreift

FR

Dodge = Esquive

Miss = Rate

Glancing = Érafle

P.S. Looks like "Raté" (or "Rate"?) is better French translation for "Missed".

UPD: Then I propose this RU translation:

Dodged = Уворот

Missed = Промах

Glanced = Скользящий

Please note, first and second words are like in Recount translation, but "Скользящий" *differs* from Recount translation "Скользящие", because the latter is in plural form.

Btw, none of those 3 words are verbs. First and second words are nouns, and third is adjective, but it is OK. I like it, because those words are short, and easier to read.

Link to comment
Share on other sites

While looking thought AddonManager code, a more graceful CT localization code came to my mind:

You can change

Code:
Global( "localizer", nil )

to

Code:
Global( "L", nil )

and change

Code:
localizer = GetGameLocalization()

to

Code:
L = Texts [ GetGameLocalization() ] 

for i, v in L do

L [ i ] = userMods.ToWString( L [ i ] )

end

Then, instead of that I have proposed earlier:

Code:
Dodge:SetVal( "localet", userMods.ToWString( Texts [ localizer ] [ "Dodged" ] ) )

you can use this:

Code:
Dodge:SetVal( "localet", L [ "Dodged" ] )

Voila! Beautiful! :)

Link to comment
Share on other sites

Guest Carnifex
Quote:
So, in DarkDPSMeter there are nouns (?):

Dodge = Ausgewichen
Miss = Verfehlt
Glance = Streiftreffer

And you proposed those strings for CT:

Dodged = Ausgewichen
Missed = Verfehlt
Glanced = Gestreift


only Streiftreffer is a noun (it is used so ingame), but I translated it for CT Total to an adjectiv, because it was also in the other language an adjectiv

Quote:
Glanced = "(Abprallen)"

lol, we don't play with balls, so

BTW: Gestreift is bether for this than Gestriffen, because the last one is only used in a widespreaded dialect
Link to comment
Share on other sites

How would I go about making this;

Code:
function OnEventEffectFinished( params )

if params.wtOwner:IsEqual( Critical ) then

if fadeS [ Critical ]  == WIDGET_FADE_IN then

Critical:PlayFadeEffect( 1.0, 1.0, MESSAGE_FADE_SOLID_TIME, EA_MONOTONOUS_INCREASE )

fadeS [ Critical ]  = WIDGET_FADE_SOLID

elseif fadeS [ Critical ]  == WIDGET_FADE_SOLID then

Critical:PlayFadeEffect( 1.0, 0.0, MESSAGE_FADE_OUT_TIME, EA_MONOTONOUS_INCREASE )

fadeS [ Critical ]  = WIDGET_FADE_OUT

elseif fadeS [ Critical ]  == WIDGET_FADE_OUT then

fadeS [ Critical ]  = WIDGET_FADE_TRANSPARENT

Critical:Show( false )

end

end

end

Into an unspecified widget, that would carry to term. IE, instead of Critical, it calls from an outside source the widget to run the effects on. The function OnEventEffectFinished as I have it set-up now runs when EVENT_EFFECT_FINISHED, so when Critical finishes it's first fade it moves onto the next fade.

My goal would be to essentially get the add-on itself to specify which widget to run through the effect finish code.

Link to comment
Share on other sites

Nevermind, figured out how to do it on my own, using a simple switch.

Code:
for widget, v in fadeS

Edit: Uploaded a new version 3.8 and then 3.9, with the localization and AM changes suggested and even more rewritten database and function coding. I'll need a tester for RU 2.0.00.22 when someone gets the time, no hurry. Shrunk the LUA file from 79 KB to 25 KB, heh.

Link to comment
Share on other sites

Quote:
for widget, v in fadeS

Yeah, that is correct.

Quote:
I'll need a tester for RU 2.0.00.22

I will test it tonight :)

P.S. BTW, I will write an English translation of the guide on posting addons on UI9, tonight. There is similar guide in Russian, but English guide will be more detailed, because it requires more explanation, with step-by-step screenshots.
Link to comment
Share on other sites

Quote:
P.S. BTW, I will write an English translation of the guide on posting addons on UI9, tonight. There is similar guide in Russian, but English guide will be more detailed, because it requires more explanation, with step-by-step screenshots.


Ah, I figured it was simple to upload; click the upload button in the top right, fill in the fields, name, information, file, and then await approval. Then after approval set-up a screenshot and make the best possible one sentence explanation translation as possible. However, if there's more to it then that, I'll wait for the posting. :P

As an explanation, I was thinking (I hope this is close and non-offensive);

Quote:

Данный аддон удаляет нормальной визуализатор повреждений и заменяет его а более подробный вариант, который отображает несколько отдельных движущихся виджеты, недалеко от района вашего персонажа, а не над головами врагов.
Link to comment
Share on other sites

Here is a special instruction in English:

Publication of new Addons (Instruction)

Quote:
However, if there's more to it then that, I'll wait for the posting. :P

Yes :), there are 2 descriptions. First is SHORT description, for UI9 start page only (and it is currently impossible to edit after you upload an addon), and second is LONG description, for addon's "About" page (you can edit it at any time).

Short Description:

Quote:
Заменяет визуализацию повреждений на более подробный вариант.

Long Description:

Quote:
Данный аддон заменяет стандартную визуализацию повреждений на более подробный вариант, который отображает надписи, разлетающиеся от вашего персонажа, а не поднимающиеся над головами врагов.

Also, add an English translation to "Long Description" as well.

And when you will create a forum topic for your addon discussion, copy-paste here your info from US forum, leave it in English. Don't worry, I will post a Russian translation below.

I have tested CT 3.9 in AO 2.0.00.26, it is working, but there is a bug :) It is related to translation text encodings. Your CT.lua file is saved as UTF-8, that's wrong, because Lua don't support unicode, so Lua files MUST be saved as 8-bit encoding instead, because if you leave it in UTF-8, then instead of "Промах" there will be "Промах", instead of "Érafle" there will be "Érafle", etc. The problem is that LUA don't support UTF-8, it works only with 8-bit encodings (like Windows-1251/1252). In European AO, strings are interpreted as Windows-1252, and in Russian AO strings are interpreted as Windows-1251. The problem is that those 2 encodings are incompatible, for example, both French é (Win1252) and Russian й (Win1251) share the same character code - \233. There are 2 variants of solution. Both solutions are ready in the attachment, and now I will explain how it works:

A) Many good text editors (like "Notepad++") can open/save text files in different encodings. Save your LUA file as Windows-1252. Copy-paste FR and DE texts here (because DE/FR texts must be Windows-1252), but since RU texts must be in another encoding - Windows-1251, there is an extra trick: Save RU texts in a separate file as Windows-1251, close this file, and OPEN IT AS Windows-1252 (RU texts will look like "Óâîðîò" - it is OK!), copy-paste those RU texts to LUA.

This way you get a 8-bit encoded LUA file. If you open it as Windows-1252, then FR/DE texts looks ok, and RU texts looks like "Óâîðîò". And if you open it as Windows-1251, then RU texts looks ok, while FR/DE texts looks like "Йrafle". THIS IS CORRECT. Such file will be interpreted as Windows-1252 in European AO (so FR/DE texts will look ok here), and it will be interpreted as Windows-1251 in Russian AO (so RU texts will look ok here).

B) I don't know, which 8-bit encoding is the default encoding in US. If your default encoding is not compatible with Windows-1252 (a.k.a. ISO-8859-1), or if it is not comfortable for you to open you Lua file as Windows-1252 each time, then there is another solution. You can make your Lua file a pure Latin encoded file, which can be opened as ANY encoding, even UTF-8, and it will look always the same. To do this, you have to convert all "special" European/Russian characters to escaped character codes. You can find FR/DE codes here and RU codes here. This way, for example, "Уворот" becomes "\211\226\238\240\238\242", and "Esquivé" becomes "Esquiv\233".

Both solutions are in the attachment. Solution A) is called "CT_MIXED.lua", and solution B) is called "CT_LATIN.lua". Choose any solution which you like more.

Link to comment
Share on other sites

Ah, I use two different coding ITE's, Notepad++ and SciTE, the second doesn't have encoding checkers, but still has detection (and it looks nicer while coding). So it probably detected that I wrote ANSI coding and translated it to UTF-8, and then later when I saved it again it saved as UTF-8 instead of ANSI. I'll use Notepad++ to verify that the Lua is saved in ANSI from now on.

Thanks for the help and English instructions.

My next development goal will be to find a way to make multiple versions of the same widget appear on screen at once, so that it doesn't display just one widget for AoE's if they all do the same type of damage. I saw that DarkDPS uses something similar for writing each different player and damage field.

Edit: I might test "local wtChildForm = common.AddonCreateChildForm( "AdditionalForm01" )" for this purpose.

Link to comment
Share on other sites

Quote:
My next development goal will be to find a way to make multiple versions of the same widget appear on screen at once, so that it doesn't display just one widget for AoE's if they all do the same type of damage. I saw that DarkDPS uses something similar for writing each different player and damage field.

It is called dynamically created widgets. The technology is rather simple. For example, you have a parent widget called ParentWidget (or it can be called, MainPanel, for example), with a child widget called "MyWidgetName". You can use this widget as a prototype to create a table named MyWidgets, consisting of 10 identical widgets:
Code:
-- Getting the widget descriptor:
local MyWidgetDesc = ParentWidget:GetChildChecked( "MyWidgetName", false ):GetWidgetDesc()
-- We dont need the widget anymore:
ParentWidget:GetChildChecked( "MyWidgetName", false ):DestroyWidget()
-- Creating a table of 10 widgets:
Global( "MyWidgets", {} )
for i = 1, 10 do
MyWidgets  = mainForm:CreateWidgetByDesc( MyWidgetDesc )
ParentWidget:AddChild( MyWidgets  )
end

Link to comment
Share on other sites

Чтоб ничего не дестроить:

Code:

local widgetDesc

function GetNextWidget( name )

local widget

if not widgetDesc then

widget = mainForm:GetChildChecked( name, false )

widgetDesc = widget:GetWidgetDesc()

else

widget = mainForm:CreateWidgetByDesc( widgetDesc )

end

return widget

end

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

By using our site you agree to the Terms of Use