Skip to content

Commit

Permalink
Version 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
rcav8tr committed Dec 12, 2024
1 parent 161ccf8 commit 04939a2
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 62 deletions.
2 changes: 1 addition & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
- Initial release.
- Fix occasional initialization error.
2 changes: 1 addition & 1 deletion IBLIV.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<!--The file where mod information which is required for publishing mod on PDX mods are stored-->
<PublishConfigurationPath>Properties\PublishConfiguration.xml</PublishConfigurationPath>
<Title>Improved Building Level Info View</Title>
<Version>1.0.0</Version>
<Version>1.0.1</Version>
<Description>Improvements to the Building Level info view.</Description>
<Copyright>Copyright © 2024</Copyright>
<PDXAccountDataPath>$(USERPROFILE)\Documents\Visual Studio Projects\Cities Skylines 2 Mods\My Mods\pdx_account.txt</PDXAccountDataPath>
Expand Down
2 changes: 1 addition & 1 deletion Library/ilpp.pid
Original file line number Diff line number Diff line change
@@ -1 +1 @@
23104
2104
58 changes: 38 additions & 20 deletions Localization/Translation.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Colossal;
using Colossal.Localization;
using Game.SceneFlow;
using System;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -138,16 +140,19 @@ public static void Initialize()
return;
}

// Read the lines from the translation CSV file.
string[] lines;
// Read the text from the translation CSV file.
string fileText;
using (Stream fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(translationFile))
{
using (StreamReader fileReader = new StreamReader(fileStream, Encoding.UTF8))
{
lines = fileReader.ReadToEnd().Split(new string[] { "\n", "\r\n" }, StringSplitOptions.None);
fileText = fileReader.ReadToEnd();
}
}

// Split the text into lines.
string[] lines = fileText.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.None);

// First line cannot be blank or a comment.
string firstLine = lines[0];
if (firstLine.Trim().Length == 0 || firstLine.StartsWith("#"))
Expand All @@ -172,11 +177,26 @@ public static void Initialize()
{
translationKeyCount.Add(translationKey, 0);
}

// Check if file text has any $$ references to game translations.
Dictionary<string, LocalizationDictionary> gameTranslations = new Dictionary<string, LocalizationDictionary>();
LocalizationManager localizationManager = GameManager.instance.localizationManager;
if (fileText.Contains("$$"))
{
// Get game translations once here instead of every time a $$ reference is encountered.
string currentLocaleID = localizationManager.activeLocaleId;
foreach (string gameLocaleID in localizationManager.GetSupportedLocales())
{
localizationManager.SetActiveLocale(gameLocaleID);
gameTranslations[gameLocaleID] = localizationManager.activeDictionary;
}
localizationManager.SetActiveLocale(currentLocaleID);
}

// Process each subsequent line.
for (int i = 1; i < lines.Length; i++)
{
ProcessTranslationLine(lines[i], languages, temporaryTranslations, translationKeys, translationKeyCount);
ProcessTranslationLine(lines[i], languages, temporaryTranslations, gameTranslations, translationKeys, translationKeyCount);
}

// Each translation key must be defined.
Expand All @@ -192,7 +212,7 @@ public static void Initialize()
// All the translations were read into the languages variable just for this right here.
foreach (string languageCode in languages.Keys)
{
Game.SceneFlow.GameManager.instance.localizationManager.AddSource(languageCode, new LocalizationSource(languages[languageCode]));
localizationManager.AddSource(languageCode, new LocalizationSource(languages[languageCode]));
}
}
catch(Exception ex)
Expand Down Expand Up @@ -267,6 +287,7 @@ private static void ProcessTranslationLine
string line,
Languages languages,
Languages temporaryTranslations,
Dictionary<string, LocalizationDictionary> gameTranslations,
string[] translationKeys,
Dictionary<string, int> translationKeyCount
)
Expand Down Expand Up @@ -319,10 +340,6 @@ Dictionary<string, int> translationKeyCount
}
}

// Save active locale ID.
Colossal.Localization.LocalizationManager localizationManager = Game.SceneFlow.GameManager.instance.localizationManager;
string savedLocaleID = localizationManager.activeLocaleId;

