305 lines
16 KiB
Java
305 lines
16 KiB
Java
package com.projectsacrifice.game;
|
|
|
|
/** All player-facing copy behind one typed, Android-independent interface. */
|
|
public final class GameStrings {
|
|
private final GameLanguage language;
|
|
|
|
private GameStrings(GameLanguage language) {
|
|
this.language = language == null ? GameLanguage.EN : language;
|
|
}
|
|
|
|
public static GameStrings forLanguage(GameLanguage language) {
|
|
return new GameStrings(language);
|
|
}
|
|
|
|
public GameLanguage language() {
|
|
return language;
|
|
}
|
|
|
|
private boolean russian() {
|
|
return language == GameLanguage.RU;
|
|
}
|
|
|
|
public String appContentDescription() {
|
|
return russian()
|
|
? "Project Sacrifice. Платформенная головоломка из десяти уровней."
|
|
: "Project Sacrifice. Ten-level puzzle platform game.";
|
|
}
|
|
|
|
public String projectTitle() { return "PROJECT SACRIFICE"; }
|
|
public String tagline() {
|
|
return russian() ? "Каждый конец оставляет путь вперёд"
|
|
: "Every ending leaves a way forward";
|
|
}
|
|
public String locked() { return russian() ? "ЗАКРЫТО" : "LOCKED"; }
|
|
public String tapToEnter() { return russian() ? "Нажмите, чтобы войти" : "Tap to enter"; }
|
|
public String levelSelectFooter() {
|
|
return russian()
|
|
? "Альбомная ориентация · мультитач · прогресс сохраняется автоматически"
|
|
: "Landscape · multitouch · progress saves automatically";
|
|
}
|
|
|
|
public String settingsButton() {
|
|
return russian() ? "Настройки" : "Settings";
|
|
}
|
|
|
|
public String settingsTitle() { return russian() ? "НАСТРОЙКИ" : "SETTINGS"; }
|
|
public String settingsInstruction() {
|
|
return russian() ? "Нажмите на строку, чтобы изменить. Всё сохраняется автоматически."
|
|
: "Tap a row to change it. Changes save automatically.";
|
|
}
|
|
public String controlSizeSetting() { return russian() ? "Размер управления" : "Control size"; }
|
|
public String controlOpacitySetting() { return russian() ? "Прозрачность управления" : "Control opacity"; }
|
|
public String vibrationSetting() { return russian() ? "Вибрация" : "Vibration"; }
|
|
public String languageSetting() { return russian() ? "Язык" : "Language"; }
|
|
public String languageName() { return russian() ? "Русский" : "English"; }
|
|
public String controlSizeValue(int index) {
|
|
String[] values = russian()
|
|
? new String[]{"Маленький", "Средний", "Большой"}
|
|
: new String[]{"Small", "Medium", "Large"};
|
|
return values[validPreset(index)];
|
|
}
|
|
public String controlOpacityValue(int index) {
|
|
String[] values = russian()
|
|
? new String[]{"Низкая", "Средняя", "Высокая"}
|
|
: new String[]{"Low", "Medium", "High"};
|
|
return values[validPreset(index)];
|
|
}
|
|
public String hapticsValue(boolean enabled) {
|
|
if (russian()) return enabled ? "Вкл." : "Выкл.";
|
|
return enabled ? "On" : "Off";
|
|
}
|
|
public String accessibilityTitle() { return russian() ? "ДОСТУПНОСТЬ" : "ACCESSIBILITY"; }
|
|
public String textSizeSetting() { return russian() ? "Размер текста" : "Text size"; }
|
|
public String textSizeValue(float scale) {
|
|
return scale > 1f ? (russian() ? "Крупный" : "Large")
|
|
: (russian() ? "Обычный" : "Standard");
|
|
}
|
|
public String highContrastSetting() { return russian() ? "Контраст" : "High contrast"; }
|
|
public String highContrastValue(boolean enabled) {
|
|
return hapticsValue(enabled);
|
|
}
|
|
public String back() { return russian() ? "Назад" : "Back"; }
|
|
|
|
public String hudStats(int deaths, long elapsedMilliseconds) {
|
|
if (russian()) {
|
|
return "Добровольцы " + deaths + " Время " + GameMath.formatTime(elapsedMilliseconds);
|
|
}
|
|
return "Volunteers " + deaths + " Time " + GameMath.formatTime(elapsedMilliseconds);
|
|
}
|
|
public String restart() { return russian() ? "Заново" : "Restart"; }
|
|
public String respawning() {
|
|
return russian() ? "Следующий доброволец уже в пути…"
|
|
: "Another volunteer is on the way…";
|
|
}
|
|
|
|
public String levelBestStats(int deaths, long elapsedMilliseconds) {
|
|
return "✓ " + deaths + " " + volunteerWord(deaths) + " · "
|
|
+ GameMath.formatTime(elapsedMilliseconds);
|
|
}
|
|
public String relicClaimed() { return russian() ? "РЕЛИКВИЯ ПОЛУЧЕНА" : "RELIC CLAIMED"; }
|
|
public String completion() { return russian() ? "Завершение ★" : "Completion ★"; }
|
|
public String completionDeaths(boolean earned, int deaths, int targetDeaths) {
|
|
return (earned ? "★" : "☆") + " " + deaths + " / " + targetDeaths + " "
|
|
+ volunteerWord(deaths);
|
|
}
|
|
public String completionTime(boolean earned, long elapsedMilliseconds, long targetMilliseconds) {
|
|
return (earned ? "★" : "☆") + " " + GameMath.formatTime(elapsedMilliseconds)
|
|
+ " / " + GameMath.formatTime(targetMilliseconds);
|
|
}
|
|
public String levelSelect() { return russian() ? "Выбор уровня" : "Level select"; }
|
|
public String replay() { return russian() ? "Повторить" : "Replay"; }
|
|
public String nextLevel() { return russian() ? "Следующий уровень" : "Next level"; }
|
|
public String paused() { return russian() ? "ПАУЗА" : "PAUSED"; }
|
|
public String resume() { return russian() ? "Продолжить" : "Resume"; }
|
|
|
|
// Result-flow hooks used by the Stage 3 result screen.
|
|
public String currentResult() { return russian() ? "Текущий результат" : "Current result"; }
|
|
public String bestResult() { return russian() ? "Лучший результат" : "Best result"; }
|
|
public String deathsStat() { return russian() ? "Добровольцы" : "Volunteers"; }
|
|
public String timeStat() { return russian() ? "Время" : "Time"; }
|
|
public String newBest() { return russian() ? "НОВЫЙ РЕКОРД" : "NEW BEST"; }
|
|
|
|
public String currentResultLine(int deaths, long timeMs) {
|
|
return currentResult() + " · " + deaths + " " + volunteerWord(deaths)
|
|
+ " · " + GameMath.formatTime(timeMs);
|
|
}
|
|
|
|
public String bestResultLine(int deaths, long timeMs) {
|
|
return bestResult() + " · " + deaths + " " + volunteerWord(deaths)
|
|
+ " · " + GameMath.formatTime(timeMs);
|
|
}
|
|
|
|
public String targetsResultLine(int deaths, long timeMs) {
|
|
String label = russian() ? "Цели" : "Targets";
|
|
return label + " · " + deaths + " " + volunteerWord(deaths)
|
|
+ " · " + GameMath.formatTime(timeMs);
|
|
}
|
|
|
|
public String nextGoalDeaths(long deaths) {
|
|
return russian()
|
|
? "Следующая цель · пройти с " + deaths + " добровольцами"
|
|
: "Next goal · finish with " + deaths + " volunteers";
|
|
}
|
|
|
|
public String nextGoalTime(long timeMs) {
|
|
return (russian() ? "Следующая цель · пройти за " : "Next goal · finish in ")
|
|
+ GameMath.formatTime(timeMs);
|
|
}
|
|
|
|
public String nextGoalLevel(long level) {
|
|
return (russian() ? "Следующая цель · перейти на уровень "
|
|
: "Next goal · enter level ") + level;
|
|
}
|
|
|
|
public String nextGoalPersonalBest() {
|
|
return russian() ? "Следующая цель · улучшить личный рекорд"
|
|
: "Next goal · improve your personal best";
|
|
}
|
|
|
|
// Onboarding hooks keep new tutorial Canvas copy out of GameView conditionals.
|
|
public String tutorialWelcomeTitle() {
|
|
return russian() ? "Смерть — это инструмент" : "Death is a tool";
|
|
}
|
|
public String tutorialWelcomeBody() {
|
|
return russian()
|
|
? "Двигайтесь стрелками и прыгайте кнопкой с крылом. Доберитесь до реликвии."
|
|
: "Move with the arrows and jump with the winged button. Reach the relic.";
|
|
}
|
|
public String tutorialSacrificeTitle() {
|
|
return russian() ? "Оставьте путь вперёд" : "Leave a way forward";
|
|
}
|
|
public String tutorialSacrificeBody() {
|
|
return russian()
|
|
? "После смерти тело остаётся в мире: закрывает шипы, держит плиты и становится ступенью."
|
|
: "A body stays in the world after death: cover spikes, hold plates, and make a step.";
|
|
}
|
|
public String tutorialSkip() { return russian() ? "Пропустить" : "Skip"; }
|
|
public String tutorialNext() { return russian() ? "Далее" : "Next"; }
|
|
public String tutorialStart() { return russian() ? "Начать" : "Start"; }
|
|
public String tutorialDone() { return russian() ? "Готово" : "Done"; }
|
|
public String tutorialMovementTitle() { return russian() ? "ДВИЖЕНИЕ" : "MOVE"; }
|
|
public String tutorialMovementBody() {
|
|
return russian() ? "Удерживайте левую или правую стрелку, чтобы двигаться."
|
|
: "Hold the left or right arrow to explore.";
|
|
}
|
|
public String tutorialJumpTitle() { return russian() ? "ДВИЖЕНИЕ + ПРЫЖОК" : "MOVE + JUMP"; }
|
|
public String tutorialJumpBody() {
|
|
return russian() ? "Используйте два пальца: держите направление и нажмите Прыжок."
|
|
: "Use two fingers: hold a direction and tap Jump.";
|
|
}
|
|
public String tutorialCorpseTitle() {
|
|
return russian() ? "СМЕРТЬ ОСТАВЛЯЕТ ИНСТРУМЕНТ" : "DEATH LEAVES A TOOL";
|
|
}
|
|
public String tutorialCorpseBody() {
|
|
return russian() ? "Павший доброволец остаётся. Используйте тело, чтобы открыть путь."
|
|
: "A fallen volunteer remains. Use the body to open a path.";
|
|
}
|
|
public String tutorialProgress(int step, int total) {
|
|
return step + " / " + total;
|
|
}
|
|
|
|
public String accessibilityStatus(int activeSignals, int totalSignals,
|
|
int openDoors, int totalDoors, boolean playerAlive) {
|
|
if (russian()) {
|
|
return "Сигналы " + activeSignals + "/" + totalSignals
|
|
+ " · Двери " + openDoors + "/" + totalDoors
|
|
+ " · Доброволец " + (playerAlive ? "активен" : "возрождается");
|
|
}
|
|
return "Signals " + activeSignals + "/" + totalSignals
|
|
+ " · Doors " + openDoors + "/" + totalDoors
|
|
+ " · Volunteer " + (playerAlive ? "active" : "respawning");
|
|
}
|
|
|
|
public String levelSelectDescription(int unlocked, int total) {
|
|
if (russian()) {
|
|
return "Выбор уровня. Открыто " + unlocked + " из " + total
|
|
+ ". Выберите открытый уровень или Настройки.";
|
|
}
|
|
return "Level select. " + unlocked + " of " + total
|
|
+ " unlocked. Choose an unlocked level or open Settings.";
|
|
}
|
|
|
|
public String settingsDescription(ControlSettings controls,
|
|
AccessibilitySettings accessibility) {
|
|
if (russian()) {
|
|
return "Настройки. Размер управления "
|
|
+ controlSizeValue(controls.controlSizeIndex())
|
|
+ ". Прозрачность управления "
|
|
+ controlOpacityValue(controls.controlOpacityIndex())
|
|
+ ". Вибрация " + hapticsValue(controls.hapticsEnabled())
|
|
+ ". Размер текста " + textSizeValue(accessibility.textScale())
|
|
+ ". Контраст " + highContrastValue(accessibility.highContrastEnabled())
|
|
+ ". Назад.";
|
|
}
|
|
return "Settings. Control size " + controls.controlSizeLabel()
|
|
+ ". Control opacity " + controls.controlOpacityLabel()
|
|
+ ". Vibration " + controls.hapticsLabel()
|
|
+ ". Text size " + accessibility.textSizeLabel()
|
|
+ ". High contrast " + accessibility.highContrastLabel()
|
|
+ ". Back.";
|
|
}
|
|
|
|
public String playingDescription(int levelNumber, int deaths, String elapsed,
|
|
String criticalState, boolean paused) {
|
|
if (paused) {
|
|
return russian()
|
|
? "Пауза на уровне " + levelNumber + ", " + levelTitle(levelNumber)
|
|
+ ". Продолжить или вернуться к выбору уровня."
|
|
: "Paused on level " + levelNumber + ", " + levelTitle(levelNumber)
|
|
+ ". Resume or return to level select.";
|
|
}
|
|
if (russian()) {
|
|
return "Идёт уровень " + levelNumber + ", " + levelTitle(levelNumber)
|
|
+ ". Добровольцы " + deaths + ". Время " + elapsed + ". "
|
|
+ criticalState + ". Движение влево и вправо, прыжок, заново, пауза.";
|
|
}
|
|
return "Playing level " + levelNumber + ", " + levelTitle(levelNumber)
|
|
+ ". " + deaths + " volunteers. Time " + elapsed + ". " + criticalState
|
|
+ ". Move left, move right, jump, restart, pause.";
|
|
}
|
|
|
|
public String completeDescription(int levelNumber, int deaths, String elapsed,
|
|
boolean hasNextLevel) {
|
|
if (russian()) {
|
|
return "Уровень завершён. " + levelTitle(levelNumber) + ". Добровольцы "
|
|
+ deaths + ". Время " + elapsed
|
|
+ ". Выбор уровня. Повторить."
|
|
+ (hasNextLevel ? " Следующий уровень." : "");
|
|
}
|
|
return "Level complete. " + levelTitle(levelNumber) + ". " + deaths
|
|
+ " volunteers. Time " + elapsed + ". Level select. Replay."
|
|
+ (hasNextLevel ? " Next level." : "");
|
|
}
|
|
|
|
public String levelTitle(int oneBasedLevelNumber) {
|
|
LevelDefinition level = level(oneBasedLevelNumber);
|
|
return russian() ? level.titleRu : level.title;
|
|
}
|
|
|
|
public String levelHint(int oneBasedLevelNumber) {
|
|
LevelDefinition level = level(oneBasedLevelNumber);
|
|
return russian() ? level.hintRu : level.hint;
|
|
}
|
|
|
|
private String volunteerWord(int count) {
|
|
if (!russian()) return count == 1 ? "volunteer" : "volunteers";
|
|
int mod100 = Math.abs(count) % 100;
|
|
int mod10 = Math.abs(count) % 10;
|
|
if (mod100 >= 11 && mod100 <= 14) return "добровольцев";
|
|
if (mod10 == 1) return "доброволец";
|
|
if (mod10 >= 2 && mod10 <= 4) return "добровольца";
|
|
return "добровольцев";
|
|
}
|
|
|
|
private static int validPreset(int index) {
|
|
return index >= 0 && index <= 2 ? index : 1;
|
|
}
|
|
|
|
private static LevelDefinition level(int oneBasedLevelNumber) {
|
|
int index = oneBasedLevelNumber - 1;
|
|
if (index < 0 || index >= LevelCatalog.all().size()) index = 0;
|
|
return LevelCatalog.get(index);
|
|
}
|
|
}
|