diff --git a/art/flashFiles/Alphabet_Bold-CyrAddon.fla b/art/flashFiles/Alphabet_Bold-CyrAddon.fla
new file mode 100644
index 000000000..dc7c8e12c
Binary files /dev/null and b/art/flashFiles/Alphabet_Bold-CyrAddon.fla differ
diff --git a/assets/data/alphabet/bold.xml b/assets/data/alphabet/bold.xml
index 2fb3ccaec..c1f58b03a 100644
--- a/assets/data/alphabet/bold.xml
+++ b/assets/data/alphabet/bold.xml
@@ -135,4 +135,22 @@
+
+
+ character-n0
+
+
+
+
+
+
+
+
+
+
+
+
+ character-three0
+ character-щ
+ character-ц
\ No newline at end of file
diff --git a/assets/images/menus/alphabet-bold.png b/assets/images/menus/alphabet-bold.png
index 8ded5848c..33f5bbbfb 100644
Binary files a/assets/images/menus/alphabet-bold.png and b/assets/images/menus/alphabet-bold.png differ
diff --git a/assets/images/menus/alphabet-bold.xml b/assets/images/menus/alphabet-bold.xml
index 258ad0978..4ca59c8bb 100644
--- a/assets/images/menus/alphabet-bold.xml
+++ b/assets/images/menus/alphabet-bold.xml
@@ -1,282 +1,346 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/languages/en/Editors.xml b/assets/languages/en/Editors.xml
index ae4c27e16..c57216a06 100644
--- a/assets/languages/en/Editors.xml
+++ b/assets/languages/en/Editors.xml
@@ -341,7 +341,7 @@
Press ACCEPT to edit this character.
New Character
Press ACCEPT to create a new character.
- Select a character to edit
+ Select a character to edit.
Select a character to edit in {0}
@@ -432,6 +432,7 @@
Animation
Position (X, Y)
FPS
+ Looping?
Indices (Frames)
@@ -447,7 +448,7 @@
Character Name $* Required$
Character Image File $* Required$
-
+
Creating Character: Error!
The character you are trying to create already exists, if you would like to override it delete the character first!
@@ -459,7 +460,7 @@
Press ACCEPT to edit this typeface.
New Typeface
Press ACCEPT to create a new typeface.
- Select a typeface to edit
+ Select a typeface to edit.
New Typeface: Feature Not Implemented!
@@ -481,6 +482,7 @@
Undo
Redo
+ Edit Main Data
Glyph
@@ -510,6 +512,12 @@
Zoom out
Reset Zoom
+
+ Tape
+
+ Move Tape Left
+ Move Tape Right
+
@@ -550,9 +558,9 @@
Zoom in
Zoom out
Reset Zoom
- Focus Dad
+ Focus Opponent
Focus GF
- Focus BF
+ Focus Player
Editor
@@ -591,7 +599,7 @@
Editing Character "{0}"
Editing Sprite "{0}"
- Editing XML <{0} />
+ Editing XML <{0}/>
Character Data
Sprite Data
@@ -622,7 +630,7 @@
BEAT
LOOP
- Tip: To access custom properties,\nHold Shift when clicking edit
+ Tip: To access custom properties,\nHold Shift when clicking edit button.
diff --git a/assets/languages/en/Options.xml b/assets/languages/en/Options.xml
index 68862baca..95a61568d 100644
--- a/assets/languages/en/Options.xml
+++ b/assets/languages/en/Options.xml
@@ -16,7 +16,7 @@
Appearance
Change Appearance options such as Flashing menus...
- Change more advanced options such as VRAM-Only Sprites, Antialiasing, Shaders
+ Change more advanced options such as VRAM-Only Sprites, Antialiasing, Shaders...
Language
Change the language that the engine uses.
diff --git a/assets/languages/en/config.ini b/assets/languages/en/config.ini
index b020d2213..01b746fd9 100644
--- a/assets/languages/en/config.ini
+++ b/assets/languages/en/config.ini
@@ -1,6 +1,6 @@
name="English"
credits="Codename Crew"
-version="1.0.0"
+version="1.0.1"
; Moving these in the wiki when releasing
; Shows missing ID:s as {id} and prints in the console Missing Translation IDs: id
diff --git a/assets/languages/ru/Editors.xml b/assets/languages/ru/Editors.xml
new file mode 100644
index 000000000..9f760b554
--- /dev/null
+++ b/assets/languages/ru/Editors.xml
@@ -0,0 +1,680 @@
+
+
+
+ Автосохранение через {0} секунд{1}
+ (Отменено)!
+
+ Ок
+ Отмена
+ Сохранить
+ Сохранить и Закрыть
+ Закрыть
+ Не Cейчас
+ Да
+
+
+
+ Символ
+ Анимация
+ Атлас
+ Спрайтлист
+ (-а, -ов)
+ (-и, -й)
+
+ Путь ({0}/)
+ Найден {0} {1}
+ Найдено {0} {1}
+ #{0} НЕ найден(-а)#
+ Найден {0} Спрайтлист
+ Найдено {0} Спрайтлиста(-ов)
+
+ Следующие файлы уже существуют: \n\n{0}\n\nВАЖНО: ПЕРЕЗАПИСЫВАНИЕ ОТМЕНИТЬ НЕЛЬЗЯ!
+ Перезаписать Файлы
+ Использовать Существующие
+
+
+
+ Редактор Алфавита
+ Редактор Чартов
+ Редактор Персонажей
+ Редактор Cцен
+ Дебаг UI
+ Вики
+ Настройки Отладки
+
+
+
+
+ Выберите песню для измениния чарта.
+ Нажмите ПРИНЯТЬ чтобы выбрать сложность.
+ Нажмите ПРИНЯТЬ чтобы выбрать песню.
+ Нажмите ПРИНЯТЬ чтобы редактировть чарт выбранной сложности.
+ Выберите сложность чтобы продолжить.
+ Новая Сложность
+ Нажмите ПРИНЯТЬ чтобы создать новую сложность.
+ Новая Песня
+ Нажмите ПРИНЯТЬ чтобы создать новую песню.
+ Новая Вариация
+ Нажмите ПРИНЯТЬ чтобы создать новую вариацию песни.
+
+
+
+ Создание Нового Чарта
+ Информация о Чарте
+ Название Сложности
+ Сцена
+ Скорость Стрелок
+
+ Струмлайны $* Требуется Минимум 1 Струмлайн$
+ Страмлайн - #{0}
+
+
+ Создание Песни: Ошибка!
+ Песня, которую вы пытаетесь создать, уже существует. Если вы хотите пересоздать её, то сначала удалите существующую песню!
+ Создание Чарта: Ошибка!
+ Чарт, который вы пытаетесь создать, уже существует. Если вы хотите пересоздать его, то сначала удалите существующий чарт!
+
+
+
+
+ Свойства Чарта
+ Данные Чарта
+ Сцена
+ Скорость Стрелок
+
+
+
+ Степ: {0}
+ Бит: {0}
+ Такт: {0}
+ Размер: {0}/{1}
+
+
+
+ Создать Группу Событий
+ Редактировать Группу Событий
+
+ Нет События
+
+ Струмлайн #{0} ({1})
+
+
+
+ Выберите Тип События...
+
+
+
+ Редактировать Метаданные
+
+ Данные Песни
+ Название Песни
+ Вариация Песни
+ Размер Такта
+
+ Отображаемое Имя
+ Иконка
+ Разрешенные Режимы
+ Цвет
+ Сложности
+ Кастомные Значения (Продвинутое)
+ Нужны Вокалы
+
+ Режим Оппонента
+ Ко-оп мод
+
+
+
+ Редактор Нот
+
+ Редактировать Ноты
+ Новая нота {0}
+
+
+
+ Создание Струмлайна {0}
+ Редактирование Свойств Струмлайна {0}
+
+ Создать Новый Струмлайн
+ Редактировать Свойства Струмлайна
+
+
+
+ Создание Новой Песни
+ Импорт Песни
+ Информация о Песне
+
+ Инструментал $* Обязательно*$
+ Вокал
+
+ Импортировать из...
+ Источник Импорта:
+ Проект V-Slice (.fnfc)
+ Формат Чарта
+ Добавить Аудио
+ Имя Файла Песни $* Обязательно$
+ Файл Данных/Чарта $* Обязательно$
+ Мета Файл $* Обязательно$
+
+ Назад
+ Далее
+
+
+
+ Персонажи
+ Новый Перс
+ Тип
+ Скорость Стрелок
+ Позиция На Сцене
+ Размер
+ Интервал
+ Hud Позиция (X [Между 0-1],Y)
+ Виден?
+ Использовать из чарта?
+ Суффикс Вокала
+ Количество Клавиш
+
+
+
+
+
+ Файл
+
+ Создать
+ Сохранить
+ Сохранить Как...
+ Сохранить Глобальные События
+ Сохранить Глобальные События Как...
+ Сохранить без Локальных Событий
+ Сохранить без Локальных Событий Как...
+ Сохранить Метаданные
+ Сохранить Метаданные Как...
+ Экспорт в FNF Legacy...
+ Экспорт в Psych Engine...
+ Выход
+
+
+ Правка
+
+ Отменить
+ Вернуть изменение
+ Копировать
+ Вставить
+ Вырезать
+ Удалить
+
+
+ Чарт
+
+ Плэйтест
+ Плэйтест с этого места
+ Плэйтест за оппонента
+ Плэйтест за оппонента с этого места
+ Включить скрипты при тесте
+ Редактировать данные чарта
+ Редактировать метаданные
+
+
+ Вид
+
+ Увеличить
+ Уменьшить
+ Сбросить Масштаб
+ Показать Разделители Секций
+ Показать Разделители Битов
+ Радужные Волны
+ Упрощенные Волны
+ Сместиться Влево
+ Сместиться Вправо
+ Сбросить Смещение
+
+
+ Песня
+
+ В начало
+ В конец
+ Добавить камеру на Оппонента
+ Добавить камеру на Игрока
+ Заглушить инструментал
+ Заглушить вокал
+
+
+
+ Добавить Закладку
+ Редактировать Закладки
+ Перейти к "{0}"
+ Создание Закладки...
+ Название:
+ Цвет:
+ Список Закладок
+ Редактировать
+ Новая Закладка
+
+
+ Нота
+
+ Увеличить длительность
+ Уменьшить длительность
+ Выбрать все
+ Выбрать такт
+ Редактировать Типы Нот
+
+ Сетка
+
+ ↑ Привязка к Сетки
+ Сбросить Привязку
+ ↓ Привязка к Сетки
+
+ Сетка {0}x
+
+
+ Воспроизведение
+
+ Старт/Пауза
+ ↑ Скорость {0}%
+ Сбросить скорость
+ ↓ Скорость {0}%
+ Пред. секция
+ След. секция
+ Начало секции
+ Пред. степ
+ След. степ
+ Метроном
+ Визуальный метроном
+
+
+
+
+ Стандартная Нота
+
+
+
+ Вызов HScript
+ Движение Камеры
+ Добавить Зум Камеры
+ Изменение Модуля Камеры
+ Флешка
+ Изменение BPM
+ Изменение Скорости Стрелок
+ Переключение на Альт. анимацию
+ Проиграть анимацию
+
+
+
+ Опции ↓
+
+ Звуки попаданя
+ Выкл. Вокал
+ Редактировать
+ Удалить
+
+ Без Волны
+
+
+ Создать
+ Заблок./Разблок.
+
+ Локальные События\n(Только Эта Сложность)
+ Глобальные События\n(Все Сложности)
+ Лок. Событие
+ Глоб. Событие
+
+ Добавить
+ Редактировать
+ Удалить
+
+
+ Чарт сохранен в {0}!
+
+
+
+
+
+
+ Нажмите ПРИНЯТЬ чтобы редактировать эту папку.
+ Нажмите ПРИНЯТЬ чтобы редактировать этого персонажа.
+ Новый Персонаж
+ Нажмите ПРИНЯТЬ чтобы создать нового персонажа.
+ Выберите персонажа для редактирования.
+ Выберите персонажа для редактирования в {0}
+
+
+
+ Редактирование Персонажа
+ Свойства Персонажа
+ Иконка
+ Цвет Иконки
+ Длительность Анимации Пения
+ Исп. Длительность Пения?
+ Кастомные Значения (Продвинутое)
+
+
+
+
+ Файл
+
+ Создать
+ Сохранить
+ Сохранить как...
+ Выход
+
+
+ Правка
+
+ Копировать Смещение
+ Вставить Смещение
+ Отменить
+ Вернуть изменение
+ Редактировать информацию
+ Редактировать спрайт
+
+
+ Смещение
+
+ Влево
+ Вверх
+ Вниз
+ Вправо
+
+
+
+
+ Перетаскивать Мышью?
+ Сбросить Смещение
+
+
+ Сцена
+
+ Использовать "{0}"
+ Без Сцены
+
+
+ Вид
+
+ Увеличить
+ Уменьшить
+ Сбросить Масштаб
+ Показать Хитбокс Персонажа?
+ Показать Камеру Персонажа?
+ Показать Ось Координат?
+
+
+ Анимация
+
+ Запустить
+ Остановить
+ Пред. Анимация
+ След. Анимация
+ Проиграть со Смещением?
+
+
+
+ Позиция (X, Y)
+ Размер
+ Редакт. Информацию
+ Редакт. Спрайт
+ Позиция Камеры (X, Y)
+ Отразить?
+ Сгладить?
+ Проверить как...
+ Поставить как...
+
+
+
+ Новая Анимация
+ Название
+ Анимация
+ Позиция (X, Y)
+ Зациклить?
+ Индексы кадров
+
+
+
+ Редактирование спрайта
+ Файл Изображения $* Обязательно$
+
+
+
+
+
+ Создание Нового Персонажа
+ Имя $* Обязательно$
+ Файл Изображения $* Обязательно$
+
+
+ Создание Персонажа: Ошибка!
+ Персонаж, которого вы пытаетесь создать, уже существует. Если вы хотите пересоздать его, то сначала удалите существующего персонажа!
+
+
+
+
+
+
+ Нажмите ПРИНЯТЬ чтобы редактировать шрифт.
+ Новый Шрифт
+ Нажмите ПРИНЯТЬ чтобы создать новый шрифт.
+ Выберите шрифт для редактирования.
+
+
+ Новый Шрифт: Функция Не Реализована!
+ Эта функция еще не реализована. Пожалуйста, дождитесь новых обновлений CNE, чтобы получить её.\n\n\n- Codename Crew
+
+
+
+
+
+ Файл
+
+ Создать
+ Сохранить
+ Сохранить как...
+ Выход
+
+
+ Правка
+
+ Отменить
+ Вернуть изменение
+ Редактирование Основных Данных
+
+
+ Глиф
+
+ Новый Глиф
+ Редактировать Глиф
+ Удалить Глиф
+ Удалить Текущий Глиф
+
+
+ Смещение
+
+ Влево
+ Вверх
+ Вниз
+ Вправо
+
+
+
+
+ Сбросить Смещение
+
+
+ Вид
+
+ Увеличить
+ Уменьшить
+ Сбросить Масштаб
+
+
+ Лента
+
+ Переместиться Влево
+ Переместиться Вправо
+
+
+
+
+
+
+
+ Выберите сцену для редактирования. Сцены, написанные только на HSCRIPT-е, не поддерживаются.
+ Нажмите ПРИНЯТЬ чтобы редактировать сцену.
+ Новая Сцена
+ Нажмите ПРИНЯТЬ чтобы создать новую сцену.
+
+
+
+
+ Файл
+
+ Сохранить
+ Сохранить как...
+ Выход
+
+
+ Правка
+
+ Отменить
+ Вернуть изменение
+ Редактировать информацию сцены
+
+
+ Выделение
+
+ Выделить все
+ Отменить Выделение
+ Инвертировать Выделение
+
+
+ Вид
+
+ Увеличить
+ Уменьшить
+ Сбросить Масштаб
+ Фокус На Оппонента
+ Фокус На GF
+ Фокус На Игрока
+
+
+ Редактор
+
+ Показать Персонажей
+
+
+
+ Редактирование спрайта сцены
+ Файл Изображения $* Обязательно$
+
+
+
+
+
+ Создание Новой Сцены
+ Информация о Сцене
+ Название
+ Директория Сцены
+
+
+ Создание сцены: Ошибка!
+ Сцена уже существует! Для перезаписи сначала удалите существующую стадию!
+
+
+
+
+ Редактирование сцены "{0}"
+ Информация о Сцене
+ Название
+ Директория Спрайтов\n(Требуется Перезагрузка)
+ Стартовая позиция камеры (X, Y)
+ Зум Камеры
+
+
+
+ Редактирование Персонажа "{0}"
+ Редактирование Спрайта "{0}"
+ Редактирование XML <{0}/>
+
+ Данные Персонажа
+ Данные Спрайта
+ Данные XML
+
+ Имя Элемента
+ Идентификатор
+ Файл Изображения (WIP: нужна перезагрузка)\nВ (${stage.spritesParentFolder})
+ Скролл {0}
+ Размер {0}
+ {0} камеры
+ Отступы (X, Y)
+ Наклон {0}
+ Прозрачность
+ Угол
+ Коэфицент Масштаба
+ Название Позиции
+ Отразить по X
+ Сглаживание
+ Высокая Нагрузка
+ Экономия Памяти
+ Атрибуты
+ Предпросмотр трансформации:
+
+ Тип Анимации
+
+ НЕТУ
+ В БИТ
+ ЦИКЛ
+
+ Совет: Для получения доступа к пользовательским свойствам\nудерживайте Shift при нажатии на кнопку "Редактировать".
+
+
+
+ Редактирование XML {0}
+ Данные XML
+ Атрибуты
+
+
+ Этот персонаж обязательно должен быть на сцене!
+ Вы не можете удалить GF
+
+
+ Масштаб: {0}, {1}
+ Скролл: {0}, {1}
+
+
+
+ Спрайты Cцены
+ Спрайт
+ Коробка
+ Персонаж
+ Создание коробок еще не реализовано!
+
+
+
+
+ Выйти Из Игры
+
+ Сохранить и Выйти Из Игры
+ Сохранить и Выйти в Меню
+ Отмена
+
+ НЕСОХРАНЕННЫЕ ИЗМЕНЕНИЯ!
+ Ваши изменения будут *потеряны*, если вы не сохраните их. (Невозможно будет восстановить)\n\n\nВы точно хотите Выйти?
+
+
+
+ Несохраненные изменения!
+ Ваши изменения будут потеряны, если вы не сохраните их. (Невозможно будет восстановить)\n\n\nВы точно хотите Выйти?
+
+ Выйти Из Игры
+
+ Сохранить и Выйти
+ Сохранить и Выйти в Меню
+ Отмена
+
+
+
+ Отсутствует конфигурация папки мода!
+ У вашего мода отстутствует файл конфигурации!\n\nХотите ли вы автоматически сгенерировать его?\n\n(PS: Если это не ваш мод, то пожалуйста, отключите режим Разработчика, чтобы это всплывающее окно не появлялось.)
+
+ Конфигурация мода создана!
+ Ваш файл конфигурации был создан в папке {0}!
+
+
\ No newline at end of file
diff --git a/assets/languages/ru/Main.xml b/assets/languages/ru/Main.xml
new file mode 100644
index 000000000..37765f359
--- /dev/null
+++ b/assets/languages/ru/Main.xml
@@ -0,0 +1,96 @@
+
+
+
+ Очки: {0}
+ Промахи: {0}
+ Срывы Комбо: {0}
+ Точность:{0} - {1}
+ Комбо: {0}
+
+ [Н/Д]
+
+
+
+ ОЧКИ ЗА НЕДЕЛЮ: {0}
+ ТРЕКИ
+
+
+
+ ЛУЧШИЙ РЕЗУЛЬТАТ: {0}
+ Соло
+ Режим Оппонента
+ Ко-оп мод
+ Ко-оп мод (Инверсия)
+
+
+
+
+ Продолжить
+ Перезапустить
+ Изменить Управление
+ Настройки
+
+ Выйти в Редактор
+ Продолжить Катсцену
+ Пропустить Катсцену
+ Перезапустить Катсцену
+
+
+ Отбитые яица: {0}
+ КО-ОП МОД
+ РЕЖИМ ОППОНЕНТА
+
+
+
+
+ *- Публичный участник команды разработчиков!*
+ Всего вкладов: ~{0}~ / *{1}* (~{2}%~) — выберите, чтобы открыть аккаунт на GitHub
+ Загрузка списка...
+ Все участники разработки движка! — Нажмите СБРОС, чтобы обновить список (не чаще одного раза в 2 минуты).
+
+
+ Авторы
+ Люди, благодаря которым это стало возможным!
+ Выберите этот пункт, чтобы увидеть всех разработчиков движка!
+ Выберите этот пункт, чтобы открыть страницу оригинальной игры на itch.io и поддержать разработчиков!
+
+
+
+
+ Отключить Моды
+
+
+
+ Коммит: {0} ({1})
+ [{0}] Открыть Меню Модов
+
+
+
+
+ НОВОЕ ОБНОВЛЕНИЕ
+ УСТАНОВИТЬ
+ ПРОПУСТИТЬ
+
+
+ Подготовка к установке обновления...
+ Создание папки установки и очистка старых файлов обновлений...
+
+ Загрузка ресурсов обновления...
+ Загрузка файла {0}
+
+ Загрузка нового исполняемого файла движка...
+ Загрузка {0}
+
+ Установка новых файлов...
+ Установка {0}
+
+
+
+
+ Лёгкая
+ Нормальная
+ Сложная
+ Эрект
+ Кошмарная
+
+
\ No newline at end of file
diff --git a/assets/languages/ru/Options.xml b/assets/languages/ru/Options.xml
new file mode 100644
index 000000000..1a9bd2eb4
--- /dev/null
+++ b/assets/languages/ru/Options.xml
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+ Управление
+ Измените Управление для двух игроков!
+
+ Геймплэй
+ Измените такие параметры Геймплэя, как Downscroll, Скорость Стрелок, Цензура...
+ Измените такие дополнительные параметры, как Потоковое Аудио...
+
+ Внешний Вид
+ Измените параметры Внешнего Вида, например, Мигание Меню...
+ Измените такие дополнительные параметры, как Загрузка в VRAM, Сглаживание, Шейдеры...
+
+ Язык
+ Измените язык, который использует движок.
+
+ Разное
+ Используйте это меню для сброса сохраненных данных или настройки движка.
+
+ Дебаг
+ Настройки Дебага для Режима Разработчика.
+
+
+
+ Влево
+ Вниз
+ Вверх
+ Вправо
+
+ Ноты
+
+ Интерфейс
+
+ Выбрать
+ Назад
+ Сброс
+ Пауза
+ Изм. Режим
+
+
+ Движок
+
+ Смен. Мод
+
+
+ Громкость
+ Больше
+ Меньше
+ Заглушить
+
+ Разработчик
+
+
+ Открыть Консоль
+ Перезагрузить Стейт
+
+
+
+
+ Частота Кадров
+ Думаю и так понятно, да?
+
+
+
+
+ Цветное Здоровье
+ Если выключено, то будет использоваться оригинальная красно-зелёная шкала здоровья из 6-й недели FNF.
+
+ Если включено, то на 6-й неделе и других пиксельных сценах будет включён эффект Pixel Perfect, который выравнивает каждый пиксель на экране.
+
+
+ Качество
+ Режимы качества: "НИЗКОЕ" = отключает все возможные тяжёлые визуальные эффекты, чтобы сделать игровой процесс комфортнее; "ВЫСОКОЕ" = включает все визуальные эффекты ценой производительности; "ПОЛЬЗОВАТЕЛЬСКОЕ" = позволяет настроить дополнительные параменты в ручную.
+ НИЗКОЕ
+ ВЫСОКОЕ
+ ПОЛЬЗОВАТ.
+
+ Сглаживание
+ Если выключено, то сглаживание на всех спрайтах будет отключено. Это повысит производительность, но спрайты станут более резкими и пиксельными.
+
+ Экономия Памяти
+ Если включено, то некоторые фоновые элементы сцен будут отключены для снижения потребления памяти.
+
+ Игровые Шейдеры
+ Если выключено, то игровые шейдеры (такие как Thorns's Chromatic Aberration) не будут загружаться; это может быть полезно для слабых устройств.
+
+ Загрузка в VRAM
+ Если включено, то изображения будут храниться только в видеопамяти, освобождая МНОГО ОЗУ (ЭКСПЕРИМЕНТАЛЬНО). Если выключить эту опцию, то будет потреблять много памяти, особенно на больших спрайтах. Если вы не уверены, то оставьте эту опцию включённой.
+
+
+
+
+ Если включено, то ноты будут двигаться не снизу-вверх, а сверху-вниз, будто они падают.
+
+ Если выключено, то любое нажатие НЕ по стрелкам будет защитываться как промах.
+
+ Цензура
+ Если выключено, то катсцены на 7-й недели и другие эллементы будут зацензурены.
+
+ Зум Камеры в Бит
+ Если выключено, то камера перестанет зумится каждые 4 бита.
+
+ Автопауза
+ Если включено, то при расфокусировке окна игра будет ставиться на паузу.
+
+ Громкость Музыки
+ Изменяет громкость музыки.
+
+ Громкость Эффектов
+ Изменяет громкость звуковых эффектов.
+
+ Смещение Песни
+ Изменяет задержку, с которой должна начинаться песня.
+
+
+ Размер Окна
+ ...
+
+ Потоковая Музыка
+ Если включено, то музыка будет воспроизводиться в потоковом режиме, что экономит память, но увеличивает нагрузку на процессор при одновременном воспроизведении нескольких треков (ЭКСПЕРИМЕНТАЛЬНО). Если отключить эту опцию, то будет расходоваться много памяти, особенно на длинных треках. Если вы не уверены, то оставьте эту опцию включённой.
+
+ Потоковые Вокалы
+ Если включено вместе с пунктом "Потоковая Музыка", то вокалы также будут воспроизводиться в потоковом режиме, что повлияет на производительность, особенно если в песне много вокальных дорожек (ЭКСПЕРИМЕНТАЛЬНО). Если вы не уверены, то оставьте эту опцию выключенной.
+
+
+
+
+ Язык
+ Язык от {0} (Версия: {1})
+
+
+
+ Принудительный Краш
+ Выберите, чтобы специально вызвать сбой.
+
+ Ночные Сборки
+ Если включено, то в проверку обновлений также будут включаться ночные сборки (последние коммиты с репозитория движка, в основном, с использованием сборок Actions).
+
+ Проверить Обновления
+ Выберите, чтобы проверить наличие обновлений движка.
+ Обновлений не найдено.
+
+ Режим Разработчика
+ Если включено, то вы сможете получить доступ к функциям разработчика, таким как: особые привязки клавиш, редакторы, опции разработчика, перезагрузка стейтов, консоль и многое другое.
+
+ Пред. от Модпаков
+ Если включено, то при запуске игры будет появляться всплывающее окно с предупреждением, что в модпаке есть проблемы, например, отсутствие конфигов, несовместимые версии и т.д.
+
+ Сбросить Сохранения
+ Выберите, чтобы удалить сохранения. Это привидёт к удалению всех ваших рекордов.
+
+
+
+ Параметры Дебага
+ Используйте это меню, чтобы включать и выключать дебаг-параметры.
+
+ Показать Консоль
+ Выберите, чтобы открыть дебаг-консоль, которая содержит информацию о работе игры.
+
+ Изм. Редакакторы
+ Если включено, то редакторы смогут рендерить за пределами базового расширения 1280x720 из FNF (что позволит увеличить детализацию и пространство...)
+
+ Снять Лимиты Размера
+ Отключает минимальное разрешение для изменения размера редакторов (используется со включённым параметром "Изменяемые Редакакторы").
+
+ Звуки в Редакторах
+ Если включено, то в редакторах появятся звуковые эффекты (например, при установке галочек...)
+
+ Форм. Чарта
+ Если включено, то сохранённые файлы из редактора чартов будут отформатированы таким образом, чтобы их можно было легко прочитать.
+
+ Форм. Персонажей
+ Если включено, то сохранённые файлы из редактора персонажей будут отформатированы таким образом, чтобы их можно было легко прочитать.
+
+ Форм. Сцен
+ Если включено, то сохранённые файлы из редактора сцен будут отформатированы таким образом, чтобы их можно было легко прочитать.
+
+ Интенсивное Размытие
+ Если включено, то будет использоваться более сильное размытие, которое выглядит лучше, но может замедлить игру.
+
+ Автосохранения
+ Если включено, то редакторы будут автоматически сохранять файлы с настройками ниже.
+
+ Время
+ Определяет, как часто редактор будет автосохранять ваш файл (в секундах...)
+
+ Время Пред.
+ Определяет, как долго редактор будет держать окно предупреждения о автосохранении перед сохранением (в секундах... 0 = отключить)
+
+ Папка Автосохранений
+ Если включено, то автосохранения будут сохранятся в отдельную папку с временной отметкой, а не перезаписываться в текущий файл. (song/autosaves/)
+
+ Смещение в Чартах
+ Если включено, то параметр "Смещение Песни" будет работать ещё и в Редакторе Чартов.
+
+
+
\ No newline at end of file
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/credits.png b/assets/languages/ru/assets/images/menus/mainmenu/credits.png
new file mode 100644
index 000000000..a4e208bd0
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/mainmenu/credits.png differ
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/credits.xml b/assets/languages/ru/assets/images/menus/mainmenu/credits.xml
new file mode 100644
index 000000000..14c211ae7
--- /dev/null
+++ b/assets/languages/ru/assets/images/menus/mainmenu/credits.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/donate.png b/assets/languages/ru/assets/images/menus/mainmenu/donate.png
new file mode 100644
index 000000000..14963a46c
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/mainmenu/donate.png differ
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/donate.xml b/assets/languages/ru/assets/images/menus/mainmenu/donate.xml
new file mode 100644
index 000000000..ee705e278
--- /dev/null
+++ b/assets/languages/ru/assets/images/menus/mainmenu/donate.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/freeplay.png b/assets/languages/ru/assets/images/menus/mainmenu/freeplay.png
new file mode 100644
index 000000000..b8335d9f3
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/mainmenu/freeplay.png differ
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/freeplay.xml b/assets/languages/ru/assets/images/menus/mainmenu/freeplay.xml
new file mode 100644
index 000000000..46ffcd83a
--- /dev/null
+++ b/assets/languages/ru/assets/images/menus/mainmenu/freeplay.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/options.png b/assets/languages/ru/assets/images/menus/mainmenu/options.png
new file mode 100644
index 000000000..2e0b80a8f
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/mainmenu/options.png differ
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/options.xml b/assets/languages/ru/assets/images/menus/mainmenu/options.xml
new file mode 100644
index 000000000..0fc4785f5
--- /dev/null
+++ b/assets/languages/ru/assets/images/menus/mainmenu/options.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/story mode.png b/assets/languages/ru/assets/images/menus/mainmenu/story mode.png
new file mode 100644
index 000000000..46d889757
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/mainmenu/story mode.png differ
diff --git a/assets/languages/ru/assets/images/menus/mainmenu/story mode.xml b/assets/languages/ru/assets/images/menus/mainmenu/story mode.xml
new file mode 100644
index 000000000..45969af59
--- /dev/null
+++ b/assets/languages/ru/assets/images/menus/mainmenu/story mode.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/languages/ru/assets/images/menus/storymenu/weeks/tutorial.png b/assets/languages/ru/assets/images/menus/storymenu/weeks/tutorial.png
new file mode 100644
index 000000000..1560320fe
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/storymenu/weeks/tutorial.png differ
diff --git a/assets/languages/ru/assets/images/menus/storymenu/weeks/week1.png b/assets/languages/ru/assets/images/menus/storymenu/weeks/week1.png
new file mode 100644
index 000000000..5e82ed05c
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/storymenu/weeks/week1.png differ
diff --git a/assets/languages/ru/assets/images/menus/storymenu/weeks/week2.png b/assets/languages/ru/assets/images/menus/storymenu/weeks/week2.png
new file mode 100644
index 000000000..13ec3009a
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/storymenu/weeks/week2.png differ
diff --git a/assets/languages/ru/assets/images/menus/storymenu/weeks/week3.png b/assets/languages/ru/assets/images/menus/storymenu/weeks/week3.png
new file mode 100644
index 000000000..15a0a6f1c
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/storymenu/weeks/week3.png differ
diff --git a/assets/languages/ru/assets/images/menus/storymenu/weeks/week4.png b/assets/languages/ru/assets/images/menus/storymenu/weeks/week4.png
new file mode 100644
index 000000000..23c3571a2
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/storymenu/weeks/week4.png differ
diff --git a/assets/languages/ru/assets/images/menus/storymenu/weeks/week5.png b/assets/languages/ru/assets/images/menus/storymenu/weeks/week5.png
new file mode 100644
index 000000000..9bd318988
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/storymenu/weeks/week5.png differ
diff --git a/assets/languages/ru/assets/images/menus/storymenu/weeks/week6.png b/assets/languages/ru/assets/images/menus/storymenu/weeks/week6.png
new file mode 100644
index 000000000..5695e752e
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/storymenu/weeks/week6.png differ
diff --git a/assets/languages/ru/assets/images/menus/storymenu/weeks/week7.png b/assets/languages/ru/assets/images/menus/storymenu/weeks/week7.png
new file mode 100644
index 000000000..b1601eaa4
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/storymenu/weeks/week7.png differ
diff --git a/assets/languages/ru/assets/images/menus/titlescreen/titleEnter.png b/assets/languages/ru/assets/images/menus/titlescreen/titleEnter.png
new file mode 100644
index 000000000..774533e57
Binary files /dev/null and b/assets/languages/ru/assets/images/menus/titlescreen/titleEnter.png differ
diff --git a/assets/languages/ru/assets/images/menus/titlescreen/titleEnter.xml b/assets/languages/ru/assets/images/menus/titlescreen/titleEnter.xml
new file mode 100644
index 000000000..50b2b9a08
--- /dev/null
+++ b/assets/languages/ru/assets/images/menus/titlescreen/titleEnter.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/languages/ru/config.ini b/assets/languages/ru/config.ini
new file mode 100644
index 000000000..1a8138a9a
--- /dev/null
+++ b/assets/languages/ru/config.ini
@@ -0,0 +1,3 @@
+name="Русский"
+credits="Endr-Port"
+version="1.0.1"
\ No newline at end of file
diff --git a/source/funkin/backend/utils/TranslationUtil.hx b/source/funkin/backend/utils/TranslationUtil.hx
index 3f8095b94..bb84abd68 100644
--- a/source/funkin/backend/utils/TranslationUtil.hx
+++ b/source/funkin/backend/utils/TranslationUtil.hx
@@ -84,28 +84,30 @@ final class TranslationUtil
* If `name` is `null`, its gonna use the current language.
* If `name` is not `null`, it will load the translations for the given language.
*/
- public static function setLanguage(?name:String):Void {
+ public static function setLanguage(?name:String, ?noLogs = false):Void {
#if TRANSLATIONS_SUPPORT
if(name == null) name = curLanguage;
if(!langConfigs.exists(name)) name = Flags.DEFAULT_LANGUAGE;
if(!langConfigs.exists(name)) name = foundLanguages[0];
- if(curLanguage != name) {
- Logs.traceColored([
- Logs.getPrefix("Language"),
- Logs.logText("Changing saved language to: "),
- Logs.logText('${getLanguageName(name)} ($name)', GREEN)
- ], INFO);
- // todo: make this into a notification system for the user
- // notification would be in previous language
- // but only if the user didnt manually change it.
- curLanguage = name;
- } else {
- Logs.traceColored([
- Logs.getPrefix("Language"),
- Logs.logText("Setting Language To: "),
- Logs.logText('${getLanguageName(name)} ($name)', GREEN)
- ], VERBOSE);
+ if(!noLogs) {
+ if(curLanguage != name) {
+ Logs.traceColored([
+ Logs.getPrefix("Language"),
+ Logs.logText("Changing saved language to: "),
+ Logs.logText('${getLanguageName(name)} ($name)', GREEN)
+ ], INFO);
+ // todo: make this into a notification system for the user
+ // notification would be in previous language
+ // but only if the user didnt manually change it.
+ curLanguage = name;
+ } else {
+ Logs.traceColored([
+ Logs.getPrefix("Language"),
+ Logs.logText("Setting Language To: "),
+ Logs.logText('${getLanguageName(name)} ($name)', GREEN)
+ ], VERBOSE);
+ }
}
for(mod in ModsFolder.getLoadedModsLibs(false))
@@ -123,11 +125,22 @@ final class TranslationUtil
*
* If `id` is `null` then it's gonna search using `defString`.
*/
- public static inline function get(?id:String, ?params:Array, ?def:String):String
- return getRaw(id, def).format(params);
+ public static inline function get(?id:String, ?params:Array, ?def:String, ?mustDefaultLang:Bool):String {
+ final result = getRaw(id, def).format(params);
+
+ if (mustDefaultLang && hasCyrillic(result)) {
+ final oldLang = curLanguage;
+ setLanguage("en", true);
+ final engResult = getRaw(id, def).format(params);
+ setLanguage(oldLang, true);
+ return engResult;
+ } // I want to redo this but I'm too lazy
+
+ return result;
+ }
- public static inline function translate(?id:String, ?params:Array, ?def:String):String
- return get(id, params, def);
+ public static inline function translate(?id:String, ?params:Array, ?def:String, ?mustDefaultLang:Bool):String
+ return get(id, params, def, mustDefaultLang);
public static inline function translateDiff(?id:String, ?params:Array):String
return get("diff." + id.toLowerCase(), params, id);
@@ -304,6 +317,19 @@ final class TranslationUtil
#end
}
+ /**
+ * Since lime is shit and can't render Cyrillic on the window title, this function will return the title from a language that will use Cyrillic to English
+ */
+ public static function hasCyrillic(text:String):Bool {
+ for (i in 0...text.length) {
+ var code = text.charCodeAt(i);
+ if ((code >= 'А'.code && code <= 'Я'.code) ||
+ (code >= 'а'.code && code <= 'я'.code))
+ return true;
+ }
+ return false;
+ }
+
// Utils
public static function getLanguageName(lang:String):String {
diff --git a/source/funkin/editors/alphabet/AlphabetEditor.hx b/source/funkin/editors/alphabet/AlphabetEditor.hx
index 374e56f29..3da70e08a 100644
--- a/source/funkin/editors/alphabet/AlphabetEditor.hx
+++ b/source/funkin/editors/alphabet/AlphabetEditor.hx
@@ -59,7 +59,7 @@ class AlphabetEditor extends UIState {
public override function create() {
super.create();
- WindowUtils.suffix = " (" + translate("name") + ")";
+ WindowUtils.suffix = " (" + TU.translate("editor.alphabet.name", true) + ")";
SaveWarning.selectionClass = AlphabetSelection;
SaveWarning.saveFunc = () -> {_file_save(null);};
@@ -102,7 +102,7 @@ class AlphabetEditor extends UIState {
},
{
- label: "Edit Main Data", // TODO: add translations
+ label: translate("edit.editMainData"),
onSelect: _edit_main
}
]
@@ -128,15 +128,15 @@ class AlphabetEditor extends UIState {
]
},
{
- label: "Tape",
+ label: translate("topBar.tape"),
childs: [
{
- label: "Move Tape Left",
+ label: translate("tape.MoveTapeLeft"),
keybind: [LEFT],
onSelect: _tape_left
},
{
- label: "Move Tape Right",
+ label: translate("tape.MoveTapeRight"),
keybind: [RIGHT],
onSelect: _tape_right
}
diff --git a/source/funkin/editors/character/CharacterAnimButton.hx b/source/funkin/editors/character/CharacterAnimButton.hx
index a9b184a9e..b4ea5a2ae 100644
--- a/source/funkin/editors/character/CharacterAnimButton.hx
+++ b/source/funkin/editors/character/CharacterAnimButton.hx
@@ -116,7 +116,7 @@ class CharacterAnimButton extends UIButton {
foldableButtons.push(fpsStepper);
addLabelOn(fpsStepper, translate("fps"), 12);
- loopedCheckbox = new UICheckbox(fpsStepper.x + 82 - 32 + 26, fpsStepper.y, "Looping?", animData.loop, 0, true);
+ loopedCheckbox = new UICheckbox(fpsStepper.x + 82 - 32 + 26, fpsStepper.y, translate("looping"), animData.loop, 0, true);
loopedCheckbox.onChecked = (newLooping:Bool) -> {this.changeLooping(newLooping);};
members.push(loopedCheckbox);
foldableButtons.push(loopedCheckbox);
diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx
index b040d9bd3..baf3a3f7f 100644
--- a/source/funkin/editors/character/CharacterEditor.hx
+++ b/source/funkin/editors/character/CharacterEditor.hx
@@ -73,7 +73,7 @@ class CharacterEditor extends UIState {
undos = new UndoList();
- WindowUtils.suffix = " (" + TU.translate("editor.character.name") + ")";
+ WindowUtils.suffix = " (" + TU.translate("editor.character.name", true) + ")";
SaveWarning.selectionClass = CharacterSelection;
SaveWarning.saveFunc = () -> {_file_save(null);};
diff --git a/source/funkin/editors/charter/ChartDataScreen.hx b/source/funkin/editors/charter/ChartDataScreen.hx
index 57334cded..325a29974 100644
--- a/source/funkin/editors/charter/ChartDataScreen.hx
+++ b/source/funkin/editors/charter/ChartDataScreen.hx
@@ -31,6 +31,7 @@ class ChartDataScreen extends UISubstateWindow {
winTitle = TU.translate("chartDataScreen.title");
winWidth = 420; winHeight = 230; // guys look, the funny numbers!
+ // услышал тебя родной
super.create();
diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx
index 952fdacac..f70bc46ee 100644
--- a/source/funkin/editors/charter/Charter.hx
+++ b/source/funkin/editors/charter/Charter.hx
@@ -129,7 +129,7 @@ class Charter extends UIState {
public override function create() {
super.create();
- WindowUtils.suffix = " (" + TU.translate("editor.chart.name") + ")";
+ WindowUtils.suffix = " (" + TU.translate("editor.chart.name", true) + ")";
SaveWarning.selectionClass = CharterSelection;
SaveWarning.saveFunc = () -> saveEverything();
@@ -1292,6 +1292,12 @@ class Charter extends UIState {
updateNoteLogic(elapsed);
updateAutoSaving(elapsed);
+ /*
+ if (FlxG.keys.justPressed.ZERO) {
+ autoSaveTimer = 15;
+ autoSaveNotif.cancelled = false;
+ }
+ */
for (bs in __bookmarkObjects)
{
@@ -2351,7 +2357,7 @@ class Charter extends UIState {
case CCreateSelection(selection):
newChanges[i] = CCreateSelection(__relinkSelection(selection));
case CDeleteSelection(selection):
- newChanges[i] = CDeleteSelection(__relinkSelection(selection));
+ newChanges[i] = CDeleteSelection(__relinkSelection(selection));
case CSelectionDrag(selectionDrags):
newChanges[i] = CSelectionDrag([
for (selectionDrag in selectionDrags)
diff --git a/source/funkin/editors/charter/CharterAutoSaveUI.hx b/source/funkin/editors/charter/CharterAutoSaveUI.hx
index 901cba9a7..2d1f70654 100644
--- a/source/funkin/editors/charter/CharterAutoSaveUI.hx
+++ b/source/funkin/editors/charter/CharterAutoSaveUI.hx
@@ -9,6 +9,7 @@ using flixel.util.FlxSpriteUtil;
class CharterAutoSaveUI extends UISliceSprite {
public var icon:FlxSprite;
public var autosavingText:UIText;
+ public var cancelText:UIText;
public var progressBarBack:FlxSprite;
public var progressBar:FlxSprite;
@@ -19,7 +20,7 @@ class CharterAutoSaveUI extends UISliceSprite {
public var cancelled:Bool = false;
public function new(x:Float, y:Float) {
- super(x, y, 300, 46, "editors/ui/inputbox");
+ super(x, y, 0, 46, "editors/ui/inputbox");
icon = new FlxSprite(x+12, y+9).loadGraphic(Paths.image("editors/autosave-icons"), true, 10, 10);
icon.animation.add("icon", [for(i in 0...3) i], 0, true);
@@ -27,6 +28,11 @@ class CharterAutoSaveUI extends UISliceSprite {
members.push(icon);
members.push(autosavingText = new UIText(x+12+10+4, y+8, 0, TU.translate("editor.autosavingIn", ["?", "..."]), 12));
+ members.push(cancelText = new UIText(0, y+8, 0, TU.translate("editor.autosavingCanceledSuffix"), 12));
+ autosavingText.updateHitbox(); cancelText.updateHitbox();
+ bWidth = autosavingText.frameWidth + 150;
+ cancelText.x = x + bWidth - cancelText.frameWidth - 4;
+ cancelText.visible = false;
progressBarBack = new FlxSprite(x + 10, y + bHeight - 20).makeGraphic(Std.int(bWidth-20), 10, 0x00000000, true);
progressBarBack.drawRoundRect(0, 0, progressBarBack.width, progressBarBack.height, 4, 6, 0xFF727272, null, {smoothing: false});
@@ -45,9 +51,9 @@ class CharterAutoSaveUI extends UISliceSprite {
icon.animation.curAnim.curFrame = 2;
(new FlxTimer()).start(1, (_) -> {disappearAnimation(true);});
- autosavingText.text += " " + TU.translate("editor.autosavingCanceledSuffix");
+ cancelText.visible = true;
cancelButton.visible = false;
- for (member in [this, autosavingText]) member.color = 0xFFE67F7F;
+ for (member in [this, autosavingText, cancelText]) member.color = 0xFFE67F7F;
for (member in [progressBar, progressBarBack]) member.color = 0xFFE67F7F;
}, 24, 14);
cancelButton.frames = Paths.getFrames("editors/ui/grayscale-button");
@@ -106,6 +112,9 @@ class CharterAutoSaveUI extends UISliceSprite {
autosavingText.follow(this, 12+10+4, 8);
autosavingText.alpha = alpha;
+ cancelText.follow(this, bWidth - cancelText.frameWidth - 4, 8);
+ cancelText.alpha = alpha;
+
for (bar in [progressBar, progressBarBack]) {
bar.follow(this, 10, bHeight-20);
bar.alpha = alpha;
@@ -115,9 +124,9 @@ class CharterAutoSaveUI extends UISliceSprite {
public function appearAnimation() {
progress = 0; icon.animation.curAnim.curFrame = 0;
- for (member in [this, autosavingText, progressBar, progressBarBack]) member.color = 0xFFFFFFFF;
+ for (member in [this, autosavingText, progressBar, progressBarBack, cancelText]) member.color = 0xFFFFFFFF;
- x = -(320); alpha=0; FlxTween.cancelTweensOf(this); cancelled = false; cancelButton.visible = true;
+ x = -(320); alpha=0; FlxTween.cancelTweensOf(this); cancelled = false; cancelButton.visible = true; cancelText.visible = false;
FlxTween.tween(this, {x: 20}, .4, {ease: FlxEase.circInOut});
FlxTween.tween(this, {alpha: 1}, .3, {ease: FlxEase.sineOut, startDelay: .1});
diff --git a/source/funkin/editors/stage/StageEditor.hx b/source/funkin/editors/stage/StageEditor.hx
index 6469d0ea0..b50bf24d3 100644
--- a/source/funkin/editors/stage/StageEditor.hx
+++ b/source/funkin/editors/stage/StageEditor.hx
@@ -82,7 +82,7 @@ class StageEditor extends UIState {
public override function create() {
super.create();
- WindowUtils.suffix = " (" + TU.translate("editor.stage.name") + ")";
+ WindowUtils.suffix = " (" + TU.translate("editor.stage.name", true) + ")";
SaveWarning.selectionClass = StageSelection;
SaveWarning.saveFunc = () -> {_file_save(null);};
diff --git a/source/funkin/editors/ui/UIContextMenu.hx b/source/funkin/editors/ui/UIContextMenu.hx
index dcd8d0af3..ae1ccf825 100644
--- a/source/funkin/editors/ui/UIContextMenu.hx
+++ b/source/funkin/editors/ui/UIContextMenu.hx
@@ -156,6 +156,8 @@ class UIContextMenuOptionSpr extends UISliceSprite {
public function new(x:Float, y:Float, option:UIContextMenuOption, parent:UIContextMenu) {
label = new UIText(20, 2, 0, option.label);
+ label.updateHitbox();
+ label.frameHeight += 4;
this.option = option;
this.parent = parent;
this.color = option.color;
diff --git a/source/funkin/editors/ui/UIImageExplorer.hx b/source/funkin/editors/ui/UIImageExplorer.hx
index 12268e4d1..f04eaf507 100644
--- a/source/funkin/editors/ui/UIImageExplorer.hx
+++ b/source/funkin/editors/ui/UIImageExplorer.hx
@@ -50,7 +50,7 @@ class UIImageExplorer extends UIFileExplorer {
directoryButton = new UIButton(x + bWidth - (bHeight - 16) - 8, y + 8, null, () -> {directoryBG.visible = !directoryBG.visible;}, 26, 26);
members.push(directoryButton);
- directoryIcon = new UIText(directoryButton.x, directoryButton.y, 0, "/", 14);
+ directoryIcon = new UIText(directoryButton.x, directoryButton.y, 0, "/", 14);
members.push(directoryIcon);
directoryBG = new UISliceSprite(0, 0, 210+16, 8+12+4+22+8, 'editors/ui/inputbox');
@@ -248,9 +248,12 @@ class UIImageExplorer extends UIFileExplorer {
message.add('${imagePath.file}.${imagePath.ext}');
message.add(' (${CoolUtil.getSizeString(size)}');
- var typeOfFrame = isAtlas ? translate("symbol") : translate("animation");
+ final spriteOAtlas = isAtlas ? "symbol" : "animation";
+ var typeOfFrame = translate(spriteOAtlas);
var shouldUsePlural = animationList.length != 1;
if (animationList.length > 0) {
+ if (translate('$spriteOAtlas-ending') != '{uiImageExplorer.$spriteOAtlas-ending}')
+ typeOfFrame += translate('$spriteOAtlas-ending');
message.add(', ${TU.getRaw("uiImageExplorer." + (shouldUsePlural ? "foundplural" : "found")).format([animationList.length, typeOfFrame])}');
} else message.add(', ${TU.getRaw("uiImageExplorer.notFound").format([typeOfFrame])}');
diff --git a/source/funkin/editors/ui/UITopMenu.hx b/source/funkin/editors/ui/UITopMenu.hx
index d705da4e6..ca93f63f2 100644
--- a/source/funkin/editors/ui/UITopMenu.hx
+++ b/source/funkin/editors/ui/UITopMenu.hx
@@ -50,6 +50,7 @@ class UITopMenuButton extends UISliceSprite {
this.label = new UIText(4, 0, 0, label);
this.label.alignment = CENTER;
+ this.label.updateHitbox(); //IDK WHY BUT WITHOUT THIS FILED WIDTH OF RUSSIAN TEXT IS LESS THAN NECESSARY
bWidth = Std.int(this.label.fieldWidth = this.label.frameWidth + 8);
members.push(this.label);
}
diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx
index 5e6fdaf5a..87f25f05d 100644
--- a/source/funkin/game/PlayState.hx
+++ b/source/funkin/game/PlayState.hx
@@ -888,7 +888,7 @@ class PlayState extends MusicBeatState
if (chartingMode) {
WindowUtils.prefix = Charter.undos.unsaved ? Flags.UNDO_PREFIX : "";
- WindowUtils.suffix = TU.translate("playtesting.chartPlaytesting");
+ WindowUtils.suffix = TU.translate("playtesting.chartPlaytesting", true);
SaveWarning.showWarning = Charter.undos.unsaved;
SaveWarning.selectionClass = CharterSelection;
diff --git a/source/funkin/menus/ui/Alphabet.hx b/source/funkin/menus/ui/Alphabet.hx
index de64e3478..3689c6449 100644
--- a/source/funkin/menus/ui/Alphabet.hx
+++ b/source/funkin/menus/ui/Alphabet.hx
@@ -446,10 +446,16 @@ class Alphabet extends FlxSprite {
if (data == null) {
var charCode:Int = char.charCodeAt(0);
+ // Latin
if (charCode >= 'A'.code && charCode <= 'Z'.code && defaults[CaseMode.UPPER] != null)
data = defaults[CaseMode.UPPER];
else if (charCode >= 'a'.code && charCode <= 'z'.code && defaults[CaseMode.LOWER] != null)
data = defaults[CaseMode.LOWER];
+ // Cyrillic
+ else if (charCode >= 'А'.code && charCode <= 'Я'.code && defaults[CaseMode.UPPER] != null)
+ data = defaults[CaseMode.UPPER];
+ else if (charCode >= 'а'.code && charCode <= 'я'.code && defaults[CaseMode.LOWER] != null)
+ data = defaults[CaseMode.LOWER];
else
data = defaults[CaseMode.NONE];
}