// Do each language code.
foreach (string languageCode in languages.Keys)
{
Expand Down Expand Up @@ -364,15 +381,22 @@ Dictionary<string, int> translationKeyCount
string gameTranslationKey = translatedText.Substring(2);

// Get the game's translation for the key.
localizationManager.SetActiveLocale(languageCode);
if (localizationManager.activeDictionary.TryGetValue(gameTranslationKey, out string gameTranslatedText))
if (gameTranslations.ContainsKey(languageCode))
{
// Use the game translated text.
translatedText = gameTranslatedText;
if (gameTranslations[languageCode].TryGetValue(gameTranslationKey, out string gameTranslatedText))
{
// Use the game translated text.
translatedText = gameTranslatedText;
}
else
{
LogUtil.Warn($"Game translation key [{gameTranslationKey}] does not exist for language [{languageCode}].");
// Leave the invalid $$ reference in the translated text.
}
}
else
{
LogUtil.Warn($"Game translation key [{gameTranslationKey}] does not exist for language [{languageCode}].");
LogUtil.Warn($"Game does not contain translations for language [{languageCode}] for translation key [{gameTranslationKey}].");
// Leave the invalid $$ reference in the translated text.
}
}
Expand Down Expand Up @@ -434,12 +458,6 @@ Dictionary<string, int> translationKeyCount
}
}
}

// Restore saved locale ID.
if (localizationManager.activeLocaleId != savedLocaleID)
{
localizationManager.SetActiveLocale(savedLocaleID);
}
}
}

Expand Down
5 changes: 0 additions & 5 deletions Localization/Translation.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
,"en-US","de-DE","es-ES","fr-FR","it-IT","ja-JP","ko-KR","pl-PL","pt-BR","ru-RU","zh-HANS","zh-HANT"
"# Mod title and description.",,,,,,,,,,,,
"Title","Improved Building Level Info View","Verbesserte Gebäudeebenen-Infoansicht","Vista de información de nivel de edificio mejorada","Amélioration de la vue d'informations sur le niveau du bâtiment","Visualizzazione informazioni livello edificio migliorata","建物レベルの情報ビューの改善","개선된 건물 레벨 정보 보기","Ulepszony widok informacji na poziomie budynku","Visualização de informações do nível do edifício aprimorada","Улучшенный вид информации об уровне здания","改进了建筑等级信息视图","改進的建築層資訊視圖"
"Description","Improvements to the Building Level info view.","Verbesserungen der Gebäudeebenen-Infoansicht.","Mejoras en la vista de información de nivel de edificio.","Améliorations apportées à la vue d'informations sur le niveau du bâtiment.","Miglioramenti alla visualizzazione informazioni livello edificio.","建物レベルの情報ビューが改善されました。","건물 레벨 정보 보기 개선.","Ulepszenia widoku informacji na poziomie budynku.","Melhorias na visualização de informações do nível do edifício.","Улучшения в виде информации об уровне здания.","改进了建筑等级信息视图。","建築物級別資訊視圖的改進。"
,,,,,,,,,,,,
,,,,,,,,,,,,
"# Infomode titles.",,,,,,,,,,,,
"@@BuildingLevel","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]","$$Infoviews.INFOMODE[Level]"
"@@Residential","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL","$$LevelInfoPanel.RESIDENTIAL"
Expand Down
20 changes: 8 additions & 12 deletions Localization/UITranslationKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,16 @@ namespace IBLIV
// Define UI translation keys.
public class UITranslationKey
{
// Mod title and description.
public const string Title = "IBLIV.Title";
public const string Description = "IBLIV.Description";

// Infomode titles.
public const string InfomodeTitleLevelResidential = "Infoviews.INFOMODE[IBLIVLevelResidential]";
public const string InfomodeTitleLevelCommercial = "Infoviews.INFOMODE[IBLIVLevelCommercial]";
public const string InfomodeTitleLevelIndustrial = "Infoviews.INFOMODE[IBLIVLevelIndustrial]";
public const string InfomodeTitleLevelOffice = "Infoviews.INFOMODE[IBLIVLevelOffice]";
public const string InfomodeTitleLevelResidential = "Infoviews.INFOMODE[" + ModAssemblyInfo.Name + "LevelResidential]";
public const string InfomodeTitleLevelCommercial = "Infoviews.INFOMODE[" + ModAssemblyInfo.Name + "LevelCommercial]";
public const string InfomodeTitleLevelIndustrial = "Infoviews.INFOMODE[" + ModAssemblyInfo.Name + "LevelIndustrial]";
public const string InfomodeTitleLevelOffice = "Infoviews.INFOMODE[" + ModAssemblyInfo.Name + "LevelOffice]";

// Infomode tooltips.
public const string InfomodeTooltipLevelResidential = "Infoviews.INFOMODE_TOOLTIP[IBLIVLevelResidential]";
public const string InfomodeTooltipLevelCommercial = "Infoviews.INFOMODE_TOOLTIP[IBLIVLevelCommercial]";
public const string InfomodeTooltipLevelIndustrial = "Infoviews.INFOMODE_TOOLTIP[IBLIVLevelIndustrial]";
public const string InfomodeTooltipLevelOffice = "Infoviews.INFOMODE_TOOLTIP[IBLIVLevelOffice]";
public const string InfomodeTooltipLevelResidential = "Infoviews.INFOMODE_TOOLTIP[" + ModAssemblyInfo.Name + "LevelResidential]";
public const string InfomodeTooltipLevelCommercial = "Infoviews.INFOMODE_TOOLTIP[" + ModAssemblyInfo.Name + "LevelCommercial]";
public const string InfomodeTooltipLevelIndustrial = "Infoviews.INFOMODE_TOOLTIP[" + ModAssemblyInfo.Name + "LevelIndustrial]";
public const string InfomodeTooltipLevelOffice = "Infoviews.INFOMODE_TOOLTIP[" + ModAssemblyInfo.Name + "LevelOffice]";
}
}
2 changes: 2 additions & 0 deletions Mod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ public void OnLoad(UpdateSystem updateSystem)
{
LogUtil.Exception(ex);
}

