SkillTree Plugin Modifications
Plugin: SkillTree by Whispers88 Source: Codefling File:
rust-template-private-main/SkillTree.csПри обновлении плагина до новой версии все модификации будут потеряны. Используй этот документ для повторного применения изменений.
Changelog
| Version | Date | Author | Description |
|---|---|---|---|
| 1.5 | 2026-01-23 | Claude | Add Mod #10: IsTreeCompleted API for SKILL_MAXED + SKILL_TREE_COMPLETED events |
| 1.4 | 2026-01-22 | Claude | Improve docs: structured checklist, complete Russian keys, Translation Adjustments section |
| 1.3 | 2026-01-22 | Claude | Add Mod #9: Enabled/Disabled localization in Buff Settings |
| 1.2 | 2026-01-22 | Claude | Update Mod #8: all CLOSE buttons, cost text width, buttons shift 30px |
| 1.1 | 2026-01-22 | Claude | Add Mod #7: Player/Ultimate Settings localization |
| 1.0 | 2025-01-22 | Claude | Initial 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
- Найди метод
HandlePerms(player, tree, name, ni.level_current); - Добавь после него 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
- Найди строку
["UIUnlocksIn"] = "<color=#f5d800>Unlocks in:</color>", - Добавь после неё новую строку с ключом
["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
- Найди
Text = tree.Replace('_', ' ').ToUpper() - Замени на
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
- Найди
string.Format("<color=#f5d800>Next row unlocks in: - Замени на
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
- Найди
Text = "< <"в методеTreeNavButtons - Замени на
Text = lang.GetMessage("UIBackArrow", this, player.UserIDString) - Найди
Text = "> >"там же - Замени на
Text = lang.GetMessage("UINextArrow", this, player.UserIDString)
Modification #6: CLOSE Buttons Localization
Purpose: Использование системы локализации для всех кнопок "CLOSE".
Locations (7 мест)
| Line | Method | Element Name |
|---|---|---|
| ~14687 | SkillTree_Buff_Settings | SkillTree_BuffMenu_close |
| ~15835 | ScoreBoardPanel | ScoreboardCloseLabel |
| ~15980 | SkillTree_UltimateMenu | SkillTree_UltimateMenu_close |
| ~19364 | ShowPrestigeRank | Button_6584 (CuiButton) |
| ~21973 | TreeNavButtons | SkillTree_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
- Найди все вхождения
Text = "CLOSE"в файле - Замени каждое на
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:
- UIPlayerSettings (~строка 4627) — ОБНОВИТЬ значение, добавив цвет:
// Было:
["UIPlayerSettings"] = "Player Settings",
// Стало:
["UIPlayerSettings"] = "<color=#ffb600>Player Settings</color>",
- UltimateSettings (~строка 4680) — уже существует с цветом, просто использовать
How to Apply
- Найди
["UIPlayerSettings"] = "Player Settings"(~строка 4627) - Замени на
["UIPlayerSettings"] = "<color=#ffb600>Player Settings</color>" - Найди
Text = "<color=#ffb600>Player Settings</color>"(~строка 21780) - Замени на
Text = lang.GetMessage("UIPlayerSettings", this, player.UserIDString) - Найди
Text = "<color=#ffb600>Ultimate Settings</color>"(~строка 21811) - Замени на
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
- Level Up: Найди
OffsetMin = "-57.32 -16", OffsetMax = "0.68 16", замени на-27.32 -16/45.68 16 - Respec: Найди
OffsetMin = "-58 -16", OffsetMax = "0 16", замени на-28 -16/45 16 - TreeNavButtons CLOSE: Найди
-29/29, замени на-45/45(2 места) - Buff Settings CLOSE: Найди
-29 -54.635/29 -22.635, замени на-45/45 - Player Settings CLOSE: Найди
-390.71 -243/-332.71 -211, замени на-374.71/-300.71 - Ultimate Menu CLOSE: Найди
-390.71 -201.1/-332.71 -169.1, замени на-374.71/-300.71 - 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
- Найди
["UIEnabled"] = "Enabled",(~строка 4849) - Добавь после неё строку:
["UIDisabled"] = "Disabled", - Найди
buff.Value.enabled ? "<color=#53ad2c>Enabled</color>" : "Disabled"(~строка 14761) - Замени на
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
- Найди
#region API(~строка 13125) - Найди метод
GetPlayerLevel(~строка 13335) - Добавь новый метод после
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
- TreeNavButtons:
- 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
Если номера строк изменились, используй эти паттерны для поиска:
| Modification | Search Pattern |
|---|---|
| #1 Hook | HandlePerms(player, tree, name, ni.level_current); |
| #2 Lang Key | ["UIUnlocksIn"] |
| #3 Tree Title | tree.Replace('_', ' ').ToUpper() |
| #4 Next Row | Next row unlocks in: |
| #5 Arrows | Text = "< <" и Text = "> >" |
| #6 Close | Text = "CLOSE" |
| #7 Settings (key) | ["UIPlayerSettings"] = "Player Settings" |
| #7 Settings (UI) | Text = "<color=#ffb600>Player Settings и Ultimate Settings |
| #8 Level Up | SkillTree_LevelUp + OffsetMin = "-57.32 |
| #8 Respec | SkillTree_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 text | SendRespecBuyPanel + OffsetMin = "-68.137 28.482 |
| #9 Enabled/Disabled | buff.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