Skip to main content

SkillTree Plugin Modifications

Plugin: SkillTree by Whispers88 Source: Codefling File: rust-template-private-main/SkillTree.cs

При обновлении плагина до новой версии все модификации будут потеряны. Используй этот документ для повторного применения изменений.


Changelog

VersionDateAuthorDescription
1.52026-01-23ClaudeAdd Mod #10: IsTreeCompleted API for SKILL_MAXED + SKILL_TREE_COMPLETED events
1.42026-01-22ClaudeImprove docs: structured checklist, complete Russian keys, Translation Adjustments section
1.32026-01-22ClaudeAdd Mod #9: Enabled/Disabled localization in Buff Settings
1.22026-01-22ClaudeUpdate Mod #8: all CLOSE buttons, cost text width, buttons shift 30px
1.12026-01-22ClaudeAdd Mod #7: Player/Ultimate Settings localization
1.02025-01-22ClaudeInitial documentation + localization fixes

Modification #1: GoLoot Integration Hook (STOnNodeLevelUp)

Purpose: Отправка события в GoLoot при прокачке навыка для трекинга квестов типа SKILL_UPGRADED.

Location

  • Line: ~10959-10961 (после HandlePerms(player, tree, name, ni.level_current);)

Original Code

HandlePerms(player, tree, name, ni.level_current);

return true;

Modified Code

HandlePerms(player, tree, name, ni.level_current);

// GoLoot Integration: notify other plugins about skill upgrade
// Parameters: player, treeName, nodeName, newLevel, maxLevel, buffType
Interface.CallHook("STOnNodeLevelUp", player, tree, name, ni.level_current, ni.level_max, ni.buffInfo.Key.ToString());

return true;

How to Apply

  1. Найди метод HandlePerms(player, tree, name, ni.level_current);
  2. Добавь после него 3 строки с комментарием и вызовом хука
  3. Убедись, что return true; идёт после хука

Modification #2: Add Localization Key (UINextRowUnlocksIn)

Purpose: Добавление ключа локализации для текста "Next row unlocks in: X points".

Location

  • Line: ~4844 (в словаре DefaultMessages, после ["UIUnlocksIn"])

Original Code

["UIUnlocksIn"] = "<color=#f5d800>Unlocks in:</color>",
["UILevelUpButton"] = "<color=#ffb600>Level Up</color>",

Modified Code

["UIUnlocksIn"] = "<color=#f5d800>Unlocks in:</color>",
["UINextRowUnlocksIn"] = "<color=#f5d800>Next row unlocks in: <color=#0AC406>{0}</color> points</color>",
["UILevelUpButton"] = "<color=#ffb600>Level Up</color>",

How to Apply

  1. Найди строку ["UIUnlocksIn"] = "<color=#f5d800>Unlocks in:</color>",
  2. Добавь после неё новую строку с ключом ["UINextRowUnlocksIn"]

Modification #3: Tree Title Localization

Purpose: Использование системы локализации для заголовка дерева навыков (Mining, Combat, etc.).

Location

  • Line: ~22101 (в методе SendSkillTree)

Original Code