LogUtil.Info($"{nameof(Mod)}.{nameof(OnLoad)} complete.");
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion ModAssemblyInfo/ModAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace IBLIV
public class ModAssemblyInfo
{
public const string Name = "IBLIV";
public const string Version = "1.0.0";
public const string Version = "1.0.1";
public const string Title = "Improved Building Level Info View";
public const string Description = "Improvements to the Building Level info view.";
}
Expand Down
4 changes: 2 additions & 2 deletions Properties/PublishConfiguration.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ The following mods were used extensively in the development of this mod:
<ForumLink Value="https://forum.paradoxplaza.com/forum/threads/improved-building-level-info-view.1718627/" />

<!-- Version of the mod. Copied from assembly Version. -->
<ModVersion Value="1.0.0" />
<ModVersion Value="1.0.1" />

<!-- Recommended version of the base game to use the mod. -->
<GameVersion Value="1.*" />
Expand All @@ -63,7 +63,7 @@ The following mods were used extensively in the development of this mod:

<!-- Change log. Copied from ChangeLog.md file. Supports minimal markdown subset. -->
<ChangeLog>
- Initial release.
- Fix occasional initialization error.
</ChangeLog>

<!-- External links. Supported types are discord, github, youtube, twitch, x, paypal, patreon, buymeacoffee, kofi, crowdin, gitlab. Can be set multiple times. -->
Expand Down
65 changes: 46 additions & 19 deletions Systems/BuildingLevelInfoviewSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Colossal.Mathematics;
using Colossal.Serialization.Entities;
using Game;
using Game.Prefabs;
using System;
Expand All @@ -14,19 +15,42 @@ namespace IBLIV
/// </summary>
public partial class BuildingLevelInfoviewSystem : GameSystemBase
{
// Initialization flag.
private bool _initialized = false;

/// <summary>
/// Initialize this system.
/// All the work of updating the building level infoview is performed in OnCreate().
/// Called when a game is about to be loaded.
/// </summary>
protected override void OnCreate()
protected override void OnGamePreload(Purpose purpose, GameMode mode)
{
base.OnCreate();
LogUtil.Info($"{nameof(BuildingLevelInfoviewSystem)}.{nameof(OnCreate)}");
base.OnGamePreload(purpose, mode);

// Initialization is performed in OnGamePreload instead of OnCreate because
// occasionally the signature infomode prefabs were not available when this system was created.
// It is not known why this happened only occasionally.

// Initialization is performed in OnGamePreload instead of OnGameLoadingComplete because
// the custom infoview icon does not get displayed if performed in OnGameLoadingComplete.

// Skip if already initialized.
if (_initialized)
{
return;
}

// Skip if not loading a game (i.e. is editor or main menu).
if (mode != GameMode.Game)
{
return;
}

LogUtil.Info($"{nameof(BuildingLevelInfoviewSystem)}.{nameof(OnGamePreload)} initialize");

try
{
// The game's infoviews must be created first.
// That will be the normal case, but perform the check anyway just in case.
// That will be the normal case by the time a game is about to be loaded.
// But perform the check anyway just in case.
InfoviewInitializeSystem infoviewInitializeSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<InfoviewInitializeSystem>();
if (infoviewInitializeSystem == null || infoviewInitializeSystem.infoviews.Count() == 0)
{
Expand All @@ -50,21 +74,9 @@ protected override void OnCreate()
return;
}

// Create a new building status infomode prefab for the building level of each zone type.
BuildingStatusInfomodePrefab infomodePrefabLevelResidential = CreateInfomodePrefab(ImprovedBuildingStatusType.LevelResidential);
BuildingStatusInfomodePrefab infomodePrefabLevelCommercial = CreateInfomodePrefab(ImprovedBuildingStatusType.LevelCommercial);
BuildingStatusInfomodePrefab infomodePrefabLevelIndustrial = CreateInfomodePrefab(ImprovedBuildingStatusType.LevelIndustrial);
BuildingStatusInfomodePrefab infomodePrefabLevelOffice = CreateInfomodePrefab(ImprovedBuildingStatusType.LevelOffice);

// Add the building status infomode prefabs to the prefab system.
PrefabSystem prefabSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<PrefabSystem>();
prefabSystem.AddPrefab(infomodePrefabLevelResidential);
prefabSystem.AddPrefab(infomodePrefabLevelCommercial);
prefabSystem.AddPrefab(infomodePrefabLevelIndustrial);
prefabSystem.AddPrefab(infomodePrefabLevelOffice);

// For signature buildings, the game's existing infomode prefabs are used instead of creating new infomode prefabs.
// Get the game's signature infomode prefab for each zone type.
PrefabSystem prefabSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<PrefabSystem>();
BuildingStatusInfomodePrefab infomodePrefabSignatureResidential = null;
BuildingStatusInfomodePrefab infomodePrefabSignatureCommercial = null;
BuildingStatusInfomodePrefab infomodePrefabSignatureIndustrial = null;
Expand Down Expand Up @@ -109,6 +121,18 @@ protected override void OnCreate()
if (infomodePrefabSignatureIndustrial == null) { LogUtil.Error("Unable to find infomode prefab for Signature Industrial." ); return; }
if (infomodePrefabSignatureOffice == null) { LogUtil.Error("Unable to find infomode prefab for Signature Office." ); return; }

// Create a new building status infomode prefab for the building level of each zone type.
BuildingStatusInfomodePrefab infomodePrefabLevelResidential = CreateInfomodePrefab(ImprovedBuildingStatusType.LevelResidential);
BuildingStatusInfomodePrefab infomodePrefabLevelCommercial = CreateInfomodePrefab(ImprovedBuildingStatusType.LevelCommercial);
BuildingStatusInfomodePrefab infomodePrefabLevelIndustrial = CreateInfomodePrefab(ImprovedBuildingStatusType.LevelIndustrial);
BuildingStatusInfomodePrefab infomodePrefabLevelOffice = CreateInfomodePrefab(ImprovedBuildingStatusType.LevelOffice);

// Add the building status infomode prefabs to the prefab system.
prefabSystem.AddPrefab(infomodePrefabLevelResidential);
prefabSystem.AddPrefab(infomodePrefabLevelCommercial);
prefabSystem.AddPrefab(infomodePrefabLevelIndustrial);
prefabSystem.AddPrefab(infomodePrefabLevelOffice);

// Remove the existing infomodes from the building level infoview.
DynamicBuffer<InfoviewMode> infomodesBuildingLevel = prefabSystem.GetBuffer<InfoviewMode>(buildingLevelInfoviewPrafab, isReadOnly: false);
infomodesBuildingLevel.Clear();
Expand All @@ -126,6 +150,9 @@ protected override void OnCreate()

// Set a new custom icon on building level infoview.
buildingLevelInfoviewPrafab.m_IconPath = $"coui://{Mod.ImagesURI}/ImprovedBuildingLevel.svg";

// Initialized.
_initialized = true;
}
catch (Exception ex)
{
Expand Down

0 comments on commit 04939a2

Please sign in to comment.