Перейти к содержанию

Дайджесты за январь-февраль

Обновления гайдов и аддонов

Январь Февраль

Мониторинг серверов и редактор аддонов

Представляем вам две легенды. То, о чем можно было только мечтать, стало реальностью.

Мониторинг серверов Редактор аддонов

Подсказки из игры на вашем сайте

Теперь вы можете отображать сведения о внутриигровых элементах простым наведением курсора мыши.

Подробнее

Апдейтер аддонов

Представляем вам программу для автообновления аддонов и делимся подробностями.

Подробнее Скачать

Developing CT_Total


SLA

Рекомендуемые сообщения

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 :)

Ссылка на комментарий
Поделиться на другие сайты

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.

Ссылка на комментарий
Поделиться на другие сайты

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).

Ссылка на комментарий
Поделиться на другие сайты

here is the file with a bether localisation (german by myself and french and russian copy and paste from darkdpsmeter)

File: CT.zip
Ссылка на комментарий
Поделиться на другие сайты

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.

Ссылка на комментарий
Поделиться на другие сайты

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

Ссылка на комментарий
Поделиться на другие сайты

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?

Ссылка на комментарий
Поделиться на другие сайты

Here's what I'll use.

French;

Dodged = "Esquivé"

Missed = "Raté"

Glanced = "(Ricoché)"

German;

Dodged = "Ausgewichen"

Missed = "Verfehlt"

Glanced = "(Abprallen)"

How's that sound/look, translation wise?

Ссылка на комментарий
Поделиться на другие сайты

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.

Ссылка на комментарий
Поделиться на другие сайты

Both abprallen and ricoché mean "glanced off of" or "ricocheted". Heh.

I'll probably end up using manqué instead of raté.

Edit: Oh, and thanks for all the help, really appreciate it.

Ссылка на комментарий
Поделиться на другие сайты

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.

Ссылка на комментарий
Поделиться на другие сайты

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! :)

Ссылка на комментарий
Поделиться на другие сайты

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
Ссылка на комментарий
Поделиться на другие сайты

Thanks for the upgrade to your code. :P

I'm in the process of stripping the whole CT_Total mod into a series of function calls, rather than repeated redundancy at the moment. So hopefully it'll all be shrunken memory wise.

Ссылка на комментарий
Поделиться на другие сайты

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.

Ссылка на комментарий
Поделиться на другие сайты

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.

Ссылка на комментарий
Поделиться на другие сайты

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.
Ссылка на комментарий
Поделиться на другие сайты

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:

Данный аддон удаляет нормальной визуализатор повреждений и заменяет его а более подробный вариант, который отображает несколько отдельных движущихся виджеты, недалеко от района вашего персонажа, а не над головами врагов.
Ссылка на комментарий
Поделиться на другие сайты

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.

Ссылка на комментарий
Поделиться на другие сайты

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.

Ссылка на комментарий
Поделиться на другие сайты

Addon is released, you can find it on the main page:

CT_Total

Further discussion - in CT_Total forum :

http://ui9.ru/forum/ct_total

Аддон уже выпущен, и доступен на главной странице:

CT_Total

Дальнейшее обсуждение - в форуме CT_Total:

http://ui9.ru/forum/ct_total

Ссылка на комментарий
Поделиться на другие сайты

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

Ссылка на комментарий
Поделиться на другие сайты

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

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

Ссылка на комментарий
Поделиться на другие сайты

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...

Важная информация

Пользуясь сайтом, вы принимаете Условия использования