new CuiTextComponent { Text = tree.Replace('_', ' ').ToUpper(), Font = "robotocondensed-bold.ttf", FontSize = 26, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" },

Modified Code

new CuiTextComponent { Text = lang.GetMessage(tree, this, player.UserIDString).ToUpper(), Font = "robotocondensed-bold.ttf", FontSize = 26, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" },

How to Apply

  1. Найди Text = tree.Replace('_', ' ').ToUpper()
  2. Замени на Text = lang.GetMessage(tree, this, player.UserIDString).ToUpper()

Modification #4: "Next Row Unlocks In" Localization

Purpose: Использование системы локализации для текста разблокировки следующего ряда.

Location

  • Line: ~22876 (в методе SendSkillTree)

Original Code

new CuiTextComponent { Text = string.Format("<color=#f5d800>Next row unlocks in: <color=#0AC406>{0}</color> points</color>", nextUnlock), Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.UpperLeft, Color = "1 1 1 1" },

Modified Code

new CuiTextComponent { Text = string.Format(lang.GetMessage("UINextRowUnlocksIn", this, player.UserIDString), nextUnlock), Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.UpperLeft, Color = "1 1 1 1" },

How to Apply

  1. Найди string.Format("<color=#f5d800>Next row unlocks in:
  2. Замени на string.Format(lang.GetMessage("UINextRowUnlocksIn", this, player.UserIDString), nextUnlock)

Modification #5: Tree Navigation Arrows Localization

Purpose: Использование системы локализации для стрелок навигации между деревьями.

Location

  • Line: ~21933, ~21954 (в методе TreeNavButtons)

Original Code

new CuiTextComponent { Text = "< <", Font = "robotocondensed-bold.ttf", ...
// и
new CuiTextComponent { Text = "> >", Font = "robotocondensed-bold.ttf", ...

Modified Code

new CuiTextComponent { Text = lang.GetMessage("UIBackArrow", this, player.UserIDString), Font = "robotocondensed-bold.ttf", ...
// и
new CuiTextComponent { Text = lang.GetMessage("UINextArrow", this, player.UserIDString), Font = "robotocondensed-bold.ttf", ...

How to Apply

  1. Найди Text = "< <" в методе TreeNavButtons
  2. Замени на Text = lang.GetMessage("UIBackArrow", this, player.UserIDString)
  3. Найди Text = "> >" там же
  4. Замени на Text = lang.GetMessage("UINextArrow", this, player.UserIDString)

Modification #6: CLOSE Buttons Localization

Purpose: Использование системы локализации для всех кнопок "CLOSE".

Locations (7 мест)

LineMethodElement Name
~14687SkillTree_Buff_SettingsSkillTree_BuffMenu_close
~15835ScoreBoardPanelScoreboardCloseLabel
~15980SkillTree_UltimateMenuSkillTree_UltimateMenu_close
~19364ShowPrestigeRankButton_6584 (CuiButton)
~21973TreeNavButtonsSkillTree_close

Original Code

new CuiTextComponent { Text = "CLOSE", Font = "robotocondensed-bold.ttf", ...
// или для CuiButton:
Text = { Text = "CLOSE", Font = "robotocondensed-bold.ttf", ...

Modified Code

new CuiTextComponent { Text = lang.GetMessage("UIClose", this, player.UserIDString), Font = "robotocondensed-bold.ttf", ...
// или для CuiButton:
Text = { Text = lang.GetMessage("UIClose", this, player.UserIDString), Font = "robotocondensed-bold.ttf", ...

How to Apply

  1. Найди все вхождения Text = "CLOSE" в файле
  2. Замени каждое на Text = lang.GetMessage("UIClose", this, player.UserIDString)

Modification #7: Player/Ultimate Settings Localization

Purpose: Использование системы локализации для кнопок "Player Settings" и "Ultimate Settings".

Location

  • Line: ~21780, ~21811 (в методе SendSkillTree)

Original Code

new CuiTextComponent { Text = "<color=#ffb600>Player Settings</color>", Font = "robotocondensed-bold.ttf", FontSize = 16, ...
// и
new CuiTextComponent { Text = "<color=#ffb600>Ultimate Settings</color>", Font = "robotocondensed-bold.ttf", FontSize = 16, ...

Modified Code

new CuiTextComponent { Text = lang.GetMessage("UIPlayerSettings", this, player.UserIDString), Font = "robotocondensed-bold.ttf", FontSize = 16, ...
// и
new CuiTextComponent { Text = lang.GetMessage("UltimateSettings", this, player.UserIDString), Font = "robotocondensed-bold.ttf", FontSize = 16, ...

Lang Keys Required

ВАЖНО: Используем СУЩЕСТВУЮЩИЕ ключи, но обновляем UIPlayerSettings:

  1. UIPlayerSettings (~строка 4627) — ОБНОВИТЬ значение, добавив цвет:
// Было:
["UIPlayerSettings"] = "Player Settings",
// Стало:
["UIPlayerSettings"] = "<color=#ffb600>Player Settings</color>",
  1. UltimateSettings (~строка 4680) — уже существует с цветом, просто использовать

How to Apply

  1. Найди ["UIPlayerSettings"] = "Player Settings" (~строка 4627)
  2. Замени на ["UIPlayerSettings"] = "<color=#ffb600>Player Settings</color>"
  3. Найди Text = "<color=#ffb600>Player Settings</color>" (~строка 21780)
  4. Замени на Text = lang.GetMessage("UIPlayerSettings", this, player.UserIDString)
  5. Найди Text = "<color=#ffb600>Ultimate Settings</color>" (~строка 21811)
  6. Замени на Text = lang.GetMessage("UltimateSettings", this, player.UserIDString)

Modification #8: UI Position/Width Fixes for Russian Localization

Purpose: Корректировка позиции и ширины кнопок для русских текстов ("Улучшить", "Сбросить", "ЗАКРЫТЬ", текст стоимости).

8.1 Level Up Button ("Улучшить")

Location: ~строка 22767 (элемент SkillTree_LevelUp)

Проблема: Кнопка находится впритык к цифре стоимости, мягкий знак обрезается.

Original Code:

new CuiRectTransformComponent{ AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-57.32 -16", OffsetMax = "0.68 16" }

Modified Code:

new CuiRectTransformComponent{ AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-27.32 -16", OffsetMax = "45.68 16" }

Изменение: Сдвинута на 30px вправо (ширина 73px сохранена). Создаёт отступ от цифры стоимости.

8.2 Respec Button ("Сбросить")

Location: ~строка 22568 (элемент SkillTree_RespecCost)

Проблема: Мягкий знак обрезается, кнопка не выровнена с Level Up.

Original Code:

new CuiRectTransformComponent{ AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-58 -16", OffsetMax = "0 16" }

Modified Code:

new CuiRectTransformComponent{ AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-28 -16", OffsetMax = "45 16" }

Изменение: Сдвинута на 30px вправо (ширина 73px сохранена). Выровнена с Level Up кнопкой.

8.3 CLOSE Buttons ("ЗАКРЫТЬ") - Все места

Проблема: Текст "ЗАКРЫТЬ" не помещается (обрезается мягкий знак).

8.3.1 TreeNavButtons (основная кнопка закрытия)

Location: ~строки 21975, 21983 (в методе TreeNavButtons)

Original Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-29 -16", OffsetMax = "29 16" }

Modified Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-45 -16", OffsetMax = "45 16" }

8.3.2 Buff Settings CLOSE

Location: ~строки 14689, 14697 (элемент SkillTree_BuffMenu_close)

Original Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-29 -54.635", OffsetMax = "29 -22.635" }

Modified Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-45 -54.635", OffsetMax = "45 -22.635" }

8.3.3 Player Settings CLOSE

Location: ~строки 14496, 14504 (в методе SkillTree_Player_Settings)

Original Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-390.71 -243", OffsetMax = "-332.71 -211" }

Modified Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-374.71 -243", OffsetMax = "-300.71 -211" }

Изменение: Ширина увеличена с 58px до 74px

8.3.4 Ultimate Menu CLOSE

Location: ~строки 15982, 15990 (элемент SkillTree_UltimateMenu_close)

Original Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-390.71 -201.1", OffsetMax = "-332.71 -169.1" }

Modified Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-374.71 -201.1", OffsetMax = "-300.71 -169.1" }

Изменение: Ширина увеличена с 58px до 74px

8.4 Cost Confirmation Text ("СТОИМОСТЬ: X скрапа")

Location: ~строка 12222 (в методе SendRespecBuyPanel)

Проблема: Текст "СТОИМОСТЬ: 420 скрапа" не помещается в одну строку.

Original Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-68.137 28.482", OffsetMax = "68.137 63.5" }

Modified Code:

new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-110 28.482", OffsetMax = "110 63.5" }

Изменение: Ширина увеличена с 136px до 220px

How to Apply

  1. Level Up: Найди OffsetMin = "-57.32 -16", OffsetMax = "0.68 16", замени на -27.32 -16 / 45.68 16
  2. Respec: Найди OffsetMin = "-58 -16", OffsetMax = "0 16", замени на -28 -16 / 45 16
  3. TreeNavButtons CLOSE: Найди -29 / 29, замени на -45 / 45 (2 места)
  4. Buff Settings CLOSE: Найди -29 -54.635 / 29 -22.635, замени на -45 / 45
  5. Player Settings CLOSE: Найди -390.71 -243 / -332.71 -211, замени на -374.71 / -300.71
  6. Ultimate Menu CLOSE: Найди -390.71 -201.1 / -332.71 -169.1, замени на -374.71 / -300.71
  7. Cost text: Найди -68.137 28.482 / 68.137 63.5, замени на -110 / 110

Modification #9: Buff Settings Enabled/Disabled Localization

Purpose: Локализация текста "Enabled"/"Disabled" в меню Buff Settings.

Location

  • Line: ~14761 (в методе SkillTree_Buff_Settings)

Original Code

Text = { Text = buff.Value.enabled ? "<color=#53ad2c>Enabled</color>" : "Disabled", Font = "robotocondensed-regular.ttf", FontSize = 18, ...

Modified Code

Text = { Text = buff.Value.enabled ? $"<color=#53ad2c>{lang.GetMessage("UIEnabled", this, player.UserIDString)}</color>" : lang.GetMessage("UIDisabled", this, player.UserIDString), Font = "robotocondensed-regular.ttf", FontSize = 18, ...

Lang Key Required

Добавить новый ключ UIDisabled (~строка 4850, после UIEnabled):

["UIEnabled"] = "Enabled",
["UIDisabled"] = "Disabled",

How to Apply

  1. Найди ["UIEnabled"] = "Enabled", (~строка 4849)
  2. Добавь после неё строку: ["UIDisabled"] = "Disabled",
  3. Найди buff.Value.enabled ? "<color=#53ad2c>Enabled</color>" : "Disabled" (~строка 14761)
  4. Замени на buff.Value.enabled ? $"<color=#53ad2c>{lang.GetMessage("UIEnabled", this, player.UserIDString)}</color>" : lang.GetMessage("UIDisabled", this, player.UserIDString)

Modification #10: IsTreeCompleted API for SKILL_MAXED + SKILL_TREE_COMPLETED

Purpose: API метод для проверки прогресса прокачки дерева скиллов. Используется GoLootTracker для:

  • SKILL_MAXED — отправляется при каждом максе скилла, содержит maxedSkills/totalSkills для прогресса (например, "5/15 скиллов в Mining")
  • SKILL_TREE_COMPLETED — отправляется когда maxedSkills == totalSkills (все скиллы в дереве замакшены)

Location

  • Line: ~13343 (в #region API секции, после метода GetPlayerLevel)

New Code

/// <summary>
/// Check if a player has completed (maxed all skills in) a specific tree
/// Returns: object[] { bool isComplete, int totalSkills, int maxedSkills } or null if error
/// Used by GoLootTracker for SKILL_MAXED + SKILL_TREE_COMPLETED webhooks
/// </summary>
[HookMethod("IsTreeCompleted")]
public object IsTreeCompleted(BasePlayer player, string treeName)
{
if (player == null || string.IsNullOrEmpty(treeName))
return null;

Configuration.TreeInfo treeConfig;
if (!config.trees.TryGetValue(treeName, out treeConfig))
return null;

PlayerInfo playerData;
if (!pcdData.pEntity.TryGetValue(player.userID, out playerData))
return null;

int totalEnabled = 0;
int maxed = 0;

foreach (var node in treeConfig.nodes)
{
if (!node.Value.enabled) continue;
totalEnabled++;

int playerLevel;
if (playerData.buff_values.TryGetValue(node.Key, out playerLevel)
&& playerLevel >= node.Value.max_level)
{
maxed++;
}
}

bool isComplete = totalEnabled > 0 && maxed >= totalEnabled;
return new object[] { isComplete, totalEnabled, maxed };
}

How to Apply

  1. Найди #region API (~строка 13125)
  2. Найди метод GetPlayerLevel (~строка 13335)
  3. Добавь новый метод после GetPlayerLevel (перед ForceDropPouch)

Search Pattern

[HookMethod("GetPlayerLevel")]

Usage Example (GoLootTracker)

var result = SkillTree.Call("IsTreeCompleted", player, tree) as object[];
if (result != null && result.Length >= 3)
{
bool isComplete = (bool)result[0];
int totalSkills = (int)result[1];
int maxedSkills = (int)result[2];
}

Quick Apply Checklist

При обновлении плагина выполни следующие шаги:

Этап 1: Модификации кода плагина (SkillTree.cs)

Хуки и новые ключи:

  • Mod #1: Добавить хук STOnNodeLevelUp (~строка 10959)
  • Mod #2: Добавить ключ UINextRowUnlocksIn в DefaultMessages (~строка 4844)
  • Mod #9: Добавить ключ UIDisabled в DefaultMessages (~строка 4850)

API методы:

  • Mod #10: Добавить метод IsTreeCompleted в #region API (~строка 13343)

Локализация текстов (замена hardcoded → lang.GetMessage):

  • Mod #3: Tree title: tree.Replace('_', ' ')lang.GetMessage(tree, ...) (~строка 22101)
  • Mod #4: Next row: hardcoded "Next row unlocks in" → lang.GetMessage (~строка 22876)
  • Mod #5: Arrows: "< <" и "> >"lang.GetMessage (~строки 21933, 21954)
  • Mod #6: CLOSE: все "CLOSE"lang.GetMessage("UIClose", ...) (5 мест)
  • Mod #7: Settings: "Player Settings" и "Ultimate Settings"lang.GetMessage (~строки 21780, 21811)
  • Mod #9: Enabled/Disabled: hardcoded → lang.GetMessage (~строка 14761)

UI размеры для русских текстов:

  • Mod #8.1: Level Up button: сдвиг 30px вправо (-27.32/45.68)
  • Mod #8.2: Respec button: сдвиг 30px вправо (-28/45)
  • Mod #8.3: CLOSE buttons:
    • TreeNavButtons: -45/45
    • Buff Settings: -45/45
    • Player Settings: -374.71/-300.71
    • Ultimate Menu: -374.71/-300.71
  • Mod #8.4: Cost text: -110/110

Этап 2: Файл локализации (ru/SkillTree.json)

  • Скопировать переводы из секции "Russian Localization Keys"
  • Проверить Translation Adjustments (UIChange → СМЕНИТЬ)

Этап 3: Проверка

  • Перезагрузить плагин: o.reload SkillTree
  • Запустить Verification Commands
  • Проверить UI на русском языке

Russian Localization Keys

Новые ключи в DefaultMessages плагина

При модификации плагина добавляются эти ключи (в DefaultMessages словарь):

["UINextRowUnlocksIn"] = "<color=#f5d800>Next row unlocks in: <color=#0AC406>{0}</color> points</color>",
["UIDisabled"] = "Disabled", // Mod #9

Обязательные переводы в ru/SkillTree.json

{
"UINextRowUnlocksIn": "<color=#f5d800>Следующий ряд через: <color=#0AC406>{0}</color> очков</color>",
"UIDisabled": "Отключено",
"UIEnabled": "Включено",
"UIPlayerSettings": "<color=#ffb600>Настройки игрока</color>",
"UltimateSettings": "<color=#ffb600>Настройки ультимейтов</color>",
"UIClose": "ЗАКРЫТЬ",
"UIBackArrow": "< <",
"UINextArrow": "> >",
"UIChange": "СМЕНИТЬ"
}

Ключи деревьев навыков

{
"Mining": "Добыча руды",
"Woodcutting": "Рубка дерева",
"Skinning": "Свежевание",
"Harvesting": "Сбор урожая",
"Combat": "Боевые навыки",
"Medical": "Медицина",
"Build_Craft": "Крафт и строительство",
"Scavenging": "Мародёрство",
"Cooking": "Кулинария",
"Vehicles": "Транспорт",
"Electricity": "Электричество",
"Raiding": "Рейды",
"Mentality": "Ментальность"
}

Translation Adjustments (только файл локализации)

Эти изменения НЕ требуют модификации кода плагина — только файла ru/SkillTree.json:

КлючОригиналРекомендуемый переводПричина
UIChangeИЗМЕНИТЬСМЕНИТЬКороче на 1 букву, влезает в кнопку

Search Patterns for Finding Locations

Если номера строк изменились, используй эти паттерны для поиска:

ModificationSearch Pattern
#1 HookHandlePerms(player, tree, name, ni.level_current);
#2 Lang Key["UIUnlocksIn"]
#3 Tree Titletree.Replace('_', ' ').ToUpper()
#4 Next RowNext row unlocks in:
#5 ArrowsText = "< <" и Text = "> >"
#6 CloseText = "CLOSE"
#7 Settings (key)["UIPlayerSettings"] = "Player Settings"
#7 Settings (UI)Text = "<color=#ffb600>Player Settings и Ultimate Settings
#8 Level UpSkillTree_LevelUp + OffsetMin = "-57.32
#8 RespecSkillTree_RespecCost + OffsetMin = "-58
#8 CLOSE (TreeNav)SkillTree_close + OffsetMin = "-29
#8 CLOSE (Buff)SkillTree_BuffMenu_close + OffsetMin = "-29
#8 CLOSE (Player)SkillTree_Player_Settings + OffsetMin = "-390.71 -243
#8 CLOSE (Ultimate)SkillTree_UltimateMenu_close + OffsetMin = "-390.71 -201
#8 Cost textSendRespecBuyPanel + OffsetMin = "-68.137 28.482
#9 Enabled/Disabledbuff.Value.enabled ? "<color=#53ad2c>Enabled</color>" : "Disabled"
#9 UIDisabled key["UIEnabled"] = "Enabled", (добавить UIDisabled после)
#10 IsTreeCompleted[HookMethod("GetPlayerLevel")] (добавить после GetPlayerLevel)

Verification Commands

После применения всех модификаций запусти эти команды для проверки:

# Не должно быть результатов (hardcoded strings):
grep -n 'Text = "CLOSE"' SkillTree.cs
grep -n 'Text = "< <"' SkillTree.cs
grep -n 'Text = "> >"' SkillTree.cs
grep -n "tree.Replace('_', ' ').ToUpper()" SkillTree.cs
grep -n '"Next row unlocks in:' SkillTree.cs
grep -n 'Player Settings</color>"' SkillTree.cs
grep -n 'Ultimate Settings</color>"' SkillTree.cs
grep -n '"<color=#53ad2c>Enabled</color>" : "Disabled"' SkillTree.cs # Mod #9

# Должны быть результаты (проверка что lang.GetMessage используется):
grep -n 'lang.GetMessage("UIClose"' SkillTree.cs
grep -n 'lang.GetMessage("UIBackArrow"' SkillTree.cs
grep -n 'lang.GetMessage("UINextArrow"' SkillTree.cs
grep -n 'lang.GetMessage(tree, this' SkillTree.cs
grep -n 'lang.GetMessage("UINextRowUnlocksIn"' SkillTree.cs
grep -n 'lang.GetMessage("UIPlayerSettings"' SkillTree.cs
grep -n 'lang.GetMessage("UltimateSettings"' SkillTree.cs
grep -n 'lang.GetMessage("UIEnabled"' SkillTree.cs # Mod #9
grep -n 'lang.GetMessage("UIDisabled"' SkillTree.cs # Mod #9
grep -n 'STOnNodeLevelUp' SkillTree.cs # Mod #1
grep -n 'IsTreeCompleted' SkillTree.cs # Mod #10

# Проверка новых ключей в DefaultMessages:
grep -n '"UIDisabled"' SkillTree.cs # Mod #9
grep -n '"UINextRowUnlocksIn"' SkillTree.cs # Mod #2