Compare commits
29 Commits
bea593732d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
b4359c0458
|
|||
| 4dabcaa13c | |||
| 2268334c30 | |||
| 645b8b070b | |||
| adb306604c | |||
| 2e4d074bfc | |||
| 025db00c6a | |||
| 92f964920a | |||
| 58c2e76603 | |||
| 1f8d003f7b | |||
| 5660fabb1a | |||
| 3bc1759c0e | |||
| 83f9e5519f | |||
| 50befc68f2 | |||
| a1bef582f8 | |||
| fdd0a7c6a7 | |||
| 28f85f5809 | |||
| 163f4479a2 | |||
| 92fcd08c8a | |||
| 73008ca1d9 | |||
| 80e2b55887 | |||
| 8c06b2a5f2 | |||
| 7a49f50c65 | |||
| 8597d10e1b | |||
| d6ca4e1415 | |||
| 5633d68a91 | |||
| 3b18c156f1 | |||
| 3344dabf67 | |||
| 854eee4275 |
+11
@@ -0,0 +1,11 @@
|
||||
# Build output
|
||||
bin/
|
||||
obj/
|
||||
|
||||
# User-specific project files
|
||||
*.user
|
||||
|
||||
# IDE
|
||||
.vs/
|
||||
.vscode/
|
||||
.idea/
|
||||
@@ -0,0 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
Kept as the work happens, not assembled at release time. Format is
|
||||
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
|
||||
[SemVer](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 1.0.0 — 2026-08-08
|
||||
|
||||
The first tagged version: *Outer Wilds* and *Echoes of the Eye* are translated,
|
||||
which is what this mod set out to do.
|
||||
|
||||
### Added
|
||||
|
||||
- Slovak localization of *Outer Wilds* and *Echoes of the Eye*, as an OWML mod
|
||||
built on `xen.LocalizationUtility`.
|
||||
- A fixed glossary of proper nouns and recurring terms, so names stay consistent
|
||||
across the whole script.
|
||||
|
||||
### Changed
|
||||
|
||||
- The documentation left the repository. The working notes, the phase roadmap,
|
||||
the glossary and the in-game review notes are now the
|
||||
[wiki](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki),
|
||||
and the history was rewritten in the same pass so they are not present at any
|
||||
commit. `assets/Translation.xml` stays here — it ships with the mod.
|
||||
|
||||
### Note on history
|
||||
|
||||
Any clone taken before 2026-08-08 has a different history and should be
|
||||
discarded rather than merged.
|
||||
@@ -0,0 +1,42 @@
|
||||
using OWML.ModHelper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
// Interface copied from xen-42's Localization Utility (MIT), so this mod can
|
||||
// resolve the utility's API through OWML's TryGetModApi<T>. Keep in sync with
|
||||
// https://github.com/xen-42/outer-wilds-localization-utility.
|
||||
namespace SlovakTranslation
|
||||
{
|
||||
public interface ILocalizationAPI
|
||||
{
|
||||
#region Add new language
|
||||
void RegisterLanguage(ModBehaviour mod, string languageName, string translationPath);
|
||||
void RegisterLanguage(ModBehaviour mod, string languageName, string translationPath, string languageToReplace);
|
||||
void AddLanguageFont(ModBehaviour mod, string languageName, string assetBundlePath, string fontPath, out Font font);
|
||||
void AddLanguageFixer(string languageName, Func<string, string> fixer);
|
||||
void SetLanguageDefaultFontSpacing(string languageName, float defaultFontSpacing);
|
||||
void SetLanguageFontSizeModifier(string languageName, float fontSizeModifier);
|
||||
#endregion
|
||||
|
||||
#region Add translations to new/existing languages
|
||||
void AddTranslation(ModBehaviour mod, string languageName, string translationPath);
|
||||
void AddTranslation(string languageName, KeyValuePair<string, string>[] regularEntries, KeyValuePair<string, string>[] shipLogEntries, KeyValuePair<int, string>[] uiEntries);
|
||||
|
||||
void AddRegularTranslation(string languageName, string key, string value);
|
||||
void AddRegularTranslation(string languageName, string commonKeyPrefix, params string[] entries);
|
||||
void AddRegularTranslation(string languageName, params KeyValuePair<string, string>[] entries);
|
||||
|
||||
void AddShiplogTranslation(string languageName, string key, string value);
|
||||
void AddShiplogTranslation(string languageName, string commonKeyPrefix, params string[] entries);
|
||||
void AddShiplogTranslation(string languageName, params KeyValuePair<string, string>[] entries);
|
||||
|
||||
void AddUITranslation(string languageName, int key, string value);
|
||||
void AddUITranslation(string languageName, params KeyValuePair<int, string>[] entries);
|
||||
#endregion
|
||||
|
||||
#region obsolete
|
||||
[Obsolete] void AddLanguageFont(ModBehaviour mod, string languageName, string assetBundlePath, string fontPath);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,79 @@
|
||||
# Outer-Wilds-SK-Translation-Mod
|
||||
# Outer Wilds — Slovenský preklad / Slovak Translation Mod
|
||||
|
||||
> **Neoficiálny slovenský preklad hry Outer Wilds** (základná hra + rozšírenie
|
||||
> *Echoes of the Eye*). Pridáva do hry jazyk **Slovenčina**.
|
||||
>
|
||||
> *An unofficial Slovak (slovenčina) translation mod for Outer Wilds, covering
|
||||
> the base game and the Echoes of the Eye DLC.*
|
||||
|
||||
**Stav / Status:** 🚧 **Work in progress** — the mod scaffold and translation are
|
||||
being built. See the [Roadmap](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki/Roadmap).
|
||||
|
||||
Outer Wilds officially ships in 12 languages; Slovak is not one of them. This mod
|
||||
adds it as a new selectable language using the community localization framework —
|
||||
no changes to the game's own files are required.
|
||||
|
||||
---
|
||||
|
||||
## How it works
|
||||
|
||||
The mod is a small [OWML](https://github.com/ow-mods/owml) mod that registers a
|
||||
new language through **[Interplanetary Polyglot / Localization Utility](https://outerwildsmods.com/mods/interplanetarypolyglot/)**
|
||||
(`xen.LocalizationUtility`). All translated text lives in a single
|
||||
`assets/Translation.xml`; the utility swaps the game's strings for the Slovak ones
|
||||
at runtime.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Install the **[Outer Wilds Mod Manager](https://outerwildsmods.com/mod-manager/)**.
|
||||
2. Install this mod through the Mod Manager. Its dependency **Interplanetary
|
||||
Polyglot** (`xen.LocalizationUtility`) will be pulled in automatically.
|
||||
3. Launch the game via the Mod Manager.
|
||||
4. In **Settings → Language**, choose **Slovenčina**.
|
||||
- Tip: the optional [Language Swap](https://outerwildsmods.com/mods/languageswap/)
|
||||
mod lets you switch language in-game with `Ctrl+L`.
|
||||
|
||||
> Until the first release is published, the mod is not yet in the Mod Manager
|
||||
> database — see the [Roadmap](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki/Roadmap) for how to build it from source.
|
||||
|
||||
## Contributing / Prispievanie
|
||||
|
||||
Translation fixes are very welcome — the goal is natural, consistent Slovak.
|
||||
|
||||
- **Report** mistranslations or awkward phrasing as an issue.
|
||||
- **Edit** only the `<value>` of each entry in `assets/Translation.xml`.
|
||||
**Never change the `<key>`** — it is the English identifier the game matches on.
|
||||
- Preserve all inline formatting exactly, e.g. `<color=orange>…</color>`,
|
||||
`<i>`, and speaker prefixes like `POKE:`.
|
||||
- Follow the terminology in the [Glossary](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki/Glossary) so names (Nomai, the Eye, Ash Twin
|
||||
Project, …) stay consistent across the whole game.
|
||||
|
||||
See the [Working notes](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki/Working-notes) for the full conventions and repo layout.
|
||||
|
||||
## License & disclaimer
|
||||
|
||||
The **original mod code and the Slovak translation** in this repository are
|
||||
released under the [MIT License](LICENSE).
|
||||
|
||||
The bundled fallback font in `assets/slovakfont` is
|
||||
**[Cabin](https://github.com/impallari/Cabin)** by the Cabin Project Authors, used
|
||||
under the **SIL Open Font License 1.1** (see
|
||||
[`assets/Cabin-OFL.txt`](assets/Cabin-OFL.txt)). The game's own menu and HUD fonts
|
||||
were never baked with Slovak caron glyphs, so those labels are redrawn with a font
|
||||
that has them — preferably one of the game's own dynamic fonts, and Cabin only where
|
||||
it ships none. See [`SlovakFont.cs`](SlovakFont.cs), and the `preferGameTypeface`
|
||||
setting if you would rather have Cabin everywhere.
|
||||
|
||||
This is an **unofficial** fan project. It is **not affiliated with, approved by, or
|
||||
endorsed by Mobius Digital or Annapurna Interactive.** *Outer Wilds*, its story,
|
||||
dialogue, characters, and other assets are **© Mobius Digital / Annapurna
|
||||
Interactive**; the underlying game text remains their property and is used here
|
||||
under **Mobius Digital's Fan Content Policy**. The MIT license covers only this
|
||||
project's own contributions, not the source material.
|
||||
|
||||
## Credits
|
||||
|
||||
- **Mobius Digital / Annapurna Interactive** — *Outer Wilds*.
|
||||
- **[xen-42](https://github.com/xen-42)** — the Localization Utility /
|
||||
Interplanetary Polyglot framework this mod is built on.
|
||||
- The Outer Wilds modding community.
|
||||
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace SlovakTranslation
|
||||
{
|
||||
/// <summary>
|
||||
/// Fixes the missing Slovak caron glyphs (č ď ĺ ľ ň ŕ ť ž) in the menus and HUD.
|
||||
///
|
||||
/// Outer Wilds renders Latin languages with a handful of *static* font atlases,
|
||||
/// and only some of them were baked with Latin Extended-A:
|
||||
///
|
||||
/// Adobe - SerifGothicStd (+ExtraBold) menus 253 glyphs — no carons
|
||||
/// Gill Sans MT (+Menu, Bold) HUD prompts 243 glyphs — no carons
|
||||
/// ParaType - Futura PT Medium dialogue 663 glyphs — complete
|
||||
/// SpaceMono-Regular translator 612 glyphs — complete
|
||||
///
|
||||
/// That is why dialogue and the Nomai translator always looked right while
|
||||
/// "Pokračovať" came out as "Pokra ova".
|
||||
///
|
||||
/// Registering a whole custom language font via the Localization Utility fixes
|
||||
/// the menus, but it also flips <c>TextTranslation.IsLanguageLatin()</c> to
|
||||
/// false, which drags dialogue, the translator and the ship log off their
|
||||
/// proper fonts. And <c>UIStyleManager.GetMenuFont()</c> — the obvious hook —
|
||||
/// is dead code with no callers; the fonts are assigned straight onto the
|
||||
/// <see cref="Text"/> components in the scenes.
|
||||
///
|
||||
/// So we substitute at the Text level, but the decision is made **per font, not
|
||||
/// per label**: a font that cannot draw Slovak is replaced everywhere it is
|
||||
/// used, so a menu never mixes two typefaces. Fonts that can draw Slovak —
|
||||
/// the dialogue and translator fonts — are left completely alone.
|
||||
///
|
||||
/// The replacement is preferably the game's *own* dynamic cut of the same
|
||||
/// typeface (it ships several, e.g. Adobe - SerifGothicStd_Dynamic), which keeps
|
||||
/// the menu pixel-identical to vanilla. Bundled Cabin is the fallback.
|
||||
/// </summary>
|
||||
internal static class SlovakFont
|
||||
{
|
||||
/// <summary>Cabin (SIL OFL 1.1), a humanist sans in the Gill Sans lineage, used
|
||||
/// where the game has no dynamic cut of its own. Dynamic, so it can draw any
|
||||
/// glyph Slovak needs.</summary>
|
||||
private static Font _font;
|
||||
|
||||
/// <summary>The letters Slovak adds on top of plain ASCII. Only these are worth
|
||||
/// probing — anything else in the text was already fine in English.</summary>
|
||||
private const string SlovakLetters = "áäčďéíĺľňóôŕšťúýžÁÄČĎÉÍĹĽŇÓÔŔŠŤÚÝŽ";
|
||||
|
||||
/// <summary>Stylised display faces (the ship's readouts, seven-segment digits).
|
||||
/// Replacing these wholesale would cost more in looks than it gains, so they
|
||||
/// are only substituted on the individual labels that actually need a glyph.</summary>
|
||||
private static readonly string[] Stylised = { "VCR_OSD_MONO", "digital-7", "PCBius" };
|
||||
|
||||
/// <summary>Font instance ID → the Slovak letters that font cannot draw.</summary>
|
||||
private static readonly Dictionary<int, string> _gaps = new Dictionary<int, string>();
|
||||
|
||||
/// <summary>Labels we substituted, and the font the game wanted on them.</summary>
|
||||
private static readonly Dictionary<Text, Font> _swapped = new Dictionary<Text, Font>();
|
||||
|
||||
/// <summary>Original font instance ID → what we put in its place.</summary>
|
||||
private static readonly Dictionary<int, Font> _substitutes = new Dictionary<int, Font>();
|
||||
|
||||
/// <summary>The game's own dynamic fonts, which can draw glyphs their static
|
||||
/// siblings were never baked with.</summary>
|
||||
private static Font[] _gameDynamicFonts = new Font[0];
|
||||
|
||||
/// <summary>When set, a static font is replaced by the game's own dynamic cut of the
|
||||
/// same typeface where one exists, keeping the vanilla look. Cabin otherwise.</summary>
|
||||
internal static bool PreferGameTypeface = true;
|
||||
|
||||
private static ModBehaviour _mod;
|
||||
|
||||
internal static bool Loaded => _font != null;
|
||||
|
||||
internal static void Load(ModBehaviour mod)
|
||||
{
|
||||
_mod = mod;
|
||||
var path = mod.ModHelper.Manifest.ModFolderPath + "assets/slovakfont";
|
||||
var bundle = AssetBundle.LoadFromFile(path);
|
||||
if (bundle == null)
|
||||
{
|
||||
mod.ModHelper.Console.WriteLine("Could not load font bundle at " + path, MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var font in bundle.LoadAllAssets<Font>())
|
||||
{
|
||||
if (font.name != "SlovakUI") continue;
|
||||
_font = font;
|
||||
Object.DontDestroyOnLoad(font);
|
||||
break;
|
||||
}
|
||||
|
||||
if (_font == null)
|
||||
mod.ModHelper.Console.WriteLine("Font bundle has no 'SlovakUI' font.", MessageType.Error);
|
||||
}
|
||||
|
||||
/// <summary>Give <paramref name="text"/> a font that can draw Slovak, or hand back
|
||||
/// the game's own font once it is no longer needed.</summary>
|
||||
internal static void Apply(Text text)
|
||||
{
|
||||
if (_font == null || text == null) return;
|
||||
|
||||
var current = text.font;
|
||||
Font stored;
|
||||
var swapped = _swapped.TryGetValue(text, out stored) && stored != null &&
|
||||
current == SubstituteFor(stored);
|
||||
|
||||
// If anything else assigned a font since our swap, that is the new baseline.
|
||||
var wanted = swapped ? stored : current;
|
||||
if (!swapped) _swapped.Remove(text);
|
||||
if (wanted == null) return;
|
||||
|
||||
var needsHelp = NeedsSubstitute(wanted, text.text);
|
||||
if (needsHelp == swapped) return;
|
||||
|
||||
if (needsHelp)
|
||||
{
|
||||
_swapped[text] = wanted;
|
||||
text.font = SubstituteFor(wanted);
|
||||
}
|
||||
else
|
||||
{
|
||||
_swapped.Remove(text);
|
||||
text.font = wanted;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>What to draw <paramref name="original"/>'s labels with instead. The
|
||||
/// game ships dynamic cuts of several of its typefaces; borrowing the matching one
|
||||
/// keeps the menu looking exactly like vanilla, which no substitute font can.</summary>
|
||||
private static Font SubstituteFor(Font original)
|
||||
{
|
||||
Font cached;
|
||||
if (_substitutes.TryGetValue(original.GetInstanceID(), out cached) && cached != null) return cached;
|
||||
if (!PreferGameTypeface) return _font;
|
||||
|
||||
if (_gameDynamicFonts.Length == 0) RefreshGameFonts();
|
||||
|
||||
Font best = null;
|
||||
var bestLength = 0;
|
||||
foreach (var candidate in _gameDynamicFonts)
|
||||
{
|
||||
if (candidate == null) continue;
|
||||
var baseName = candidate.name.EndsWith("_Dynamic")
|
||||
? candidate.name.Substring(0, candidate.name.Length - "_Dynamic".Length)
|
||||
: candidate.name;
|
||||
|
||||
if (baseName.Length <= bestLength) continue;
|
||||
if (!original.name.StartsWith(baseName, System.StringComparison.Ordinal)) continue;
|
||||
if (GapsOf(candidate).Length != 0) continue;
|
||||
|
||||
best = candidate;
|
||||
bestLength = baseName.Length;
|
||||
}
|
||||
|
||||
if (best == null) return _font;
|
||||
|
||||
_substitutes[original.GetInstanceID()] = best;
|
||||
_mod?.ModHelper.Console.WriteLine(
|
||||
$"drawing \"{original.name}\" with the game's own \"{best.name}\"", MessageType.Info);
|
||||
return best;
|
||||
}
|
||||
|
||||
private static void RefreshGameFonts()
|
||||
{
|
||||
var found = new List<Font>();
|
||||
foreach (var font in Resources.FindObjectsOfTypeAll<Font>())
|
||||
{
|
||||
if (font != null && font.dynamic && font != _font) found.Add(font);
|
||||
}
|
||||
_gameDynamicFonts = found.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>Drop every cached decision, so a settings change takes effect at once.</summary>
|
||||
internal static void ForgetChoices()
|
||||
{
|
||||
_substitutes.Clear();
|
||||
_gameDynamicFonts = new Font[0];
|
||||
foreach (var pair in _swapped)
|
||||
{
|
||||
if (pair.Key != null && pair.Value != null) pair.Key.font = pair.Value;
|
||||
}
|
||||
_swapped.Clear();
|
||||
}
|
||||
|
||||
/// <summary>Re-check every live label. Scene loads and language changes reassign
|
||||
/// fonts wholesale, and menus are built lazily, so sweep periodically too.</summary>
|
||||
internal static void ApplyToAll()
|
||||
{
|
||||
if (_font == null) return;
|
||||
|
||||
// Labels that have since been destroyed would otherwise pile up.
|
||||
var dead = new List<Text>();
|
||||
foreach (var pair in _swapped)
|
||||
{
|
||||
if (pair.Key == null) dead.Add(pair.Key);
|
||||
}
|
||||
foreach (var text in dead) _swapped.Remove(text);
|
||||
|
||||
RefreshGameFonts();
|
||||
foreach (var text in Object.FindObjectsOfType<Text>()) Apply(text);
|
||||
}
|
||||
|
||||
private static bool NeedsSubstitute(Font font, string content)
|
||||
{
|
||||
if (!CustomLanguageActive()) return false;
|
||||
|
||||
var gaps = GapsOf(font);
|
||||
if (gaps.Length == 0) return false;
|
||||
|
||||
// Ordinary UI faces are replaced everywhere they appear, so a menu never
|
||||
// mixes typefaces. Stylised readouts only give way when a glyph is at stake.
|
||||
if (!IsStylised(font.name)) return true;
|
||||
|
||||
if (string.IsNullOrEmpty(content)) return false;
|
||||
foreach (var c in content)
|
||||
{
|
||||
if (gaps.IndexOf(c) >= 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string GapsOf(Font font)
|
||||
{
|
||||
var id = font.GetInstanceID();
|
||||
string gaps;
|
||||
if (_gaps.TryGetValue(id, out gaps)) return gaps;
|
||||
|
||||
// Dynamic fonts only report a character as present once it has been
|
||||
// rasterised, so ask for the whole Slovak set before probing.
|
||||
if (font.dynamic) font.RequestCharactersInTexture(SlovakLetters);
|
||||
|
||||
var builder = new StringBuilder();
|
||||
foreach (var c in SlovakLetters)
|
||||
{
|
||||
if (!font.HasCharacter(c)) builder.Append(c);
|
||||
}
|
||||
gaps = builder.ToString();
|
||||
_gaps[id] = gaps;
|
||||
|
||||
if (gaps.Length > 0)
|
||||
{
|
||||
_mod?.ModHelper.Console.WriteLine(
|
||||
$"font \"{font.name}\" cannot draw \"{gaps}\" — " +
|
||||
(IsStylised(font.name) ? "substituting only where needed" : "substituting everywhere"),
|
||||
MessageType.Info);
|
||||
}
|
||||
return gaps;
|
||||
}
|
||||
|
||||
private static bool IsStylised(string fontName)
|
||||
{
|
||||
foreach (var stylised in Stylised)
|
||||
{
|
||||
if (fontName.IndexOf(stylised, System.StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>True while a mod-registered language is selected. The Localization
|
||||
/// Utility appends custom languages past <c>Language.TOTAL</c>, and treats
|
||||
/// everything up to it as vanilla — same test it uses itself.</summary>
|
||||
private static bool CustomLanguageActive()
|
||||
{
|
||||
if (TextTranslation.s_theTable == null) return false;
|
||||
return TextTranslation.Get().GetLanguage() > TextTranslation.Language.TOTAL;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hooks: every label as it appears or changes, plus a sweep whenever the game
|
||||
/// reassigns fonts wholesale.
|
||||
/// </summary>
|
||||
[HarmonyPatch]
|
||||
internal static class SlovakFontPatches
|
||||
{
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(Text), "OnEnable")]
|
||||
public static void TextEnabled(Text __instance) => SlovakFont.Apply(__instance);
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(Text), "text", MethodType.Setter)]
|
||||
public static void TextChanged(Text __instance) => SlovakFont.Apply(__instance);
|
||||
|
||||
// The game reassigns fonts wholesale when the language changes. Re-deciding here
|
||||
// is safe: our own assignment re-enters once, finds the state already correct,
|
||||
// and stops.
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(Text), "font", MethodType.Setter)]
|
||||
public static void FontAssigned(Text __instance) => SlovakFont.Apply(__instance);
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(TextTranslation), nameof(TextTranslation.SetLanguage))]
|
||||
public static void LanguageChanged() => SlovakFont.ApplyToAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper;
|
||||
|
||||
namespace SlovakTranslation
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers Slovenčina as a selectable language via xen-42's Localization
|
||||
/// Utility (xen.LocalizationUtility). All the heavy lifting lives in the
|
||||
/// utility; this mod just points it at our translated strings and patches the
|
||||
/// few menu/HUD fonts that were never baked with Slovak glyphs (see
|
||||
/// <see cref="SlovakFont"/>).
|
||||
/// </summary>
|
||||
public class SlovakTranslation : ModBehaviour
|
||||
{
|
||||
public static SlovakTranslation Instance;
|
||||
|
||||
/// <summary>Name the language is registered (and displayed) under.</summary>
|
||||
public const string LanguageName = "Slovenčina";
|
||||
|
||||
/// <summary>Path (relative to the mod folder) to the translated strings.</summary>
|
||||
public static string translationFile = "assets/Translation.xml";
|
||||
|
||||
/// <summary>The Localization Utility's API, kept for reflection in <see cref="SlovakFont"/>.</summary>
|
||||
internal static ILocalizationAPI LocalizationApi;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
LocalizationApi = ModHelper.Interaction.TryGetModApi<ILocalizationAPI>("xen.LocalizationUtility");
|
||||
if (LocalizationApi == null)
|
||||
{
|
||||
ModHelper.Console.WriteLine(
|
||||
"Could not find xen.LocalizationUtility — is Interplanetary Polyglot installed?",
|
||||
MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
LocalizationApi.RegisterLanguage(this, LanguageName, translationFile);
|
||||
ModHelper.Console.WriteLine("Registered language: " + LanguageName, MessageType.Success);
|
||||
|
||||
// Deliberately *not* AddLanguageFont: that would make IsLanguageLatin false
|
||||
// and pull dialogue, the translator and the ship log off their correct
|
||||
// vanilla fonts. We only patch the fonts that can't draw Slovak.
|
||||
SlovakFont.Load(this);
|
||||
if (SlovakFont.Loaded)
|
||||
{
|
||||
new Harmony("Homer.SlovakTranslation").PatchAll();
|
||||
UnityEngine.SceneManagement.SceneManager.sceneLoaded += (scene, mode) => SlovakFont.ApplyToAll();
|
||||
ModHelper.Console.WriteLine("Slovak menu/HUD font (Cabin) loaded and patched in.", MessageType.Success);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <c>preferGameTypeface</c> — when on, a menu font that can't draw Slovak is
|
||||
/// replaced by the game's own dynamic cut of the same typeface where one exists,
|
||||
/// so the menu keeps its vanilla look. Turn it off to use the bundled Cabin
|
||||
/// everywhere instead.
|
||||
/// </summary>
|
||||
public override void Configure(IModConfig config)
|
||||
{
|
||||
SlovakFont.PreferGameTypeface = config.GetSettingsValue<bool>("preferGameTypeface");
|
||||
if (!SlovakFont.Loaded) return;
|
||||
|
||||
SlovakFont.ForgetChoices();
|
||||
SlovakFont.ApplyToAll();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<LangVersion>default</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
<RootNamespace>SlovakTranslation</RootNamespace>
|
||||
<AssemblyName>SlovakTranslation</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Lets net48 build on machines without the .NET Framework targeting pack
|
||||
(e.g. Linux / dotnet SDK only). Build-time only. -->
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
<PackageReference Include="HarmonyX" Version="2.10.0" />
|
||||
<PackageReference Include="OWML" Version="2.5.2" />
|
||||
<!-- Provides the Outer Wilds / Unity reference DLLs from NuGet, so no game
|
||||
install is needed to compile. -->
|
||||
<PackageReference Include="OuterWildsGameLibs" Version="1.1.12.168" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="manifest.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="default-config.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="assets/Translation.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="assets/slovakfont">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30114.105
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlovakTranslation", "SlovakTranslation.csproj", "{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,93 @@
|
||||
Copyright 2018 The Cabin Project Authors (https://github.com/impallari/Cabin.git)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
+16268
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"settings": {
|
||||
"preferGameTypeface": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"filename": "SlovakTranslation.dll",
|
||||
"author": "Jaroslav Beneš",
|
||||
"name": "Slovak Localization / Slovenčina",
|
||||
"uniqueName": "Homer.SlovakTranslation",
|
||||
"version": "1.0.0",
|
||||
"owmlVersion": "2.5.2",
|
||||
"dependencies": [
|
||||
"xen.LocalizationUtility"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user