Все способы локализовать карту

Published
» Способ реализации: Lua
» Тип: Наработка
Всем привет, сидите на рефордже, но ваша карта поддерживает только 1 язык? Не беда - всё проще чем вы думаете.

Авто определение языка

Если мне не изменяет память, то возможность локализации подвезли в 1.29+ а конкретно функцию BlzGetLocale() она автоматически считывает язык батлнет клиента и может иметь следующие значения:
"ruRU" - русский
"enUS" - английский
В этом случае игроку ничего даже выбирать не придётся, но рассмотрим все способы, как это использовать и разумеется с примерами

Функция L()

На мой взгляд это самый простейший способ, и я остановился на нём
function L(ru, en)
    if en=="" then
        en=ru
    end
    return BlzGetLocale()=="ruRU" and ru or en
end
и пример использования:
print(L("Русский текст", "English Text"))
В любую функцию, где должен быть текст, мы подставляем L("русский","Другой язык"), если другой язык не указан, то текст всё равно будет русским, однако помните, что не у всех иностранцев стоит кириллица, скорее всего они просто увидят пустые сроки вместо нашего, как они говорят "dog language" или "monkey language". Хотя в варкрафте к нам относятся хорошо, но это уже другая тема для разговора...

if ... else

Способ аналогичный верхнему, можно даже совместить с BlzGetLocale() или менять язык через выбор диалога
Создаём массив языков, циклом или ручками
local ls = "Текст по умолчанию"
if GetLocalPlayer() == GetTriggerPlayer() then
    if lang == 1 then
        ls = "Текст изменён на язык 1"
    else
        ls = "Текст изменён на язык 2"
    end
end
print(ls) -- подставляем ls в нужном месте например в игровых сообщениях, описании фрейма, плавающем тексте
Или второй вариант, можно делать локализованные модели, например чтобы табличка над таверной была переведена
langPlayer = { 1, 1, 1, 2 } -- Первые 3 игрока русский язык, последний - иной, заполняется как угодно, например стартовый диалогом или локалью
local langModel = "enter"

if langPlayer[GetPlayerId(GetLocalPlayer())] == 1 then
    langModel="pathToRUModel"
else
    langModel = "pathToENGModel"
end

AddSpecialEffect(langModel, x, y)
Для каждого игрока будет своя локализованная модель эффекта

Через WTS строки

Как только вы создаёте карту в ней появляется папка с названием _Locales
ruRU.w3mod
zhCN.w3mod
enUS.w3mod
dede.w3mod
kokr.w3mod
и куча других
Внутри каждой папки есть war3map.wts, многие замечали, что англоязычные карты не отображают текст в нашей русской локале вообще, потому что war3map.wts заполнена только в enUS.w3mod
Простейший пример как это использовать, можно разово прогнать просто файл через переводчик
STRING 132
// Items: I000 (Healing Rune), Name (Name)
{
Восстанавливающая руна
}
а на китайском это вот так
STRING 132
// Items: I000 (Healing Rune), Name (Name)
{
治疗符文
}
Как видите, это вообще автозаполнение из РО, кстати первые 2 способа для РО не очень удобно применять, там есть заморочки, придётся нагружать карту лишним кодом BlzSetAbilityExtendedTooltip
А чтобы это использовать вне РО например в описании фреймов или вывод текста на экран достаточно написать
print("TRIGSTR_132")
Опять же, весьма неудобно ибо придётся подглядывать в WTS и смотреть, а что же у тебя там в 465 строке
Это уже на ваш, выбор...

Примеры локализованных карт, что мне известны

xgm.guru/p/samurowars через wts
xgm.guru/p/wc3/peonrpg2 через locale
xgm.guru/p/wc3/blood-arena определите сами (Это домашнее задание)


Views: 176

» Лучшие комментарии


Bergi_Bear #1 - 1 month ago (изм. ) 0
Голосов: +1 / -1
Если кому известны другие способы локализации и есть примеры мультиязычных карт, то кидайте их в комментарии
AntNo #2 - 4 weeks ago (изм. ) 2
Голосов: +2 / -0
Текст фреймов интерфейса, тексты сообщений, системные и подсказки делаются через *.fdf файлы:
» Пример
Файл, содержащий строки (на конкретном языке) и импортированный в карту с указанием локали
StringList
{
WELCOME_USER_MSG "Welcome $p",
}
Файл (*.toc), в котором указан путь к *.fdf файлу, загруженный соответствующей функцией (BlzLoadTOCFile)
Использование:
  1. в описании фреймов: TEXT "WELCOME_USER_MSG"
  2. в коде: GetLocalizedString("WELCOME_USER_MSG")
ScorpioT1000 #4 - 4 weeks ago 0
Голосов: +0 / -0
А enGB там нет?

Функция L()
Красота, сам так часто делаю во многих проектах)
Bergi_Bear #5 - 4 weeks ago 2
Голосов: +2 / -0
Красота
Так это с твоей подачи и есть
ScorpioT1000 #6 - 4 weeks ago 5
Голосов: +5 / -0
Вот вам ещё подгон, можешь добавить в статью.
Функция Морфологии - Множественное число (Plural Form)
--- Morphology function to get plural form of the number
-- @param input number
-- @param table morphology plural forms
-- @param bool (default true) to include number or return just the word
function pluralForm(number, forms, includeNumber)
    if(#forms == 2) then
        forms[3] = forms[2]
    elseif(#forms ~= 3) then
        error("pluralForm: not enough elements in 'forms' argument")
    end
    local cases = {2,0,1,1,1,2}
    local result = ""
    if(includeNumber or includeNumber == nil) then
        result = result .. number .. ' '
    end
    return result .. forms[ ((number % 100 > 4 and number % 100 < 20) and 2 or cases[math.min(number % 10, 5)+1])+1 ]
end
Пример:
print(pluralForm(1, {"юнит", "юнита", "юнитов"}))
print(pluralForm(3, {"юнит", "юнита", "юнитов"}))
print(pluralForm(5, {"юнит", "юнита", "юнитов"}))
print(pluralForm(1, {"unit", "units"}))
print(pluralForm(3, {"unit", "units"}))
print(pluralForm(5, {"unit", "units"}))
print(pluralForm(1, {"Получен новый предмет!", "Получены новые предметы!"}, false))
print(pluralForm(5, {"Получен новый предмет!", "Получены новые предметы!"}, false))
Результат:
1 юнит
3 юнита
5 юнитов
1 unit
3 units
5 units
Получен новый предмет!
Получены новые предметы!

Можно миксовать с переводом:
print(pluralForm(1, {L("юнит","unit"), L("юнита","units"), L("юнитов","units")}))
Bergi_Bear #8 - 4 weeks ago 0
Голосов: +0 / -0
ScorpioT1000, о да, эту штуку знаю, ещё у Назара её видел