From fa7f9acc97e380bba267ff3c9203427c1c2745b9 Mon Sep 17 00:00:00 2001 From: Quantumrunner <58113888+Quantumrunner@users.noreply.github.com> Date: Sat, 17 Jan 2026 14:29:36 +0100 Subject: [PATCH 1/6] Removed all code related to imperial assault. --- .../FFGAppImport/AssetImport/FetchContent.cs | 5 - .../FFGAppImport/AssetImport/IAFinder.cs | 76 --- libraries/FFGAppImport/FFGAppImport.cs | 3 +- libraries/IADBExtract/IADBExtract.csproj | 59 --- libraries/IADBExtract/Inject.cs | 496 ------------------ .../IADBExtract/Properties/AssemblyInfo.cs | 36 -- unity/Assets/Scripts/Content/QuestLoader.cs | 10 +- unity/Assets/Scripts/GameType.cs | 91 ---- unity/Assets/Scripts/Quest/EventManager.cs | 22 +- .../QuestEditor/EditorComponentEvent.cs | 4 +- .../QuestEditor/EditorComponentSpawn.cs | 2 +- .../Scripts/QuestEditor/QuestEditorData.cs | 2 +- .../Scripts/UI/Screens/EndGameScreen.cs | 2 +- .../Scripts/UI/Screens/GameSelectionScreen.cs | 119 +---- unity/Assets/StreamingAssets/content/IA.meta | 9 - .../StreamingAssets/content/IA/CoreSet.meta | 9 - .../content/IA/CoreSet/SWI01.meta | 9 - .../IA/CoreSet/SWI01/Localization.English.txt | 5 - .../SWI01/Localization.English.txt.meta | 8 - .../content/IA/CoreSet/SWI01/tiles.ini | 8 - .../content/IA/CoreSet/SWI01/tiles.ini.meta | 8 - .../content/IA/CoreSet/SWI01/tokens.ini | 2 - .../content/IA/CoreSet/SWI01/tokens.ini.meta | 8 - .../text/Localization.Chinese.txt | 6 - .../text/Localization.Czech.txt | 6 - .../text/Localization.English.txt | 6 - .../text/Localization.French.txt | 6 - .../text/Localization.German.txt | 6 - .../text/Localization.Japanese.txt | 6 - .../text/Localization.Korean.txt | 6 - .../text/Localization.Portuguese.txt | 6 - .../text/Localization.Russian.txt | 6 - .../UnitTests/Editor/EventManagerTests.cs | 94 +--- .../Assets/UnitTests/Editor/GameTypeTests.cs | 237 +-------- 34 files changed, 25 insertions(+), 1353 deletions(-) delete mode 100644 libraries/FFGAppImport/AssetImport/IAFinder.cs delete mode 100644 libraries/IADBExtract/IADBExtract.csproj delete mode 100644 libraries/IADBExtract/Inject.cs delete mode 100644 libraries/IADBExtract/Properties/AssemblyInfo.cs delete mode 100644 unity/Assets/StreamingAssets/content/IA.meta delete mode 100644 unity/Assets/StreamingAssets/content/IA/CoreSet.meta delete mode 100644 unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01.meta delete mode 100644 unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/Localization.English.txt delete mode 100644 unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/Localization.English.txt.meta delete mode 100644 unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tiles.ini delete mode 100644 unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tiles.ini.meta delete mode 100644 unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tokens.ini delete mode 100644 unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tokens.ini.meta diff --git a/libraries/FFGAppImport/AssetImport/FetchContent.cs b/libraries/FFGAppImport/AssetImport/FetchContent.cs index 26758d181..532d7e856 100644 --- a/libraries/FFGAppImport/AssetImport/FetchContent.cs +++ b/libraries/FFGAppImport/AssetImport/FetchContent.cs @@ -38,11 +38,6 @@ public FetchContent(FFGImport import) finder = new MoMFinder(import.platform); gameType = "MoM"; } - else if (import.type == GameType.IA) - { - finder = new IAFinder(import.platform); - gameType = "IA"; - } else { return; diff --git a/libraries/FFGAppImport/AssetImport/IAFinder.cs b/libraries/FFGAppImport/AssetImport/IAFinder.cs deleted file mode 100644 index 3060ce468..000000000 --- a/libraries/FFGAppImport/AssetImport/IAFinder.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using ValkyrieTools; - -namespace FFGAppImport -{ - public class IAFinder : AppFinder - { - protected string obbPath; - - public IAFinder(Platform p) - : base(p) - { - } - - // If the installed app isn't this or higher don't import - override public string RequiredFFGVersion() - { - return "1.0.0"; - } - // Steam app ID - override public string AppId() - { - return "703980"; - } - // Where to store imported data - override public string Destination() - { - return "IA"; - } - - override public string DataDirectory() - { - if (platform == Platform.MacOS) - { - return "/Contents/Resources/Data"; - } - else if (platform == Platform.Android) - { - return ""; - } - return "/Imperial Assault_Data"; - } - override public string Executable() - { - if (platform == Platform.MacOS) - { - return "Imperial Assault.app"; - } - return "Imperial Assault.exe"; - } - // IA does not obfuscate text - override public int ObfuscateKey() - { - return 0; - } - - public override string DataPath() - { - return GetDataPath("com.fantasyflightgames.iaca"); - } - - public override string AuxDataPath() - { - return GetAuxDataPath("com.fantasyflightgames.iaca"); - } - - public override string ObbPath() - { - if (obbPath != null) // try this only once - return obbPath; - obbPath = GetObbPath("Android/obb/com.fantasyflightgames.iaca", ".com.fantasyflightgames.iaca.obb"); - return obbPath; - } - } -} \ No newline at end of file diff --git a/libraries/FFGAppImport/FFGAppImport.cs b/libraries/FFGAppImport/FFGAppImport.cs index bde67826a..8a7f04d8a 100644 --- a/libraries/FFGAppImport/FFGAppImport.cs +++ b/libraries/FFGAppImport/FFGAppImport.cs @@ -51,8 +51,7 @@ public bool Import(string import_path) public enum GameType { D2E, - MoM, - IA + MoM } public enum Platform diff --git a/libraries/IADBExtract/IADBExtract.csproj b/libraries/IADBExtract/IADBExtract.csproj deleted file mode 100644 index e87bf8945..000000000 --- a/libraries/IADBExtract/IADBExtract.csproj +++ /dev/null @@ -1,59 +0,0 @@ - - - - - Debug - AnyCPU - {BCFBB92E-2902-4E7C-8FD8-E0369927DA99} - Library - Properties - IADBExtract - IADBExtract - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - $(steampath)\steamapps\common\Imperial Assault\Imperial Assault_Data\Managed\ - TRACE - prompt - 4 - - - - $(steampath)\steamapps\common\Imperial Assault\Imperial Assault_Data\Managed\Assembly-CSharp.dll - - - - - - - - - - $(steampath)\steamapps\common\Imperial Assault\Imperial Assault_Data\Managed\UnityEngine.dll - - - - - - - - - \ No newline at end of file diff --git a/libraries/IADBExtract/Inject.cs b/libraries/IADBExtract/Inject.cs deleted file mode 100644 index 7ed3518b8..000000000 --- a/libraries/IADBExtract/Inject.cs +++ /dev/null @@ -1,496 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using FFG.IA; -using System.IO; - -namespace IADBExtract -{ - public static class Inject - { - public static int Extract(bool unused) - { - if (File.Exists(Extractor.outputDir + "log.txt")) return 0; - Extractor extractor = new Extractor(SingletonBehaviour.Instance.Database); - try - { - extractor.Extract(); - } - catch (Exception e) - { - extractor.WriteLog(e.Message); - } - return 0; - } - } - - public class Extractor - { - public static string outputDir = "C:\\Users\\Bruce\\Desktop\\IA\\"; - public static Extractor e; - - List logData; - IA_Database db; - public Dictionary packs = new Dictionary(); - - public Extractor(IA_Database database) - { - e = this; - db = database; - } - - public void Log(string toLog) - { - logData.Add(toLog); - } - - public void WriteLog(string final = null) - { - if (final != null) - { - logData.Add(final); - } - File.WriteAllLines(outputDir + "log.txt", logData); - } - - public void Extract() - { - Log("Starting Extraction"); - Directory.CreateDirectory(outputDir); - foreach(IA_ProductModel product in db.Products) - { - Log("Next Product"); - ExtractProduct(product); - } - foreach (IA_CampaignModel campaign in db.Campaigns) - { - Log("Next Campaign"); - ExtractCampaign(campaign); - } - } - - public void ExtractCampaign(IA_CampaignModel campaign) - { - Log("Campaign " + campaign.Title.Key); - Directory.CreateDirectory(outputDir + "campaign"); - List campaignData = new List(); - campaignData.Add("Title: " + campaign.Title.Key); - campaignData.Add("Description: " + campaign.Description.Key); - campaignData.Add("Contents: " + campaign.Contents.Key); - if (campaign.RequiredProduct != null) - { - campaignData.Add("RequiredProduct: " + campaign.RequiredProduct.NameKey); - } - campaignData.Add("Image: " + campaign.Image.Path); - campaignData.Add("Fame Insignificant: " + campaign.CampaignFameThresholds.Insignificant + " Noteworthy: " + campaign.CampaignFameThresholds.Noteworthy + " Impressive: " + campaign.CampaignFameThresholds.Impressive + " Celebrated: " + campaign.CampaignFameThresholds.Celebrated + " Heroic: " + campaign.CampaignFameThresholds.Heroic + " Legendary: " + campaign.CampaignFameThresholds.Legendary); - campaignData.Add("Normal Gold per Hero: " + campaign.DifficultyNormal.StartingGoldPerHero + " Start Peril: " + campaign.DifficultyNormal.QuestStartingPeril + " Reduce Peril: " + campaign.DifficultyNormal.PerilReduction); - campaignData.Add("Hard Gold per Hero: " + campaign.DifficultyHard.StartingGoldPerHero + " Start Peril: " + campaign.DifficultyHard.QuestStartingPeril + " Reduce Peril: " + campaign.DifficultyHard.PerilReduction); - - foreach (IA_CampaignTaskModel task in campaign.Tasks) - { - // TODO: Tasks details - campaignData.Add("Task: " + task.NameKey); - } - foreach (IA_PerilModel peril in campaign.Perils) - { - // TODO: Perils - campaignData.Add("Peril: " + peril.Level.ToString()); - } - - foreach (IA_MissionModel mission in campaign.StoryQuests) - { - campaignData.Add("Story Mission: " + mission.NameKey); - ExtractMission(mission); - } - foreach (IA_MissionModel mission in campaign.SideQuests) - { - campaignData.Add("Side Mission: " + mission.NameKey); - ExtractMission(mission); - } - campaignData.Add("HasTutorial: " + campaign.HasTutorial); - campaignData.Add("StartingMission: " + campaign.StartingMission.NameKey); - if (campaign.NewPlayersStartingMission != null) - { - campaignData.Add("NewPlayersStartingMission: " + campaign.NewPlayersStartingMission.NameKey); - } - File.WriteAllLines(outputDir + "campaign\\" + campaign.Title.Key + ".txt", campaignData.ToArray()); - } - - public void ExtractMission(IA_MissionModel mission) - { - Directory.CreateDirectory(outputDir + "campaign"); - List missionData = new List(); - missionData.Add("Title: " + mission.NameKey); - missionData.Add("Description: " + mission.DescriptionKey); - missionData.Add("Image: " + mission.Image.Path); - missionData.Add("IsFinale: " + mission.IsFinale); - missionData.Add("CanFail: " + mission.CanFail); - missionData.Add("IncapacitatedInsteadOfWithdrawn: " + mission.IncapacitatedInsteadOfWithdrawn); - missionData.Add("IncapacitatedMessageKey: " + mission.IncapacitatedMessageKey); - missionData.Add("ParFame: " + mission.ParFame); - missionData.Add("ParRound: " + mission.ParRound); - missionData.Add("ThreatLevel: " + mission.ThreatLevel); - missionData.Add("XPValueAwardedOnFinish: " + mission.XPValueAwardedOnFinish); - missionData.Add("CreditsAwardedOnFinish: " + mission.CreditsAwardedOnFinish); - missionData.Add("CreditsAwardedPerHeroOnFinish: " + mission.CreditsAwardedPerHeroOnFinish); - missionData.Add("CreditsAwardedPerHeroOnVictory: " + mission.CreditsAwardedPerHeroOnVictory); - missionData.Add("BaseMinorPerilLevel: " + mission.BaseMinorPerilLevel); - missionData.Add("BaseMajorPerilLevel: " + mission.BaseMajorPerilLevel); - missionData.Add("BaseDeadlyPerilLevel: " + mission.BaseDeadlyPerilLevel); - missionData.Add("BlockEnemyDefeatFameAward: " + mission.BlockEnemyDefeatFameAward); - missionData.Add("BlockEndMissionRewards: " + mission.BlockEndMissionRewards); - missionData.Add("CanStartWithAllies: " + mission.CanStartWithAllies); - missionData.Add("RandomGroupThreatFloor: " + mission.RandomGroupThreatFloor); - missionData.Add("RandomGroupThreatCeiling: " + mission.RandomGroupThreatCeiling); - missionData.Add("Mission Type: " + mission.Type.ToString()); - missionData.Add("Location: " + mission.Location.NameKey); - foreach (IA_InventoryItemModel item in mission.ItemsAwardedOnFinish) - { - missionData.Add("Finish Item: " + item.NameKey); - } - foreach (IA_EnemyGroupModel enemy in mission.BlacklistedEnemyGroups) - { - missionData.Add("BlacklistedEnemy: " + enemy.EnemyType.KeySingular); - } - foreach (IA_EnemyGroupModel enemy in mission.ReservedEnemyGroups) - { - missionData.Add("ReservedEnemy: " + enemy.EnemyType.KeySingular); - } - foreach (IA_AllyModel ally in mission.BlacklistedAllies) - { - missionData.Add("Blacklisted Ally: " + ally.NameKey); - } - foreach (IA_ProductModel product in mission.RequiredProducts) - { - missionData.Add("Required Product: " + product.NameKey); - } - - File.WriteAllLines(outputDir + "campaign\\" + mission.NameKey + ".txt", missionData.ToArray()); - } - - public void ExtractProduct(IA_ProductModel product) - { - packs.Add(product.Code, new ContentPack(product)); - } - } - - public class ContentPack - { - public IA_ProductModel product; - public List includes = new List(); - - public ContentPack(IA_ProductModel p) - { - product = p; - Extractor.e.Log("Product Code: product.Code"); - Write(); - } - - public void Write() - { - if (product.EnemyTypes.Length > 0) - { - includes.Add("enemies.ini"); - includes.Add("activations.ini"); - WriteEnemies(); - } - - if (product.Items.Length > 0) - { - includes.Add("items.ini"); - WriteItems(); - } - - if (product.Heroes.Length > 0) - { - includes.Add("heroes.ini"); - includes.Add("skills.ini"); - WriteHeroes(); - } - - //IA_AllyModel product.Allies - - WritePack(); - } - - string TargetPath() - { - return Extractor.outputDir + product.Type.ToString() +"/" + product.Code + "/"; - } - - string PathStrip(string toConvert) - { - return Path.GetFileNameWithoutExtension(toConvert); - } - - void WriteEnemies() - { - List enemyData = new List(); - List activations = new List(); - foreach (IA_EnemyTypeModel enemy in product.EnemyTypes) - { - Extractor.e.Log("Product Code: " + product.Code + " Enemy " + enemy.KeySingular); - List enemyDataElite = new List(); - - enemyData.Add("[Monster" + enemy.KeySingular + "]"); - enemyDataElite.Add("[MonsterElite" + enemy.KeySingular + "]"); - - enemyData.Add("name={ffg:" + enemy.KeySingular + "}"); - enemyDataElite.Add("name={ffg:" + enemy.KeySingular + "}"); - - enemyData.Add("; Plural: " + enemy.KeyPlural); - enemyDataElite.Add("; Plural: " + enemy.KeyPlural); - - enemyData.Add("; Use Article: " + enemy.UseAnArticle); - enemyDataElite.Add("; Use Article: " + enemy.UseAnArticle); - - enemyData.Add("image=\"{import}/img/" + PathStrip(enemy.Icon.Path) + "\""); - enemyDataElite.Add("image=\"{import}/img/" + PathStrip(enemy.Icon.Path) + "\""); - - enemyData.Add("imageplace=\"{import}/img/" + PathStrip(enemy.ImagePlacement.Path) + "\""); - enemyDataElite.Add("imageplace=\"{import}/img/" + PathStrip(enemy.ImagePlacement.Path) + "\""); - - enemyData.Add("; Portrait: " + enemy.Portrait.Path + "\""); - enemyDataElite.Add("; Portrait: " + enemy.Portrait.Path + "\""); - - enemyData.Add("info={ffg:" + enemy.KeyInstructionsReg + "}"); - enemyDataElite.Add("info={ffg:" + enemy.KeyInstructionsElite + "}"); - - enemyData.Add("; Piority Override: " + enemy.KeySecondaryPriorityOverride); - enemyDataElite.Add("; Piority Override: " + enemy.KeySecondaryPriorityOverride); - - string surgeOrder = "; Surge Order: "; - foreach (string s in enemy.SurgePrioritiesReg) - { - surgeOrder += s; - } - enemyData.Add(surgeOrder); - string surgeOrderElite = "; Surge Order: "; - foreach (string s in enemy.SurgePrioritiesElite) - { - surgeOrderElite += s; - } - enemyDataElite.Add(surgeOrderElite); - - enemyData.Add("; Max Unit Count: " + enemy.MaxUnitCount); - enemyDataElite.Add("; Max Unit Count: " + enemy.MaxUnitCount); - - enemyData.Add("; Max Group Count: " + enemy.MaxInPlayGroupCount); - enemyDataElite.Add("; Max Group Count: " + enemy.MaxInPlayGroupCount); - - enemyData.Add("; Threat: " + enemy.UnitThreatReg); - enemyDataElite.Add("; Threat: " + enemy.UnitThreatElite); - - enemyData.Add("; Group Threat: " + enemy.TotalGroupThreatReg); - enemyDataElite.Add("; Group Threat: " + enemy.TotalGroupThreatElite); - - enemyData.Add("; Elites use normal activations: " + enemy.UseRegularActivations); - enemyDataElite.Add("; Elites use normal activations: " + enemy.UseRegularActivations); - - foreach (UnityEngine.AudioClip audio in enemy.RevealSounds) - { - enemyData.Add("; Audio: " + audio.ToString()); - enemyDataElite.Add("; Audio: " + audio.ToString()); - } - - string enemyTraits = "traits=" + enemy.Size.ToString(); - foreach (EnemyTraitsSet1 trait in Enum.GetValues(typeof(EnemyTraitsSet1))) - { - if ((enemy.TraitsSet1 & trait) != 0) - { - enemyTraits += " " + trait.ToString(); - } - } - enemyData.Add(enemyTraits); - enemyDataElite.Add(enemyTraits); - - enemyData.Add(""); - enemyData.AddRange(enemyDataElite); - enemyData.Add(""); - - for (int activation = 0; activation < enemy.ActionsReg.Length; activation++) - { - if (enemy.BonusReg.Length <= activation || enemy.TargetTraitsReg.Length <= activation || enemy.TargetsReg.Length <= activation) - { - activations.Add("; activation error"); - continue; - } - activations.Add("[MonsterActivation" + enemy.KeySingular + activation + "]"); - - List activationDetails = new List(); - activationDetails.Add("ability={ffg:" + enemy.BonusReg[activation].Key + "}"); - activationDetails.Add("; Additional range: " + enemy.BonusReg[activation].AdditionalRange); - activationDetails.Add("master={ffg:" + enemy.ActionsReg[activation].Key + "}"); - activationDetails.Add("; Default range: " + enemy.ActionsReg[activation].DefaultRange); - activationDetails.Add("; Secondary Priority: " + enemy.ActionsReg[activation].SecondaryPriority); - activationDetails.Add("; Target: " + enemy.TargetsReg[activation].Key); - foreach (IA_HeroModel.HeroTraits trait in Enum.GetValues(typeof(IA_HeroModel.HeroTraits))) - { - if ((enemy.TargetTraitsReg[activation] & trait) != 0) - { - activationDetails.Add("; Target Trait: " + trait.ToString()); - } - } - activationDetails.Add(""); - - activations.AddRange(activationDetails); - if (enemy.UseRegularActivations) - { - activations.Add("[MonsterActivationElite" + enemy.KeySingular + activation + "]"); - activations.AddRange(activationDetails); - } - } - - if (!enemy.UseRegularActivations) - { - for (int activation = 0; activation < enemy.ActionsElite.Length; activation++) - { - if (enemy.BonusElite.Length <= activation || enemy.TargetsElite.Length <= activation || enemy.TargetTraitsElite.Length <= activation) - { - activations.Add("; activation error"); - continue; - } - - activations.Add("[MonsterActivationElite" + enemy.KeySingular + activation + "]"); - activations.Add("ability={ffg:" + enemy.BonusElite[activation].Key + "}"); - activations.Add("; Additional range: " + enemy.BonusElite[activation].AdditionalRange); - activations.Add("master={ffg:" + enemy.ActionsElite[activation].Key + "}"); - activations.Add("; Default range: " + enemy.ActionsElite[activation].DefaultRange); - activations.Add("; Secondary Priority: " + enemy.ActionsElite[activation].SecondaryPriority); - activations.Add("; Target: " + enemy.TargetsElite[activation].Key); - foreach (IA_HeroModel.HeroTraits trait in Enum.GetValues(typeof(IA_HeroModel.HeroTraits))) - { - if ((enemy.TargetTraitsElite[activation] & trait) != 0) - { - activations.Add("; Target Trait: " + trait.ToString()); - } - } - activations.Add(""); - } - } - } - File.WriteAllLines(TargetPath() + "enemies.ini", enemyData.ToArray()); - File.WriteAllLines(TargetPath() + "activations.ini", activations.ToArray()); - } - - public void WriteItems() - { - List itemData = new List(); - foreach (IA_InventoryItemModel item in product.Items) - { - itemData.Add("[Item" + item.NameKey + "]"); - itemData.Add("name={ffg:" + item.NameKey + "}"); - itemData.Add("image=\"{import}/img/" + PathStrip(item.Icon.Path) + "\""); - itemData.Add("price=" + item.CostBuy); - itemData.Add("; priceFame=" + item.CostFame); - itemData.Add("; priceSell=" + item.CostSell); - itemData.Add("; Number of mod slots: " + item.NumberOfModSlots); - itemData.Add("; Starting Item: " + item.IsStartingItem); - string itemTraits = "traits=deck" + item.Deck.ToString() + " " + item.Type.ToString(); - /*if (item.ModType != ModTraits.None) - { - itemTraits += " mod" + item.ModType.ToString(); - }*/ - if (item.WeaponType != WeaponTraits.None) - { - itemTraits += " weapon" + item.WeaponType.ToString(); - } - itemData.Add(itemTraits); - itemData.Add(""); - } - File.WriteAllLines(TargetPath() + "items.ini", itemData.ToArray()); - } - - public void WriteHeroes() - { - List heroData = new List(); - List skillData = new List(); - foreach (IA_HeroModel hero in product.Heroes) - { - heroData.Add("[Hero" + hero.NameKey + "]"); - heroData.Add("name={ffg:" + hero.NameKey + "}"); - heroData.Add("image=\"{import}/img/" + PathStrip(hero.Icon.Path) + "\""); - heroData.Add("; Portrait " + hero.Portrait.Path); - heroData.Add("class=" + "Class" + hero.NameKey); - heroData.Add("; Weapon Type " + hero.WeaponType.ToString()); - string heroTraits = "traits=" + hero.Gender.ToString(); - foreach (IA_HeroModel.HeroTraits trait in Enum.GetValues(typeof(IA_HeroModel.HeroTraits))) - { - if ((hero.Traits & trait) != 0) - { - heroTraits += " " + trait.ToString(); - } - } - - heroData.Add("[Class" + hero.NameKey + "]"); - string startingItems = "items="; - foreach (IA_InventoryItemModel item in hero.StartingItems) - { - if (startingItems[startingItems.Length - 1] != '=') - { - startingItems += " "; - } - startingItems += "Item" + item.NameKey; - } - heroData.Add(startingItems); - heroData.Add(""); - - foreach (IA_SkillModel skill in hero.Skills) - { - skillData.Add("[Skill" + hero.NameKey + skill.NameKey + "]"); - skillData.Add("name={ffg:" + skill.NameKey + "}"); - skillData.Add("xp=" + skill.Cost); - string skillExceptions = "; Excpetions"; - foreach (IA_SkillModel.SkillExceptions except in Enum.GetValues(typeof(IA_SkillModel.SkillExceptions))) - { - if ((skill.Exceptions & except) != 0) - { - skillExceptions += " " + except.ToString(); - } - } - skillData.Add(skillExceptions); - skillData.Add(""); - } - } - File.WriteAllLines(TargetPath() + "heroes.ini", heroData.ToArray()); - File.WriteAllLines(TargetPath() + "skills.ini", skillData.ToArray()); - } - - public void WritePack() - { - List packData = new List(); - - packData.Add("[ContentPack]"); - packData.Add("name={ffg:" + product.NameKey + "}"); - packData.Add("description={ffg:" + product.DescriptionKey + "}"); - packData.Add("; Contents " + product.ContentsKey); - packData.Add("image=\"{import}/img/\"" + PathStrip(product.Image.Path) + "\""); - if (product.Type != IA_ProductModel.ExpansionType.CoreSet) - { - foreach (IA_ProductModel.ExpansionType packType in Enum.GetValues(typeof(IA_ProductModel.ExpansionType))) - { - if (packType == IA_ProductModel.ExpansionType.CoreSet) continue; - packData.Add(""); - packData.Add("[Pack" + packType.ToString() + "]"); - packData.Add("name={pck:" + packType.ToString().ToUpper() + "}"); - } - packData.Add(""); - packData.Add("[LanguageData]"); - packData.Add("pck Localization.English.txt"); - } - else - { - packData.Add("id=" + product.Code); - packData.Add("type=" + product.Type.ToString()); - } - packData.Add(""); - - packData.Add("[ContentPackData]"); - packData.AddRange(includes); - - File.WriteAllLines(TargetPath() + "content_pack.ini", packData.ToArray()); - } - } -} diff --git a/libraries/IADBExtract/Properties/AssemblyInfo.cs b/libraries/IADBExtract/Properties/AssemblyInfo.cs deleted file mode 100644 index 8a2a98fda..000000000 --- a/libraries/IADBExtract/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("IADBExtract")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("IADBExtract")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("2b9f7fec-7e27-421d-bea8-f889b39d2fea")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/unity/Assets/Scripts/Content/QuestLoader.cs b/unity/Assets/Scripts/Content/QuestLoader.cs index f0fe06186..3259db887 100644 --- a/unity/Assets/Scripts/Content/QuestLoader.cs +++ b/unity/Assets/Scripts/Content/QuestLoader.cs @@ -37,10 +37,7 @@ public class QuestLoader { { dataLocation += "/D2E/Editor"; } - if (game.gameType is IAGameType) - { - dataLocation += "/IA/Editor"; - } + questDirectories.AddRange(GetUnpackedQuests(dataLocation)); // Go through all directories @@ -94,10 +91,7 @@ public class QuestLoader { { dataLocation += "/D2E/Editor"; } - if (context.gameType == "IA") - { - dataLocation += "/IA/Editor"; - } + questDirectories.AddRange(GetUnpackedQuests(dataLocation)); diff --git a/unity/Assets/Scripts/GameType.cs b/unity/Assets/Scripts/GameType.cs index d6137a63e..0cecf0510 100644 --- a/unity/Assets/Scripts/GameType.cs +++ b/unity/Assets/Scripts/GameType.cs @@ -315,98 +315,7 @@ public override bool MonstersGrouped() { return false; } -} - -// Things for IA -public class IAGameType : GameType -{ - public override string BaseContentPackId() - { - return "BaseIA"; - } - - public override string DataDirectory() - { - return ContentData.ContentPath() + "IA/"; - } - - public override StringKey HeroName() - { - return new StringKey("val", "IA_HERO_NAME"); - } - - public override StringKey HeroesName() - { - return new StringKey("val", "IA_HEROES_NAME"); - } - - public override StringKey QuestName() - { - return new StringKey("val", "IA_QUEST_NAME"); - } - public override Font GetFont() - { - return (Font)Resources.Load("Fonts/Gara_Scenario_Desc"); - } - public override Font GetHeaderFont() - { - return (Font)Resources.Load("Fonts/Windl"); - } - public override Font GetSymbolFont() - { - return (Font)Resources.Load("Fonts/Gara_Scenario_Desc"); - } - - public override int MaxHeroes() - { - return 4; - } - - public override int DefaultHeroes() - { - return 4; - } - - public override bool DisplayHeroes() - { - return true; - } - - // Tiles imported from RtL have 105 pixels per square (each 1 inch) - public override float TilePixelPerSquare() - { - return 105; - } - - public override string TypeName() - { - return "IA"; - } - - public override bool TileOnGrid() - { - return true; - } - public override bool DisplayMorale() - { - return true; - } - - public override float SelectionRound() - { - return 1f; - } - - public override float TileRound() - { - return 1f; - } - - public override bool MonstersGrouped() - { - return false; - } } diff --git a/unity/Assets/Scripts/Quest/EventManager.cs b/unity/Assets/Scripts/Quest/EventManager.cs index 71c7b8d25..99df01e9b 100644 --- a/unity/Assets/Scripts/Quest/EventManager.cs +++ b/unity/Assets/Scripts/Quest/EventManager.cs @@ -978,21 +978,7 @@ public static Dictionary GetCharacterMap(bool addRnd = false, bo {"{clue}", ""}, } }, - { "IA", new Dictionary() - { - {"{action}", ""}, - {"{wound}", ""}, - {"{surge}", ""}, - {"{attack}", ""}, - {"{strain}", ""}, - {"{tech}", ""}, - {"{insight}", ""}, - {"{strength}", ""}, - {"{block}", ""}, - {"{evade}", ""}, - {"{dodge}", ""}, - } - } + }; public static Dictionary> CHAR_PACKS_MAP = new Dictionary> @@ -1014,11 +1000,7 @@ public static Dictionary GetCharacterMap(bool addRnd = false, bo {"{MAD28}", ""}, } }, - { "IA", new Dictionary() - { - {"{SWI01}", ""}, - } - } + }; } diff --git a/unity/Assets/Scripts/QuestEditor/EditorComponentEvent.cs b/unity/Assets/Scripts/QuestEditor/EditorComponentEvent.cs index dd35c7ce3..6055eaa61 100644 --- a/unity/Assets/Scripts/QuestEditor/EditorComponentEvent.cs +++ b/unity/Assets/Scripts/QuestEditor/EditorComponentEvent.cs @@ -104,7 +104,7 @@ override public float AddSubComponents(float offset) } offset++; - if (game.gameType is D2EGameType || game.gameType is IAGameType) + if (game.gameType is D2EGameType) { offset = AddHeroSelection(offset); } @@ -920,7 +920,7 @@ public void AddVisibility(bool add, int index = -1) select.AddItem("#shop", traits); } - if (game.gameType is D2EGameType || game.gameType is IAGameType) + if (game.gameType is D2EGameType) { select.AddNewComponentItem("Door"); } diff --git a/unity/Assets/Scripts/QuestEditor/EditorComponentSpawn.cs b/unity/Assets/Scripts/QuestEditor/EditorComponentSpawn.cs index 60f9ac2cd..68870b488 100644 --- a/unity/Assets/Scripts/QuestEditor/EditorComponentSpawn.cs +++ b/unity/Assets/Scripts/QuestEditor/EditorComponentSpawn.cs @@ -264,7 +264,7 @@ override public float AddSubEventComponents(float offset) if (traitOffset > offset) offset = traitOffset; offset++; - if (game.gameType is D2EGameType || game.gameType is IAGameType) + if (game.gameType is D2EGameType) { offset = AddPlacementComponenets(offset); } diff --git a/unity/Assets/Scripts/QuestEditor/QuestEditorData.cs b/unity/Assets/Scripts/QuestEditor/QuestEditorData.cs index ba96b2f73..3674bd291 100644 --- a/unity/Assets/Scripts/QuestEditor/QuestEditorData.cs +++ b/unity/Assets/Scripts/QuestEditor/QuestEditorData.cs @@ -102,7 +102,7 @@ public static void TypeSelect(string type = "") select.AddNewComponentItem("CustomMonster"); select.AddNewComponentItem("UI"); select.AddNewComponentItem("QItem"); - if (game.gameType is D2EGameType || game.gameType is IAGameType) + if (game.gameType is D2EGameType) { select.AddNewComponentItem("Activation"); select.AddNewComponentItem("Door"); diff --git a/unity/Assets/Scripts/UI/Screens/EndGameScreen.cs b/unity/Assets/Scripts/UI/Screens/EndGameScreen.cs index baa8fc967..d1be231a6 100644 --- a/unity/Assets/Scripts/UI/Screens/EndGameScreen.cs +++ b/unity/Assets/Scripts/UI/Screens/EndGameScreen.cs @@ -56,10 +56,10 @@ public EndGameScreen() } else { - // TODO: support a background picture for IA GameStateManager.MainMenu(); return; } + bg.SetImage(bgTex); bg.SetLocation(0, 0, UIScaler.GetWidthUnits(), UIScaler.GetHeightUnits()); diff --git a/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs b/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs index 2ffdb650d..0e5f1e152 100644 --- a/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs +++ b/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs @@ -20,9 +20,7 @@ public class GameSelectionScreen { FFGImport fcD2E; FFGImport fcMoM; -#if IA - FFGImport fcIA; -#endif + protected string importType = ""; Thread importThread; @@ -46,11 +44,7 @@ public class GameSelectionScreen private static readonly string D2E_APP_URL_STEAM = "https://store.steampowered.com/app/477200/Descent_Road_to_Legend/"; -#if IA - private StringKey IA_NAME = new StringKey("val", "IA_NAME"); - private StringKey IA_APP_NOT_FOUND = new StringKey("val", "IA_APP_NOT_FOUND"); - private StringKey IA_APP_NOT_FOUND_ANDROID = new StringKey("val", "IA_APP_NOT_FOUND_ANDROID"); -#endif + // Create a menu which will take up the whole screen and have options. All items are dialog for destruction. public GameSelectionScreen() @@ -80,9 +74,7 @@ public void Draw() DrawMoMSection(offset); -#if IA - DrawIASection(); -#endif + DrawExitButton(); @@ -97,32 +89,24 @@ private void InitializeImporters() { fcD2E = new FFGImport(FFGAppImport.GameType.D2E, Platform.MacOS, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); fcMoM = new FFGImport(FFGAppImport.GameType.MoM, Platform.MacOS, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); -#if IA - fcIA = new FFGImport(FFGAppImport.GameType.IA, Platform.MacOS, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); -#endif + } else if (Application.platform == RuntimePlatform.Android) { fcD2E = new FFGImport(FFGAppImport.GameType.D2E, Platform.Android, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); fcMoM = new FFGImport(FFGAppImport.GameType.MoM, Platform.Android, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); -#if IA - fcIA = new FFGImport(FFGAppImport.GameType.IA, Platform.Android, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); -#endif + } else { fcD2E = new FFGImport(FFGAppImport.GameType.D2E, Platform.Windows, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); fcMoM = new FFGImport(FFGAppImport.GameType.MoM, Platform.Windows, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); -#if IA - fcIA = new FFGImport(FFGAppImport.GameType.IA, Platform.Windows, Game.AppData() + Path.DirectorySeparatorChar, Application.isEditor); -#endif + } fcD2E.Inspect(); fcMoM.Inspect(); -#if IA - fcIA.Inspect(); -#endif + } private void DrawBanner() @@ -351,60 +335,7 @@ private void DrawMoMSection(float offset) } } -#if IA - private void DrawIASection() - { - // Draw IA button - Color startColor = Color.white; - if (fcIA.NeedImport()) - { - startColor = Color.gray; - } - // Always disabled - startColor = Color.gray; - UIElement ui = new UIElement(); - ui.SetLocation((UIScaler.GetWidthUnits() - 30) / 2, 21, 30, 3); - ui.SetText(IA_NAME, startColor); - ui.SetFontSize(UIScaler.GetMediumFont()); - //ui.SetButton(delegate { IA(); }); - ui.SetBGColor(new Color(0, 0.03f, 0f)); - new UIElementBorder(ui, startColor); - // Draw IA import button - ui = new UIElement(); - if (fcIA.ImportAvailable()) - { - ui.SetLocation((UIScaler.GetWidthUnits() - 14) / 2, 24.2f, 14, 2); - StringKey keyText = StringKey.NULL; - if (Application.platform == RuntimePlatform.Android) - { - keyText = fcIA.NeedImport() ? CONTENT_IMPORT_ZIP : CONTENT_REIMPORT_ZIP; - } - else - { - keyText = fcIA.NeedImport() ? CONTENT_IMPORT_OFFICIAL : CONTENT_REIMPORT_OFFICIAL; - } - ui.SetText(keyText); - ui.SetFontSize(UIScaler.GetMediumFont()); - ui.SetButton(delegate { Import("IA"); }); - ui.SetBGColor(new Color(0, 0.03f, 0f)); - new UIElementBorder(ui); - } - else // Import unavailable - { - ui.SetLocation((UIScaler.GetWidthUnits() - 24) / 2, 24.2f, 24, 1); - if (Application.platform == RuntimePlatform.Android) - { - ui.SetText(IA_APP_NOT_FOUND_ANDROID, Color.red); - } - else - { - ui.SetText(IA_APP_NOT_FOUND, Color.red); - } - new UIElementBorder(ui, Color.red); - } - } -#endif private void DrawExitButton() { @@ -522,12 +453,7 @@ private void StartImport(string type, string path) { importThread = new Thread(new ThreadStart(delegate { fcMoM.Import(path); })); } -#if IA - if (type.Equals("IA")) - { - importThread = new Thread(new ThreadStart(delegate { fcIA.Import(path); })); - } -#endif + importThread.Start(); } @@ -584,19 +510,7 @@ public void ImportZipFromPath(string zipPath, string type) ZipManager.CopyDirectory(tempPath, destPath); } } -#if IA - if (type.Equals("IA")) - { - if (rawAssetsFound) fcIA.Import(tempPath); - else - { - ValkyrieDebug.Log("ZIP Import: Raw assets not found, performing direct copy."); - string destPath = fcIA.path; - if (Directory.Exists(destPath)) Directory.Delete(destPath, true); - ZipManager.CopyDirectory(tempPath, destPath); - } - } -#endif + })); importThread.Start(); } @@ -636,20 +550,7 @@ public void MoM() } } - // Start game as IA - public void IA() - { - // Not working yet -#if false - // Check if import neeeded - if (!fcIA.NeedImport()) - { - Game.Get().gameType = new IAGameType(); - loadLocalization(); - Destroyer.MainMenu(); - } -#endif - } + /// /// After selecting game, we load the localization file. diff --git a/unity/Assets/StreamingAssets/content/IA.meta b/unity/Assets/StreamingAssets/content/IA.meta deleted file mode 100644 index 873592389..000000000 --- a/unity/Assets/StreamingAssets/content/IA.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: cc905dafaaccbce41a1d25bdd82710e6 -folderAsset: yes -timeCreated: 1516958008 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/StreamingAssets/content/IA/CoreSet.meta b/unity/Assets/StreamingAssets/content/IA/CoreSet.meta deleted file mode 100644 index a0fed1f5d..000000000 --- a/unity/Assets/StreamingAssets/content/IA/CoreSet.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 40dc921c49756ee4d9a2af9e29ebd6bc -folderAsset: yes -timeCreated: 1516958008 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01.meta b/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01.meta deleted file mode 100644 index df9588084..000000000 --- a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 057ec457683633e46a4de993a343d15c -folderAsset: yes -timeCreated: 1516958008 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/Localization.English.txt b/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/Localization.English.txt deleted file mode 100644 index 99ad93ab8..000000000 --- a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/Localization.English.txt +++ /dev/null @@ -1,5 +0,0 @@ -,English -BIGEXPANSION,Large Boxed Expansions -SMALLEXPANSION,Small Boxed Expansions -ALLYPACK,Ally Pack -VILLAINPACK,Villain Pack diff --git a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/Localization.English.txt.meta b/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/Localization.English.txt.meta deleted file mode 100644 index 3099e5e78..000000000 --- a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/Localization.English.txt.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 06081918815781c4cb72848cea02020b -timeCreated: 1516958008 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tiles.ini b/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tiles.ini deleted file mode 100644 index 42d90f07b..000000000 --- a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tiles.ini +++ /dev/null @@ -1,8 +0,0 @@ -; Each tile side has a section -[TileSide1A] -name="?01A" -top=197 -left=79 -image="{import}/img/001A" -; traits= -reverse=TileSide1B diff --git a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tiles.ini.meta b/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tiles.ini.meta deleted file mode 100644 index 87e23ff0a..000000000 --- a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tiles.ini.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 753fc4c74f0b76f40b80494d4561f973 -timeCreated: 1516958008 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tokens.ini b/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tokens.ini deleted file mode 100644 index ab75ab87f..000000000 --- a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tokens.ini +++ /dev/null @@ -1,2 +0,0 @@ -[TokenSearch] -image="{import}/img/Search-Token" diff --git a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tokens.ini.meta b/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tokens.ini.meta deleted file mode 100644 index 8682ad4e1..000000000 --- a/unity/Assets/StreamingAssets/content/IA/CoreSet/SWI01/tokens.ini.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: cd93e743ade829946aebfe87b47ff40e -timeCreated: 1516958008 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/StreamingAssets/text/Localization.Chinese.txt b/unity/Assets/StreamingAssets/text/Localization.Chinese.txt index 51276245e..20c639e46 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Chinese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Chinese.txt @@ -75,12 +75,6 @@ HEALTH_HERO,Per Hero HIGHLIGHT,高光 HORROR_CHECK,恐懼判定 AWARENESS,Awareness -IA_APP_NOT_FOUND,Unable to locate Legends of the Alliance, install via Steam -IA_APP_NOT_FOUND_ANDROID,Unable to locate Legends of the Alliance -IA_HEROES_NAME,Heroes -IA_HERO_NAME,Hero -IA_NAME,Star Wars: Imperial Assault UNAVAILABLE -IA_QUEST_NAME,Mission INDENT, {0} INFO,資訊 INFORMATION,資訊 diff --git a/unity/Assets/StreamingAssets/text/Localization.Czech.txt b/unity/Assets/StreamingAssets/text/Localization.Czech.txt index e1ba9164b..1d79f21f4 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Czech.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Czech.txt @@ -110,12 +110,6 @@ HEALTH_HERO,za hrdinu HIGHLIGHT,Zvýraznit HORROR_CHECK,Kontrola hrůzy AWARENESS,Ostražitost -IA_APP_NOT_FOUND,Nelze nalézt Legends of the Alliance, Instalovat ze Steamu -IA_APP_NOT_FOUND_ANDROID,Nelze nalézt Legends of the Alliance, Instalovat z Google Play -IA_HEROES_NAME,Hrdinové -IA_HERO_NAME,Hrdina -IA_NAME,Star Wars: Imperial Assault UNAVAILABLE -IA_QUEST_NAME,Mise INDENT, {0} INFO,Info INFORMATION,Informace diff --git a/unity/Assets/StreamingAssets/text/Localization.English.txt b/unity/Assets/StreamingAssets/text/Localization.English.txt index 168ec0a86..3bfb6a00e 100644 --- a/unity/Assets/StreamingAssets/text/Localization.English.txt +++ b/unity/Assets/StreamingAssets/text/Localization.English.txt @@ -107,12 +107,6 @@ HEALTH_HERO,Per Hero HIGHLIGHT,Highlight HORROR_CHECK,Horror Check AWARENESS,Awareness -IA_APP_NOT_FOUND,Unable to locate Legends of the Alliance, install via Steam -IA_APP_NOT_FOUND_ANDROID,Unable to locate Legends of the Alliance -IA_HEROES_NAME,Heroes -IA_HERO_NAME,Hero -IA_NAME,Star Wars: Imperial Assault UNAVAILABLE -IA_QUEST_NAME,Mission INDENT, {0} INFO,Info INFORMATION,Information diff --git a/unity/Assets/StreamingAssets/text/Localization.French.txt b/unity/Assets/StreamingAssets/text/Localization.French.txt index f11c8c01f..7d0fbc903 100644 --- a/unity/Assets/StreamingAssets/text/Localization.French.txt +++ b/unity/Assets/StreamingAssets/text/Localization.French.txt @@ -80,12 +80,6 @@ HEALTH_HERO,Par Héros HIGHLIGHT,Mettre en valeur HORROR_CHECK,Test d'horreur AWARENESS,Conscience -IA_APP_NOT_FOUND,Veuillez installer Legends of the Alliance via Steam -IA_APP_NOT_FOUND_ANDROID,Veuillez installer Legends of the Alliance via Google Play -IA_HEROES_NAME,Heroes -IA_HERO_NAME,Hero -IA_NAME,Star Wars: Imperial Assault UNAVAILABLE -IA_QUEST_NAME,MissionINDENT, {0} INFO,Info INFORMATION,Information INITIAL_MESSAGE,Message de départ : diff --git a/unity/Assets/StreamingAssets/text/Localization.German.txt b/unity/Assets/StreamingAssets/text/Localization.German.txt index 88cd14961..b125bc79b 100644 --- a/unity/Assets/StreamingAssets/text/Localization.German.txt +++ b/unity/Assets/StreamingAssets/text/Localization.German.txt @@ -79,12 +79,6 @@ HEALTH_HERO,Pro Held HIGHLIGHT,Markieren HORROR_CHECK,Horrortest AWARENESS,Aufmerksamkeit -IA_APP_NOT_FOUND,"Imperial Assault" nicht gefunden, bitte über Steam installieren -IA_APP_NOT_FOUND_ANDROID,"Imperial Assault" nicht gefunden -IA_HEROES_NAME,Helden -IA_HERO_NAME,Held -IA_NAME,Star Wars: Imperial Assault -IA_QUEST_NAME,Mission INDENT, {0} INFO,Info INFORMATION,Information diff --git a/unity/Assets/StreamingAssets/text/Localization.Japanese.txt b/unity/Assets/StreamingAssets/text/Localization.Japanese.txt index a09629514..a4e65fe85 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Japanese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Japanese.txt @@ -173,12 +173,6 @@ HEALTH_HERO,Per Hero HIGHLIGHT,ハイライト HORROR_CHECK,恐怖判定 AWARENESS,知覚力 -IA_APP_NOT_FOUND,Unable to locate Legends of the Alliance, install via Steam -IA_APP_NOT_FOUND_ANDROID,Unable to locate Legends of the Alliance -IA_HEROES_NAME,Heroes -IA_HERO_NAME,Hero -IA_NAME,Star Wars: Imperial Assault UNAVAILABLE -IA_QUEST_NAME,Mission INDENT, {0} INFO,情報 INFORMATION,情報 diff --git a/unity/Assets/StreamingAssets/text/Localization.Korean.txt b/unity/Assets/StreamingAssets/text/Localization.Korean.txt index 1c90616a9..66d953002 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Korean.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Korean.txt @@ -108,12 +108,6 @@ HEALTH_HERO,조사자당 추가 체력 HIGHLIGHT,하이라이트 HORROR_CHECK,공포 체크 AWARENESS,인식 -IA_APP_NOT_FOUND,Unable to locate Legends of the Alliance, install via Steam -IA_APP_NOT_FOUND_ANDROID,Unable to locate Legends of the Alliance -IA_HEROES_NAME,영웅 -IA_HERO_NAME,영웅 -IA_NAME,스타 워즈 : 임페리얼 어썰트 없는 -IA_QUEST_NAME,미션 INDENT, {0} INFO,정보 INFORMATION,정보 diff --git a/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt b/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt index 92ec48764..df59b743c 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt @@ -86,12 +86,6 @@ HEALTH_HERO,Por Herói HIGHLIGHT,Destaque HORROR_CHECK,Teste de Horror AWARENESS,Consciência -IA_APP_NOT_FOUND,Não foi possível localizar Legends of the Alliance, instale via Steam -IA_APP_NOT_FOUND_ANDROID,Não foi possível localizar Legends of the Alliance -IA_HEROES_NAME,Heróis -IA_HERO_NAME,Heróis -IA_NAME,Star Wars: Imperial Assault UNAVAILABLE -IA_QUEST_NAME,Missão INDENT, {0} INFO,Info INFORMATION,Informação diff --git a/unity/Assets/StreamingAssets/text/Localization.Russian.txt b/unity/Assets/StreamingAssets/text/Localization.Russian.txt index 9d14ba14e..f07a3ad5d 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Russian.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Russian.txt @@ -79,12 +79,6 @@ HEALTH_HERO,За каждого игрока HIGHLIGHT,Отметка HORROR_CHECK,Проверка Ужаса AWARENESS,Бдительность -IA_APP_NOT_FOUND,Не найдено Legends of the Alliance, установите из Steam -IA_APP_NOT_FOUND_ANDROID,Не найдено Legends of the Alliance -IA_HEROES_NAME,Герои -IA_HERO_NAME,Герой -IA_NAME,Звездные войны: Имперский штурм НЕДОСТУПНО -IA_QUEST_NAME,Миссия INDENT, {0} INFO,Инфо INFORMATION,Информация diff --git a/unity/Assets/UnitTests/Editor/EventManagerTests.cs b/unity/Assets/UnitTests/Editor/EventManagerTests.cs index b43428d68..a8d583ee9 100644 --- a/unity/Assets/UnitTests/Editor/EventManagerTests.cs +++ b/unity/Assets/UnitTests/Editor/EventManagerTests.cs @@ -45,13 +45,7 @@ public void CHARS_MAP_ContainsMoMGameType() "CHARS_MAP should contain MoM game type"); } - [Test] - public void CHARS_MAP_ContainsIAGameType() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP.ContainsKey("IA"), - "CHARS_MAP should contain IA game type"); - } + [Test] public void CHARS_MAP_D2E_ContainsHeartSymbol() @@ -189,77 +183,7 @@ public void CHARS_MAP_MoM_ContainsClueSymbol() "MoM map should contain clue symbol"); } - [Test] - public void CHARS_MAP_IA_ContainsWoundSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{wound}"), - "IA map should contain wound symbol"); - } - - [Test] - public void CHARS_MAP_IA_ContainsSurgeSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{surge}"), - "IA map should contain surge symbol"); - } - - [Test] - public void CHARS_MAP_IA_ContainsAttackSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{attack}"), - "IA map should contain attack symbol"); - } - - [Test] - public void CHARS_MAP_IA_ContainsStrainSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{strain}"), - "IA map should contain strain symbol"); - } - - [Test] - public void CHARS_MAP_IA_ContainsTechSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{tech}"), - "IA map should contain tech symbol"); - } - - [Test] - public void CHARS_MAP_IA_ContainsInsightSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{insight}"), - "IA map should contain insight symbol"); - } - [Test] - public void CHARS_MAP_IA_ContainsBlockSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{block}"), - "IA map should contain block symbol"); - } - - [Test] - public void CHARS_MAP_IA_ContainsEvadeSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{evade}"), - "IA map should contain evade symbol"); - } - - [Test] - public void CHARS_MAP_IA_ContainsDodgeSymbol() - { - // Assert - Assert.IsTrue(EventManager.CHARS_MAP["IA"].ContainsKey("{dodge}"), - "IA map should contain dodge symbol"); - } #endregion @@ -281,13 +205,7 @@ public void CHAR_PACKS_MAP_ContainsMoMGameType() "CHAR_PACKS_MAP should contain MoM game type"); } - [Test] - public void CHAR_PACKS_MAP_ContainsIAGameType() - { - // Assert - Assert.IsTrue(EventManager.CHAR_PACKS_MAP.ContainsKey("IA"), - "CHAR_PACKS_MAP should contain IA game type"); - } + [Test] public void CHAR_PACKS_MAP_MoM_ContainsMAD01Symbol() @@ -305,13 +223,7 @@ public void CHAR_PACKS_MAP_MoM_ContainsMAD06Symbol() "MoM packs map should contain MAD06 symbol"); } - [Test] - public void CHAR_PACKS_MAP_IA_ContainsSWI01Symbol() - { - // Assert - Assert.IsTrue(EventManager.CHAR_PACKS_MAP["IA"].ContainsKey("{SWI01}"), - "IA packs map should contain SWI01 symbol"); - } + [Test] public void CHAR_PACKS_MAP_D2E_IsEmpty() diff --git a/unity/Assets/UnitTests/Editor/GameTypeTests.cs b/unity/Assets/UnitTests/Editor/GameTypeTests.cs index 45a1efd5b..ff3f0f044 100644 --- a/unity/Assets/UnitTests/Editor/GameTypeTests.cs +++ b/unity/Assets/UnitTests/Editor/GameTypeTests.cs @@ -8,7 +8,7 @@ namespace Valkyrie.UnitTests { /// /// Unit tests for GameType classes - Game-specific settings and configuration - /// Tests cover NoGameType, D2EGameType, MoMGameType, and IAGameType implementations + /// Tests cover NoGameType, D2EGameType, and MoMGameType implementations /// Note: Font-related methods are skipped as they require Unity Resources /// Note: MoMGameType is internal, so it is accessed via reflection /// @@ -622,235 +622,15 @@ public void MoMGameType_QuestName_ReturnsMoMQuestNameKey() #endregion - #region IAGameType Tests - [Test] - public void IAGameType_DataDirectory_ReturnsIAPath() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - string result = gameType.DataDirectory(); - - // Assert - Assert.IsNotNull(result); - Assert.IsTrue(result.EndsWith("IA/")); - Assert.AreEqual(ContentData.ContentPath() + "IA/", result); - } - - [Test] - public void IAGameType_HeroName_ReturnsIAHeroNameKey() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - StringKey result = gameType.HeroName(); - - // Assert - Assert.IsNotNull(result); - Assert.AreEqual("val", result.dict); - Assert.AreEqual("IA_HERO_NAME", result.key); - } - - [Test] - public void IAGameType_HeroesName_ReturnsIAHeroesNameKey() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - StringKey result = gameType.HeroesName(); - - // Assert - Assert.IsNotNull(result); - Assert.AreEqual("val", result.dict); - Assert.AreEqual("IA_HEROES_NAME", result.key); - } - - [Test] - public void IAGameType_MaxHeroes_ReturnsFour() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - int result = gameType.MaxHeroes(); - - // Assert - Assert.AreEqual(4, result); - } - - [Test] - public void IAGameType_DefaultHeroes_ReturnsFour() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - int result = gameType.DefaultHeroes(); - - // Assert - Assert.AreEqual(4, result); - } - - [Test] - public void IAGameType_TilePixelPerSquare_Returns105() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - float result = gameType.TilePixelPerSquare(); - - // Assert - Assert.AreEqual(105f, result); - } - - [Test] - public void IAGameType_TypeName_ReturnsIA() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - string result = gameType.TypeName(); - - // Assert - Assert.AreEqual("IA", result); - } - - [Test] - public void IAGameType_TileOnGrid_ReturnsTrue() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - bool result = gameType.TileOnGrid(); - - // Assert - Assert.IsTrue(result); - } - - [Test] - public void IAGameType_DisplayMorale_ReturnsTrue() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - bool result = gameType.DisplayMorale(); - - // Assert - Assert.IsTrue(result); - } - - [Test] - public void IAGameType_MonstersGrouped_ReturnsFalse() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - bool result = gameType.MonstersGrouped(); - - // Assert - Assert.IsFalse(result); - } - - [Test] - public void IAGameType_SelectionRound_ReturnsOne() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - float result = gameType.SelectionRound(); - - // Assert - Assert.AreEqual(1f, result); - } - - [Test] - public void IAGameType_TileRound_ReturnsOne() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - float result = gameType.TileRound(); - - // Assert - Assert.AreEqual(1f, result); - } - - [Test] - public void IAGameType_DisplayHeroes_ReturnsTrue() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - bool result = gameType.DisplayHeroes(); - - // Assert - Assert.IsTrue(result); - } - - [Test] - public void IAGameType_QuestName_ReturnsIAQuestNameKey() - { - // Arrange - IAGameType gameType = new IAGameType(); - - // Act - StringKey result = gameType.QuestName(); - - // Assert - Assert.IsNotNull(result); - Assert.AreEqual("val", result.dict); - Assert.AreEqual("IA_QUEST_NAME", result.key); - } - - #endregion #region Cross-GameType Comparison Tests - [Test] - public void GameTypes_D2EAndIA_HaveSameTilePixelPerSquare() - { - // Arrange - D2EGameType d2e = new D2EGameType(); - IAGameType ia = new IAGameType(); - // Act & Assert - Assert.AreEqual(d2e.TilePixelPerSquare(), ia.TilePixelPerSquare()); - } - [Test] - public void GameTypes_D2EAndIA_HaveSameMaxHeroes() - { - // Arrange - D2EGameType d2e = new D2EGameType(); - IAGameType ia = new IAGameType(); - // Act & Assert - Assert.AreEqual(d2e.MaxHeroes(), ia.MaxHeroes()); - Assert.AreEqual(4, d2e.MaxHeroes()); - } - [Test] - public void GameTypes_D2EAndIA_HaveSameDefaultHeroes() - { - // Arrange - D2EGameType d2e = new D2EGameType(); - IAGameType ia = new IAGameType(); - // Act & Assert - Assert.AreEqual(d2e.DefaultHeroes(), ia.DefaultHeroes()); - } [Test] public void GameTypes_MoM_HasHigherMaxHeroesThanOthers() @@ -858,11 +638,8 @@ public void GameTypes_MoM_HasHigherMaxHeroesThanOthers() // Arrange GameType mom = CreateMoMGameType(); D2EGameType d2e = new D2EGameType(); - IAGameType ia = new IAGameType(); - // Act & Assert Assert.IsTrue(mom.MaxHeroes() > d2e.MaxHeroes()); - Assert.IsTrue(mom.MaxHeroes() > ia.MaxHeroes()); } [Test] @@ -872,13 +649,10 @@ public void GameTypes_OnlyMoM_HasTileOnGridFalse() NoGameType no = new NoGameType(); D2EGameType d2e = new D2EGameType(); GameType mom = CreateMoMGameType(); - IAGameType ia = new IAGameType(); - // Act & Assert Assert.IsTrue(no.TileOnGrid()); Assert.IsTrue(d2e.TileOnGrid()); Assert.IsFalse(mom.TileOnGrid()); - Assert.IsTrue(ia.TileOnGrid()); } [Test] @@ -888,22 +662,18 @@ public void GameTypes_TypeNames_AreUnique() NoGameType no = new NoGameType(); D2EGameType d2e = new D2EGameType(); GameType mom = CreateMoMGameType(); - IAGameType ia = new IAGameType(); - // Act string[] typeNames = new string[] { no.TypeName(), d2e.TypeName(), - mom.TypeName(), - ia.TypeName() + mom.TypeName() }; // Assert - all should be unique (NoGameType returns empty string) Assert.AreEqual("", typeNames[0]); Assert.AreEqual("D2E", typeNames[1]); Assert.AreEqual("MoM", typeNames[2]); - Assert.AreEqual("IA", typeNames[3]); } [Test] @@ -912,12 +682,9 @@ public void GameTypes_DataDirectories_ContainTypeName() // Arrange D2EGameType d2e = new D2EGameType(); GameType mom = CreateMoMGameType(); - IAGameType ia = new IAGameType(); - // Act & Assert Assert.IsTrue(d2e.DataDirectory().Contains(d2e.TypeName())); Assert.IsTrue(mom.DataDirectory().Contains(mom.TypeName())); - Assert.IsTrue(ia.DataDirectory().Contains(ia.TypeName())); } #endregion From 2c4dfb1e1edfc7d047e92d1b2ce43599b44b36ed Mon Sep 17 00:00:00 2001 From: Quantumrunner <58113888+Quantumrunner@users.noreply.github.com> Date: Sat, 17 Jan 2026 14:57:21 +0100 Subject: [PATCH 2/6] Added button in main menu to go back GameType selection. --- .../Scripts/UI/Screens/GameSelectionScreen.cs | 9 ++++-- .../Scripts/UI/Screens/MainMenuScreen.cs | 29 ++++++++++++++++++- .../text/Localization.Chinese.txt | 1 + .../text/Localization.Czech.txt | 1 + .../text/Localization.English.txt | 1 + .../text/Localization.French.txt | 1 + .../text/Localization.German.txt | 1 + .../text/Localization.Italian.txt | 1 + .../text/Localization.Japanese.txt | 1 + .../text/Localization.Korean.txt | 1 + .../text/Localization.Polish.txt | 1 + .../text/Localization.Portuguese.txt | 1 + .../text/Localization.Russian.txt | 1 + .../text/Localization.Spanish.txt | 1 + 14 files changed, 46 insertions(+), 4 deletions(-) diff --git a/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs b/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs index 2ffdb650d..a17017873 100644 --- a/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs +++ b/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs @@ -18,10 +18,10 @@ namespace Assets.Scripts.UI.Screens // and import controls public class GameSelectionScreen { - FFGImport fcD2E; - FFGImport fcMoM; + static FFGImport fcD2E; + static FFGImport fcMoM; #if IA - FFGImport fcIA; + static FFGImport fcIA; #endif protected string importType = ""; Thread importThread; @@ -92,6 +92,9 @@ public void Draw() private void InitializeImporters() { + // Check if we have already initialized + if (fcD2E != null && fcMoM != null) return; + // Get the current content for games if (Application.platform == RuntimePlatform.OSXPlayer) { diff --git a/unity/Assets/Scripts/UI/Screens/MainMenuScreen.cs b/unity/Assets/Scripts/UI/Screens/MainMenuScreen.cs index 69b753a30..046b54bdb 100644 --- a/unity/Assets/Scripts/UI/Screens/MainMenuScreen.cs +++ b/unity/Assets/Scripts/UI/Screens/MainMenuScreen.cs @@ -11,6 +11,7 @@ namespace Assets.Scripts.UI.Screens public class MainMenuScreen { private static readonly StringKey SELECT_CONTENT = new StringKey("val", "SELECT_CONTENT"); + private static readonly StringKey SELECT_GAME_TYPE = new StringKey("val", "SELECT_GAME_TYPE"); private static readonly StringKey ABOUT = new StringKey("val", "ABOUT"); private static readonly StringKey OPTIONS = new StringKey("val", "OPTIONS"); private static readonly StringKey ABOUT_FFG = new StringKey("val", "ABOUT_FFG"); @@ -134,9 +135,26 @@ public MainMenuScreen() ui.SetBGColor(BUTTON_BG_COLOR); new UIElementBorder(ui, BUTTON_BORDER_COLOR_ACTIVE); - // Exit Valkyrie + // Select Game Type ui = new UIElement(); ui.SetLocation(menuButtonsX, 23, ButtonWidth, 2); + ui.SetText(SELECT_GAME_TYPE); + ui.SetFont(game.gameType.GetHeaderFont()); + if (SELECT_GAME_TYPE.Translate().Length > 20) + { + ui.SetFontSize(UIScaler.GetSmallFont()); + } + else + { + ui.SetFontSize(UIScaler.GetMediumFont()); + } + ui.SetButton(GameSelection); + ui.SetBGColor(BUTTON_BG_COLOR); + new UIElementBorder(ui, BUTTON_BORDER_COLOR_ACTIVE); + + // Exit Valkyrie + ui = new UIElement(); + ui.SetLocation(menuButtonsX, 26, ButtonWidth, 2); ui.SetText(CommonStringKeys.EXIT); ui.SetFont(game.gameType.GetHeaderFont()); ui.SetFontSize(UIScaler.GetMediumFont()); @@ -179,6 +197,15 @@ private void Config() new OptionsScreen(); } + public void GameSelection() + { + ValkyrieDebug.Log("INFO: Return to game selection"); + // Clean up everything + Destroyer.Destroy(); + Game.Get().gameType = new NoGameType(); + new GameSelectionScreen(); + } + static int click_counter = 0; static public void TestCrash() diff --git a/unity/Assets/StreamingAssets/text/Localization.Chinese.txt b/unity/Assets/StreamingAssets/text/Localization.Chinese.txt index 51276245e..73d2438b0 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Chinese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Chinese.txt @@ -496,3 +496,4 @@ CLICK_BEHAVIOR,点击行为 CLICK_BLINK,闪烁 / 触发事件 CLICK_STATIC,静态 / 无事件 REQUIRED,必须 +SELECT_GAME_TYPE,选择游戏类型 diff --git a/unity/Assets/StreamingAssets/text/Localization.Czech.txt b/unity/Assets/StreamingAssets/text/Localization.Czech.txt index e1ba9164b..ce77e5d88 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Czech.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Czech.txt @@ -691,3 +691,4 @@ CLICK_BEHAVIOR,Chování při kliknutí CLICK_BLINK,Blikání / spustit událost CLICK_STATIC,Statické / Žádná událost REQUIRED,Vyžadováno +SELECT_GAME_TYPE,Vybrat typ hry diff --git a/unity/Assets/StreamingAssets/text/Localization.English.txt b/unity/Assets/StreamingAssets/text/Localization.English.txt index 168ec0a86..4411ba107 100644 --- a/unity/Assets/StreamingAssets/text/Localization.English.txt +++ b/unity/Assets/StreamingAssets/text/Localization.English.txt @@ -688,3 +688,4 @@ CLICK_BEHAVIOR,Click Behavior CLICK_BLINK,Blink / Trigger event CLICK_STATIC,Static / No event REQUIRED,Required +SELECT_GAME_TYPE,Select Game Type diff --git a/unity/Assets/StreamingAssets/text/Localization.French.txt b/unity/Assets/StreamingAssets/text/Localization.French.txt index f11c8c01f..97fe623ab 100644 --- a/unity/Assets/StreamingAssets/text/Localization.French.txt +++ b/unity/Assets/StreamingAssets/text/Localization.French.txt @@ -519,3 +519,4 @@ CLICK_BEHAVIOR,Comportement au clic CLICK_BLINK,Clignoter / Déclencher événement CLICK_STATIC,Statique / Pas d'événement REQUIRED,Requis +SELECT_GAME_TYPE,Sélectionner le type de jeu diff --git a/unity/Assets/StreamingAssets/text/Localization.German.txt b/unity/Assets/StreamingAssets/text/Localization.German.txt index 88cd14961..34e4a6316 100644 --- a/unity/Assets/StreamingAssets/text/Localization.German.txt +++ b/unity/Assets/StreamingAssets/text/Localization.German.txt @@ -515,3 +515,4 @@ CLICK_BEHAVIOR,Klickverhalten CLICK_BLINK,Blinken / Ereignis auslösen CLICK_STATIC,Statisch / Kein Ereignis REQUIRED,Erforderlich +SELECT_GAME_TYPE,Spieltyp auswählen diff --git a/unity/Assets/StreamingAssets/text/Localization.Italian.txt b/unity/Assets/StreamingAssets/text/Localization.Italian.txt index cb854edbf..5b2157095 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Italian.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Italian.txt @@ -455,3 +455,4 @@ CLICK_BEHAVIOR,Comportamento clic CLICK_BLINK,Lampeggia / Attiva evento CLICK_STATIC,Statico / Nessun evento REQUIRED,Richiesto +SELECT_GAME_TYPE,Seleziona tipo di gioco diff --git a/unity/Assets/StreamingAssets/text/Localization.Japanese.txt b/unity/Assets/StreamingAssets/text/Localization.Japanese.txt index a09629514..676c389cd 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Japanese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Japanese.txt @@ -718,3 +718,4 @@ CLICK_BEHAVIOR,クリック動作 CLICK_BLINK,点滅 / イベントトリガー CLICK_STATIC,静的 / イベントなし REQUIRED,必須 +SELECT_GAME_TYPE,ゲームタイプを選択 diff --git a/unity/Assets/StreamingAssets/text/Localization.Korean.txt b/unity/Assets/StreamingAssets/text/Localization.Korean.txt index 1c90616a9..b3a4b7c67 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Korean.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Korean.txt @@ -684,3 +684,4 @@ CLICK_BEHAVIOR,클릭 동작 CLICK_BLINK,깜박임 / 이벤트 트리거 CLICK_STATIC,정적 / 이벤트 없음 REQUIRED,필수 +SELECT_GAME_TYPE,게임 유형 선택 diff --git a/unity/Assets/StreamingAssets/text/Localization.Polish.txt b/unity/Assets/StreamingAssets/text/Localization.Polish.txt index 12bd28118..d76f48d88 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Polish.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Polish.txt @@ -489,3 +489,4 @@ FADE_SLOW,Wolno CLICK_BEHAVIOR,Zachowanie kliknięcia CLICK_BLINK,Miganie / wyzwalanie zdarzenia CLICK_STATIC,Statyczne / Brak zdarzeniaREQUIRED,Wymagane +SELECT_GAME_TYPE,Wybierz typ gry diff --git a/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt b/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt index 92ec48764..9cb6433b9 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt @@ -522,3 +522,4 @@ FADE_SLOW,Lento CLICK_BEHAVIOR,Comportamento do Clique CLICK_BLINK,Piscar / disparar evento CLICK_STATIC,Estático / Sem eventoREQUIRED,Obrigatório +SELECT_GAME_TYPE,Selecionar tipo de jogo diff --git a/unity/Assets/StreamingAssets/text/Localization.Russian.txt b/unity/Assets/StreamingAssets/text/Localization.Russian.txt index 9d14ba14e..ead93834f 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Russian.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Russian.txt @@ -518,3 +518,4 @@ CLICK_BEHAVIOR,Поведение клика CLICK_BLINK,Мигание / событие CLICK_STATIC,Статично / Нет события REQUIRED,Требуется +SELECT_GAME_TYPE,Выбрать тип игры diff --git a/unity/Assets/StreamingAssets/text/Localization.Spanish.txt b/unity/Assets/StreamingAssets/text/Localization.Spanish.txt index 025e52e23..b6dfa7a68 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Spanish.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Spanish.txt @@ -515,3 +515,4 @@ CLICK_BEHAVIOR,Comportamiento al hacer clic CLICK_BLINK,Parpadear / Activar evento CLICK_STATIC,Estático / Sin evento REQUIRED,Requerido +SELECT_GAME_TYPE,Seleccionar tipo de juego From f7f1a699ead5908267fea8f6e6cce656440b5d64 Mon Sep 17 00:00:00 2001 From: Quantumrunner <58113888+Quantumrunner@users.noreply.github.com> Date: Sat, 17 Jan 2026 19:07:44 +0100 Subject: [PATCH 3/6] Fixed errors in 3.12 in QuestSelectionScreen. --- .agent/rules/testing.md | 2 +- .agent/rules/text-localization.md | 2 +- .../Assets/Scripts/Content/DictionaryI18n.cs | 16 +++- .../UI/Screens/QuestSelectionScreen.cs | 32 +++++--- .../text/Localization.Chinese.txt | 1 + .../text/Localization.Czech.txt | 1 + .../text/Localization.English.txt | 1 + .../text/Localization.French.txt | 1 + .../text/Localization.German.txt | 1 + .../text/Localization.Italian.txt | 1 + .../text/Localization.Japanese.txt | 1 + .../text/Localization.Korean.txt | 1 + .../text/Localization.Polish.txt | 1 + .../text/Localization.Portuguese.txt | 1 + .../text/Localization.Russian.txt | 1 + .../text/Localization.Spanish.txt | 1 + .../UnitTests/Editor/LocalizationReadTests.cs | 79 +++++++++++++++++++ 17 files changed, 125 insertions(+), 18 deletions(-) diff --git a/.agent/rules/testing.md b/.agent/rules/testing.md index edcc70e6e..c52ca5760 100644 --- a/.agent/rules/testing.md +++ b/.agent/rules/testing.md @@ -2,7 +2,7 @@ trigger: always_on --- -- Generate unit tests for each file and each method +- Always generate unit tests for each file and each method - Exception: UI related classes in `valkyrie\unity\Assets\Scripts\UI` - Unit Tests should always be located in `valkyrie\unity\Assets\UnitTests` - When new tests have been created/existing tests have been updated ask if Unit tests should be ran. Do not run Unit Tests without confirmation from the user. diff --git a/.agent/rules/text-localization.md b/.agent/rules/text-localization.md index 6fa12267f..3bcb5e9f0 100644 --- a/.agent/rules/text-localization.md +++ b/.agent/rules/text-localization.md @@ -9,7 +9,7 @@ UI text should always get localized. Localization files are located in `Assets/S - The format is `KEY,Value`. - When adding new text: 1. Add the `KEY,English Value` to `Localization.English.txt`. -2. **CRITICAL**: Add a translated version `KEY,Translated Value` to *all* other relevant files (`Localization.German.txt`, `Localization.French.txt`, `Localization.Spanish.txt`, `Localization.Italian.txt`, etc.) where the value is translated to the language specified in the filename **IMMEDIATELY**. Do not defer this task. Failing to do so will result in missing text for users of those languages. +2. **CRITICAL**: Add a translated version `KEY,Translated Value` to *all* other relevant files (`Localization.German.txt`, `Localization.French.txt`, `Localization.Spanish.txt`, `Localization.Italian.txt`, etc.) where the value is translated to the language specified in the filename **IMMEDIATELY**. You must not just copy the English text; you must provide a translation. Do not defer this task. Failing to do so will result in missing text for users of those languages. 3. In C# code, use `new StringKey("val", "KEY")` to reference the text. 4. For commonly used keys, add a static reference in `Assets/Scripts/Content/CommonStringKeys.cs`. 5. **VERIFICATION**: Before finishing the task, use find_by_name or list_dir to list all Localization.*.txt files. Confirm that the new key has been added and translated to the respective file language to EACH file. Do not assume; verify. \ No newline at end of file diff --git a/unity/Assets/Scripts/Content/DictionaryI18n.cs b/unity/Assets/Scripts/Content/DictionaryI18n.cs index 2c507b8d0..691544c9a 100644 --- a/unity/Assets/Scripts/Content/DictionaryI18n.cs +++ b/unity/Assets/Scripts/Content/DictionaryI18n.cs @@ -63,7 +63,7 @@ public DictionaryI18n() { data = new Dictionary>(); rawData = new Dictionary>(); - currentLanguage = Game.Get().currentLang; + InitCurrentLanguage(); } /// @@ -74,7 +74,7 @@ public DictionaryI18n(string newDefaultLanguage) { data = new Dictionary>(); rawData = new Dictionary>(); - currentLanguage = Game.Get().currentLang; + InitCurrentLanguage(); } /// @@ -84,7 +84,7 @@ public DictionaryI18n(string[] languageData) { data = new Dictionary>(); rawData = new Dictionary>(); - currentLanguage = Game.Get().currentLang; + InitCurrentLanguage(); AddData(languageData); } @@ -98,10 +98,18 @@ public DictionaryI18n(string[] languageData, string newDefaultLanguage) data = new Dictionary>(); rawData = new Dictionary>(); defaultLanguage = newDefaultLanguage; - currentLanguage = Game.Get().currentLang; + InitCurrentLanguage(); AddData(languageData); } + private void InitCurrentLanguage() + { + if (Game.Get() != null) + currentLanguage = Game.Get().currentLang; + else + currentLanguage = "English"; + } + /// /// Add language data to dictionary from file path. /// diff --git a/unity/Assets/Scripts/UI/Screens/QuestSelectionScreen.cs b/unity/Assets/Scripts/UI/Screens/QuestSelectionScreen.cs index 6cbc02789..bc7fbb3b1 100644 --- a/unity/Assets/Scripts/UI/Screens/QuestSelectionScreen.cs +++ b/unity/Assets/Scripts/UI/Screens/QuestSelectionScreen.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.IO; @@ -1016,12 +1016,13 @@ private IEnumerator DrawListItems() if (nb_filtered_out_quest > 0) { - StringKey FILTER_TEXT_TOTAL_AND_FILTERED = new StringKey(new StringKey("val", "FILTER_TEXT_TOTAL_AND_FILTERED"), "{0}:" + (total_scenarios - nb_filtered_out_quest - nb_invalid_quest), "{1}:" + nb_filtered_out_quest); - text_number_of_filtered_scenario.SetText(FILTER_TEXT_TOTAL_AND_FILTERED); + StringKey filterText = new StringKey(new StringKey("val", "FILTER_TEXT_TOTAL_AND_FILTERED"), "{0}:" + (total_scenarios - nb_filtered_out_quest - nb_invalid_quest), "{1}:" + nb_filtered_out_quest); + text_number_of_filtered_scenario.SetText(filterText.Translate()); } else { - text_number_of_filtered_scenario.SetText(" "); + StringKey filterText = new StringKey("val", "FILTER_TEXT_TOTAL_ONLY", total_scenarios - nb_filtered_out_quest - nb_invalid_quest); + text_number_of_filtered_scenario.SetText(filterText.Translate()); } } catch (Exception e) @@ -1038,14 +1039,15 @@ private IEnumerator DrawListItems() // Do it one last time in case the latest scenario has been filtered or if there are no scenario in the list if (nb_filtered_out_quest > 0) - { - StringKey FILTER_TEXT_TOTAL_AND_FILTERED = new StringKey(new StringKey("val", "FILTER_TEXT_TOTAL_AND_FILTERED"), "{0}:" + (total_scenarios - nb_filtered_out_quest - nb_invalid_quest), "{1}:" + nb_filtered_out_quest); - text_number_of_filtered_scenario.SetText(FILTER_TEXT_TOTAL_AND_FILTERED); - } - else - { - text_number_of_filtered_scenario.SetText(" "); - } + { + StringKey filterText = new StringKey(new StringKey("val", "FILTER_TEXT_TOTAL_AND_FILTERED"), "{0}:" + (total_scenarios - nb_filtered_out_quest - nb_invalid_quest), "{1}:" + nb_filtered_out_quest); + text_number_of_filtered_scenario.SetText(filterText.Translate()); + } + else + { + StringKey filterText = new StringKey("val", "FILTER_TEXT_TOTAL_ONLY", total_scenarios - nb_filtered_out_quest - nb_invalid_quest); + text_number_of_filtered_scenario.SetText(filterText.Translate()); + } images_list.StartDownloadASync(scrollArea); } @@ -1525,6 +1527,9 @@ public void Selection(string key) // Play Destroyer.Dialog(); CleanQuestList(); + // Clean up quest UI (header, filters, etc) + foreach (GameObject go in GameObject.FindGameObjectsWithTag(Game.QUESTUI)) + Destroy(go); ValkyrieDebug.Log("INFO: ... and launch offline quest"); new QuestDetailsScreen(q); } @@ -1533,6 +1538,9 @@ public void Selection(string key) // Play Destroyer.Dialog(); CleanQuestList(); + // Clean up quest UI (header, filters, etc) + foreach (GameObject go in GameObject.FindGameObjectsWithTag(Game.QUESTUI)) + Destroy(go); ValkyrieDebug.Log("INFO: ... and launch online quest"); new QuestDetailsScreen(QuestLoader.GetSingleQuest(key)); } diff --git a/unity/Assets/StreamingAssets/text/Localization.Chinese.txt b/unity/Assets/StreamingAssets/text/Localization.Chinese.txt index 51276245e..908f27316 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Chinese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Chinese.txt @@ -496,3 +496,4 @@ CLICK_BEHAVIOR,点击行为 CLICK_BLINK,闪烁 / 触发事件 CLICK_STATIC,静态 / 无事件 REQUIRED,必须 +FILTER_TEXT_TOTAL_ONLY,{0} 场景 diff --git a/unity/Assets/StreamingAssets/text/Localization.Czech.txt b/unity/Assets/StreamingAssets/text/Localization.Czech.txt index e1ba9164b..034b8ab09 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Czech.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Czech.txt @@ -691,3 +691,4 @@ CLICK_BEHAVIOR,Chování při kliknutí CLICK_BLINK,Blikání / spustit událost CLICK_STATIC,Statické / Žádná událost REQUIRED,Vyžadováno +FILTER_TEXT_TOTAL_ONLY,{0} scenářů diff --git a/unity/Assets/StreamingAssets/text/Localization.English.txt b/unity/Assets/StreamingAssets/text/Localization.English.txt index 168ec0a86..e55f673ed 100644 --- a/unity/Assets/StreamingAssets/text/Localization.English.txt +++ b/unity/Assets/StreamingAssets/text/Localization.English.txt @@ -688,3 +688,4 @@ CLICK_BEHAVIOR,Click Behavior CLICK_BLINK,Blink / Trigger event CLICK_STATIC,Static / No event REQUIRED,Required +FILTER_TEXT_TOTAL_ONLY,{0} scenarios diff --git a/unity/Assets/StreamingAssets/text/Localization.French.txt b/unity/Assets/StreamingAssets/text/Localization.French.txt index f11c8c01f..5d5ff17dd 100644 --- a/unity/Assets/StreamingAssets/text/Localization.French.txt +++ b/unity/Assets/StreamingAssets/text/Localization.French.txt @@ -519,3 +519,4 @@ CLICK_BEHAVIOR,Comportement au clic CLICK_BLINK,Clignoter / Déclencher événement CLICK_STATIC,Statique / Pas d'événement REQUIRED,Requis +FILTER_TEXT_TOTAL_ONLY,{0} scénarios diff --git a/unity/Assets/StreamingAssets/text/Localization.German.txt b/unity/Assets/StreamingAssets/text/Localization.German.txt index 88cd14961..f539a2f5f 100644 --- a/unity/Assets/StreamingAssets/text/Localization.German.txt +++ b/unity/Assets/StreamingAssets/text/Localization.German.txt @@ -515,3 +515,4 @@ CLICK_BEHAVIOR,Klickverhalten CLICK_BLINK,Blinken / Ereignis auslösen CLICK_STATIC,Statisch / Kein Ereignis REQUIRED,Erforderlich +FILTER_TEXT_TOTAL_ONLY,{0} Szenarien diff --git a/unity/Assets/StreamingAssets/text/Localization.Italian.txt b/unity/Assets/StreamingAssets/text/Localization.Italian.txt index cb854edbf..ec7edac37 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Italian.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Italian.txt @@ -455,3 +455,4 @@ CLICK_BEHAVIOR,Comportamento clic CLICK_BLINK,Lampeggia / Attiva evento CLICK_STATIC,Statico / Nessun evento REQUIRED,Richiesto +FILTER_TEXT_TOTAL_ONLY,{0} scenari diff --git a/unity/Assets/StreamingAssets/text/Localization.Japanese.txt b/unity/Assets/StreamingAssets/text/Localization.Japanese.txt index a09629514..9a3ef24b6 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Japanese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Japanese.txt @@ -718,3 +718,4 @@ CLICK_BEHAVIOR,クリック動作 CLICK_BLINK,点滅 / イベントトリガー CLICK_STATIC,静的 / イベントなし REQUIRED,必須 +FILTER_TEXT_TOTAL_ONLY,{0} シナリオ diff --git a/unity/Assets/StreamingAssets/text/Localization.Korean.txt b/unity/Assets/StreamingAssets/text/Localization.Korean.txt index 1c90616a9..1ba3c63d4 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Korean.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Korean.txt @@ -684,3 +684,4 @@ CLICK_BEHAVIOR,클릭 동작 CLICK_BLINK,깜박임 / 이벤트 트리거 CLICK_STATIC,정적 / 이벤트 없음 REQUIRED,필수 +FILTER_TEXT_TOTAL_ONLY,{0} 시나리오 diff --git a/unity/Assets/StreamingAssets/text/Localization.Polish.txt b/unity/Assets/StreamingAssets/text/Localization.Polish.txt index 12bd28118..56f8cb751 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Polish.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Polish.txt @@ -489,3 +489,4 @@ FADE_SLOW,Wolno CLICK_BEHAVIOR,Zachowanie kliknięcia CLICK_BLINK,Miganie / wyzwalanie zdarzenia CLICK_STATIC,Statyczne / Brak zdarzeniaREQUIRED,Wymagane +FILTER_TEXT_TOTAL_ONLY,{0} scenariuszy diff --git a/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt b/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt index 92ec48764..cdf40d08a 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Portuguese.txt @@ -522,3 +522,4 @@ FADE_SLOW,Lento CLICK_BEHAVIOR,Comportamento do Clique CLICK_BLINK,Piscar / disparar evento CLICK_STATIC,Estático / Sem eventoREQUIRED,Obrigatório +FILTER_TEXT_TOTAL_ONLY,{0} cenários diff --git a/unity/Assets/StreamingAssets/text/Localization.Russian.txt b/unity/Assets/StreamingAssets/text/Localization.Russian.txt index 9d14ba14e..a686cdd8d 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Russian.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Russian.txt @@ -518,3 +518,4 @@ CLICK_BEHAVIOR,Поведение клика CLICK_BLINK,Мигание / событие CLICK_STATIC,Статично / Нет события REQUIRED,Требуется +FILTER_TEXT_TOTAL_ONLY,{0} сценариев diff --git a/unity/Assets/StreamingAssets/text/Localization.Spanish.txt b/unity/Assets/StreamingAssets/text/Localization.Spanish.txt index 025e52e23..8e19f6465 100644 --- a/unity/Assets/StreamingAssets/text/Localization.Spanish.txt +++ b/unity/Assets/StreamingAssets/text/Localization.Spanish.txt @@ -515,3 +515,4 @@ CLICK_BEHAVIOR,Comportamiento al hacer clic CLICK_BLINK,Parpadear / Activar evento CLICK_STATIC,Estático / Sin evento REQUIRED,Requerido +FILTER_TEXT_TOTAL_ONLY,{0} escenarios diff --git a/unity/Assets/UnitTests/Editor/LocalizationReadTests.cs b/unity/Assets/UnitTests/Editor/LocalizationReadTests.cs index f21701f5c..1448ac966 100644 --- a/unity/Assets/UnitTests/Editor/LocalizationReadTests.cs +++ b/unity/Assets/UnitTests/Editor/LocalizationReadTests.cs @@ -763,5 +763,84 @@ public void ParameterReplacement_NoMatchingPlaceholder_NoChange() } #endregion + + #region DictLookup and StringKey Tests + + [Test] + public void DictLookup_NumericParameter_ReplacesCorrectly() + { + // Arrange + DictionaryI18n dict = new DictionaryI18n(); + dict.AddEntry("KEY", "Value: {0}", "English"); + LocalizationRead.dicts.Add("val", dict); + + // Act + // This mirrors the fix: passing int directly to StringKey constructor + StringKey sk = new StringKey("val", "KEY", 5); + string result = LocalizationRead.DictLookup(sk); + + // Assert + Assert.AreEqual("Value: 5", result); + } + + [Test] + public void DictLookup_StringParameter_ReplacedCorrectly() + { + // Arrange + DictionaryI18n dict = new DictionaryI18n(); + dict.AddEntry("KEY_S", "Hello {0}", "English"); + LocalizationRead.dicts.Add("val", dict); + + // Act + StringKey sk = new StringKey("val", "KEY_S", "World"); + string result = LocalizationRead.DictLookup(sk); + + // Assert + Assert.AreEqual("Hello World", result); + } + + + [Test] + public void DictLookup_MultipleParameters_ReplacedCorrectly() + { + // Arrange + DictionaryI18n dict = new DictionaryI18n(); + dict.AddEntry("KEY_M", "{0} met {1}", "English"); + LocalizationRead.dicts.Add("val", dict); + + // Act + // To replace multiple parameters, we need to ensure the parameters string contains brackets {} + // so DictQuery enters the parsing mode. + // We construct parameters manually: "{0}:Alice:{1}:Bob", passing "Alice:{1}:Bob" + // because the constructor prepends "{0}:" + StringKey sk = new StringKey("val", "KEY_M", "Alice:{1}:Bob"); + + string result = LocalizationRead.DictLookup(sk); + + // Assert + Assert.AreEqual("Alice met Bob", result); + } + + [Test] + public void DictLookup_IncorrectParameterFormat_FailsToReplace() + { + // Arrange + DictionaryI18n dict = new DictionaryI18n(); + dict.AddEntry("KEY_ERR", "Count: {0}", "English"); + LocalizationRead.dicts.Add("val", dict); + + // Act + // This mirrors the bug: manually adding "{0}:" to the value parameter + // The StringKey constructor adds "{0}:", so we get "{0}:{0}:5" in the parameters string + // DictQuery parses elements: KEY_ERR, {0}, {0}, 5 + // It replaces "{0}" with "{0}", leaving the string unchanged. + StringKey sk = new StringKey("val", "KEY_ERR", "{0}:" + 5); + string result = LocalizationRead.DictLookup(sk); + + // Assert + Assert.AreEqual("Count: {0}", result); + } + + #endregion } } From d38ce67d70f4425a737449820b35401b87c2bf1d Mon Sep 17 00:00:00 2001 From: Quantumrunner <58113888+Quantumrunner@users.noreply.github.com> Date: Sat, 17 Jan 2026 19:20:48 +0100 Subject: [PATCH 4/6] Fixed issue which caused Change game mode logic to load too long. --- unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs b/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs index 3b437d5b3..63ead3ca1 100644 --- a/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs +++ b/unity/Assets/Scripts/UI/Screens/GameSelectionScreen.cs @@ -18,8 +18,8 @@ namespace Assets.Scripts.UI.Screens // and import controls public class GameSelectionScreen { - FFGImport fcD2E; - FFGImport fcMoM; + static FFGImport fcD2E; + static FFGImport fcMoM; protected string importType = ""; Thread importThread; From 9b4d8419a367057fd1d14161bb9f6bd4ba721afa Mon Sep 17 00:00:00 2001 From: Quantumrunner <58113888+Quantumrunner@users.noreply.github.com> Date: Sat, 17 Jan 2026 19:24:35 +0100 Subject: [PATCH 5/6] Changed version to 3.13 --- unity/Assets/Resources/prod_version.txt | 2 +- unity/Assets/Resources/version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unity/Assets/Resources/prod_version.txt b/unity/Assets/Resources/prod_version.txt index fdcfcfdfc..3a4f41ef3 100644 --- a/unity/Assets/Resources/prod_version.txt +++ b/unity/Assets/Resources/prod_version.txt @@ -1 +1 @@ -3.12 \ No newline at end of file +3.13 \ No newline at end of file diff --git a/unity/Assets/Resources/version.txt b/unity/Assets/Resources/version.txt index fdcfcfdfc..3a4f41ef3 100644 --- a/unity/Assets/Resources/version.txt +++ b/unity/Assets/Resources/version.txt @@ -1 +1 @@ -3.12 \ No newline at end of file +3.13 \ No newline at end of file From c97e229c4ca29b4cb00b18a76e9857560923d1d6 Mon Sep 17 00:00:00 2001 From: Quantumrunner <58113888+Quantumrunner@users.noreply.github.com> Date: Sat, 17 Jan 2026 19:52:19 +0100 Subject: [PATCH 6/6] Removed obsolete class file link to prevent build issues. --- libraries/FFGAppImport/FFGAppImport.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/FFGAppImport/FFGAppImport.csproj b/libraries/FFGAppImport/FFGAppImport.csproj index 22e690d62..95eec6099 100644 --- a/libraries/FFGAppImport/FFGAppImport.csproj +++ b/libraries/FFGAppImport/FFGAppImport.csproj @@ -68,7 +68,7 @@ - +