diff --git a/CustomSpawns/CampaignData/Config/CampaignDataConfigLoader.cs b/CustomSpawns/CampaignData/Config/CampaignDataConfigLoader.cs index 29cdc8a..b253820 100644 --- a/CustomSpawns/CampaignData/Config/CampaignDataConfigLoader.cs +++ b/CustomSpawns/CampaignData/Config/CampaignDataConfigLoader.cs @@ -7,6 +7,7 @@ using System.Xml.Serialization; using CustomSpawns.ModIntegration; using CustomSpawns.Utils; +using TaleWorlds.Localization; namespace CustomSpawns.CampaignData.Config { @@ -50,7 +51,7 @@ private void ConstructConfigs(string xmlPath) if (!processed) { - _messageBoxService.ShowMessage("Could not find Campaign Data config file for type " + t.Name); + _messageBoxService.ShowMessage(new TextObject("{=SpawnAPIWarn003}Could not find Campaign Data config file for type {NAME}").SetTextVariable("NANE", t.Name).ToString()); } } } diff --git a/CustomSpawns/CampaignData/Implementations/DevestationMetricData.cs b/CustomSpawns/CampaignData/Implementations/DevestationMetricData.cs index c42daaa..32cb87f 100644 --- a/CustomSpawns/CampaignData/Implementations/DevestationMetricData.cs +++ b/CustomSpawns/CampaignData/Implementations/DevestationMetricData.cs @@ -7,6 +7,7 @@ using TaleWorlds.CampaignSystem.MapEvents; using TaleWorlds.CampaignSystem.Settlements; using TaleWorlds.TwoDimension; +using TaleWorlds.Localization; namespace CustomSpawns.CampaignData.Implementations { @@ -84,13 +85,13 @@ private void OnMapEventEnded(MapEvent e) if (!_settlementToDevestation.ContainsKey(closestSettlement)) { - _messageBoxService.ShowCustomSpawnsErrorMessage(new System.Exception("Devestation value for settlement could not be found!")); + _messageBoxService.ShowCustomSpawnsErrorMessage(new System.Exception("Devastation value for settlement could not be found!")); return; } ChangeDevestation(closestSettlement, increase); - _modDebug.ShowMessage("Fight at " + closestSettlement.Name + ". Increasing devestation by " + increase + ". New devestation is: " + _settlementToDevestation[closestSettlement], _config); + _modDebug.ShowMessage(new TextObject("{=SpawnAPIMsg003}Fight at {SETTLEMENT}. Increasing devastation by {VALUE1}. New devastation is: {VALUE2}", new Dictionary() { { "SETTLEMENT", closestSettlement.Name}, { "VALUE1", increase}, { "VALUE2", _settlementToDevestation[closestSettlement] } }).ToString(), _config); } private void OnVillageLooted(Village v) @@ -100,7 +101,7 @@ private void OnVillageLooted(Village v) ChangeDevestation(v.Settlement, _config.DevestationPerTimeLooted); - _modDebug.ShowMessage("Successful Looting at " + v.Name + ". Increasing devestation by " + _config.DevestationPerTimeLooted, _config); + _modDebug.ShowMessage(new TextObject("{=SpawnAPIMsg004}Successful Looting at {NAME}. Increasing devastation by {VALUE}", new Dictionary() { { "NAME", v.Name}, { "VALUE", _config.DevestationPerTimeLooted } }).ToString(), _config); } private void OnSettlementDaily(Settlement s) @@ -136,7 +137,7 @@ private void OnSettlementDaily(Settlement s) } } - if(friendlyGain > 0) + if (friendlyGain > 0) { //ModDebug.ShowMessage("Calculating friendly presence devestation decay in " + s.Name + ". Decreasing devestation by " + friendlyGain, campaignConfig); @@ -144,21 +145,21 @@ private void OnSettlementDaily(Settlement s) } - if(hostileDecay > 0) + if (hostileDecay > 0) { - _modDebug.ShowMessage("Calculating hostile presence devestation gain in " + s.Name + ". Increasing devestation by " + hostileDecay, _config); + _modDebug.ShowMessage(new TextObject("{=SpawnAPIMsg005}Calculating hostile presence devastation gain in {NAME}. Increasing devastation gain in {VALUE}", new Dictionary() { { "NAME", s.Name }, { "VALUE", hostileDecay } }).ToString(), _config); ChangeDevestation(s, hostileDecay); } - if(GetDevestation(s) > 0) + if (GetDevestation(s) > 0) { - _modDebug.ShowMessage("Calculating daily Devestation Decay in " + s.Name + ". Decreasing devestation by " + _config.DailyDevestationDecay, _config); + _modDebug.ShowMessage(new TextObject("{=SpawnAPIMsg006}Calculating daily Devastation Decay in {NAME}. Decreasing devastation by {VALUE}", new Dictionary() { { "NAME", s.Name }, { "VALUE", _config.DailyDevestationDecay } }).ToString(), _config); ChangeDevestation(s, -_config.DailyDevestationDecay); } - if(GetDevestation(s) != 0) - _modDebug.ShowMessage("Current Devestation at " + s.Name + " is now " + _settlementToDevestation[s], _config); + if (GetDevestation(s) != 0) + _modDebug.ShowMessage(new TextObject("{=SpawnAPIMsg007}Current Devastation at {NAME} is now {VALUE}", new Dictionary() {{ "NAME", s.Name }, { "VALUE", _settlementToDevestation[s] }}).ToString(), _config); } #endregion @@ -169,7 +170,7 @@ private void ChangeDevestation(Settlement s, float change) { if (!_settlementToDevestation.ContainsKey(s)) { - _messageBoxService.ShowCustomSpawnsErrorMessage(new System.Exception("Devastation value for settlement could not be found!")); + _messageBoxService.ShowCustomSpawnsErrorMessage(new System.Exception("Devestation value for settlement could not be found!")); return; } @@ -187,7 +188,7 @@ public float GetDevestation(Settlement s) if (_settlementToDevestation.ContainsKey(s)) return _settlementToDevestation[s]; - _messageBoxService.ShowCustomSpawnsErrorMessage(new System.Exception("Devestation value for settlement could not be found!")); + _messageBoxService.ShowCustomSpawnsErrorMessage(new System.Exception("Devastation value for settlement could not be found!")); return 0; } diff --git a/CustomSpawns/Data/Dao/SpawnDao.cs b/CustomSpawns/Data/Dao/SpawnDao.cs index 7bf4cee..9543265 100644 --- a/CustomSpawns/Data/Dao/SpawnDao.cs +++ b/CustomSpawns/Data/Dao/SpawnDao.cs @@ -7,6 +7,7 @@ using CustomSpawns.Exception; using CustomSpawns.Utils; using TaleWorlds.Core; +using TaleWorlds.Localization; namespace CustomSpawns.Data.Dao { @@ -42,11 +43,11 @@ private List Spawns() } catch (TechnicalException e) { - _messageBoxService.ShowMessage("Warning: The Custom Spawns API detected that you are trying to load" + + _messageBoxService.ShowMessage(new TextObject("{=SpawnAPIWarn001}Warning: The Custom Spawns API detected that you are trying to load" + " a Custom Spawns sub-mod into an existing saved game." + " This mod requires a fresh start to work correctly.\n" + "If you decide to continue, expect to have very unstable" + - " behaviours during your play-through."); + " behaviours during your play-through.").ToString()); return null; } }) diff --git a/CustomSpawns/Data/Model/Dialogue/DefaultDialogue.cs b/CustomSpawns/Data/Model/Dialogue/DefaultDialogue.cs index b65ba28..5086987 100644 --- a/CustomSpawns/Data/Model/Dialogue/DefaultDialogue.cs +++ b/CustomSpawns/Data/Model/Dialogue/DefaultDialogue.cs @@ -26,7 +26,7 @@ private Dialogue HostileAttackDialogue() { Dialogue dialogue = new(); dialogue.IsPlayerDialogue = false; - dialogue.Text = "That's a nice head on your shoulders!"; + dialogue.Text = "{=EVkXWo6S}That's a nice head on your shoulders!"; dialogue.Consequence = "Battle"; dialogue.Condition = BaseDefaultCondition + " AND IsHostile AND IsAttacking"; dialogue.Options = new(); @@ -37,7 +37,7 @@ private Dialogue HostileDefendDialogue() { Dialogue dialogue = new(); dialogue.IsPlayerDialogue = false; - dialogue.Text = "I will drink from your skull!"; + dialogue.Text = "{=C7PgdtDN}I will drink from your skull!"; dialogue.Consequence = "Battle"; dialogue.Condition = BaseDefaultCondition + " AND IsHostile AND IsDefending"; dialogue.Options = new(); @@ -48,7 +48,7 @@ private Dialogue FriendlyDialogue() { Dialogue dialogue = new(); dialogue.IsPlayerDialogue = false; - dialogue.Text = "It's almost harvesting season!"; + dialogue.Text = "{=Z28hBxDM}It's almost harvesting season!"; dialogue.Condition = BaseDefaultCondition + " AND IsFriendly"; dialogue.Options = new(); dialogue.Options.Add(AttackFriendlyDialogue()); @@ -60,7 +60,7 @@ private Dialogue LeaveFriendlyDialogue() { Dialogue dialogue = new(); dialogue.IsPlayerDialogue = true; - dialogue.Text = "Away with you vile beggar!"; + dialogue.Text = "{=J50mnkoo}Away with you vile beggar!"; dialogue.Consequence = "Leave"; dialogue.Options = new(); return dialogue; @@ -70,7 +70,7 @@ private Dialogue AttackFriendlyDialogue() { Dialogue dialogue = new(); dialogue.IsPlayerDialogue = true; - dialogue.Text = "I will tear you limb from limb!"; + dialogue.Text = "{=nJ3uAPZH}I will tear you limb from limb!"; dialogue.Consequence = "War"; dialogue.Options = new(); return dialogue; diff --git a/CustomSpawns/Data/Model/Spawn.cs b/CustomSpawns/Data/Model/Spawn.cs index 0ad14ae..49f5193 100644 --- a/CustomSpawns/Data/Model/Spawn.cs +++ b/CustomSpawns/Data/Model/Spawn.cs @@ -1,9 +1,14 @@ -using System; +using CustomSpawns.Utils; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Text.RegularExpressions; using System.Xml; using System.Xml.Serialization; +using TaleWorlds.Diamond; +using TaleWorlds.Library; +using TaleWorlds.Localization; namespace CustomSpawns.Data.Model { @@ -39,13 +44,45 @@ public class Spawn public int RepeatSpawnRolls { get; set; } = 1; [XmlElement(ElementName="SpawnMessage")] - public string? SpawnMessage { get; set; } + public string? SpawnMessage { + get + { + return this._spawnMessage; + } + set + { + if (value == null) + { + this._spawnMessage = null; + } + else + { + this._spawnMessage = Regex.Replace(value.ToString(), @"\[" + UX.SpawnPlaceIdentifier + @"\]", $"{{{UX.SpawnPlaceIdentifier}}}", RegexOptions.IgnoreCase); + } + } + } + private string? _spawnMessage = null; [XmlElement(ElementName="SpawnMessageColor")] public string? SpawnMessageColor { get; set; } [XmlElement(ElementName="DeathMessage")] - public string? DeathMessage { get; set; } + public string? DeathMessage { + get + { return this._deathMessage; } + set + { + if (value == null) + { + this._deathMessage = value; + } + else + { + this._deathMessage = Regex.Replace(value.ToString(), @"\[" + UX.DeathPlaceIdentifier + @"\]", $"{{{UX.DeathPlaceIdentifier}}}", RegexOptions.IgnoreCase); + } + } + } + private string? _deathMessage = null; [XmlElement(ElementName = "DeathMessageColor")] public string? DeathMessageColor { get; set; } diff --git a/CustomSpawns/Dialogues/DialogueConsequenceInterpretor.cs b/CustomSpawns/Dialogues/DialogueConsequenceInterpretor.cs index deda565..5ccfca0 100644 --- a/CustomSpawns/Dialogues/DialogueConsequenceInterpretor.cs +++ b/CustomSpawns/Dialogues/DialogueConsequenceInterpretor.cs @@ -14,6 +14,7 @@ using TaleWorlds.CampaignSystem.Encounters; using TaleWorlds.CampaignSystem.Party; using TaleWorlds.Library; +using TaleWorlds.Localization; namespace CustomSpawns.Dialogues { @@ -99,7 +100,7 @@ public DialogueConsequence ParseConsequence(string text) } catch (System.Exception e) { - _messageBoxService.ShowMessage("Could not parse dialogue consequnce: \n" + text + "\n Error Message: \n" + e.Message); + _messageBoxService.ShowMessage(new TextObject("{SpawnAPIErr002}Could not parse dialogue consequnce:\n{TEXT}\nError Message:\n{ERROR}", new Dictionary() { { "TEXT", text }, { "EROR", e.Message } }).ToString()); return null; } @@ -306,12 +307,12 @@ private static void declare_peace_consequence_delegate() { //Interestingly, PlayerEncounter.EnemySurrender = true; results in a null reference crash. param.PlayerParty.Party.AddPrisoners(param.AdversaryParty.Party.MemberRoster); param.AdversaryParty.RemoveParty(); - UX.ShowMessage("You have taken your enemies prisoner.", TaleWorlds.Library.Colors.Green); + UX.ShowMessage(new TextObject("{=SpawnAPIMsg001}You have taken your enemies prisoner.").ToString(), TaleWorlds.Library.Colors.Green); end_conversation_consequence_delegate(param); } else { - _messageBoxService.ShowMessage("Can't interpret " + isPlayer.ToString() + " as a bool. Possible typo in the XML consequence 'Surrender'"); + _messageBoxService.ShowMessage(new TextObject("{=SpawnAPIMsg002}Can't interpret {PLAYER} as a bool. Possible typo in the XML consequence 'Surrender'").SetTextVariable("PLAYER", isPlayer.ToString()).ToString()); } PlayerEncounter.Update(); } diff --git a/CustomSpawns/Main.cs b/CustomSpawns/Main.cs index 67df6b0..dcaf537 100755 --- a/CustomSpawns/Main.cs +++ b/CustomSpawns/Main.cs @@ -19,6 +19,7 @@ using TaleWorlds.MountAndBlade; using TaleWorlds.CampaignSystem; using TaleWorlds.Library; +using TaleWorlds.Localization; namespace CustomSpawns { @@ -123,11 +124,11 @@ private void InstantiateDependencies() private void DisplayLoadedModules() { - UX.ShowMessage("Custom Spawns API loaded", Color.ConvertStringToColor("#001FFFFF")); + UX.ShowMessage(new TextObject("{=SpawnAPIMsg000}Custom Spawns API loaded").ToString(), Color.ConvertStringToColor("#001FFFFF")); AIManager.FlushRegisteredBehaviours(); //forget old behaviours to allocate space. foreach (var subMod in _subModService.GetAllLoadedSubMods()) { - UX.ShowMessage(subMod.SubModuleName + " is now integrated into the Custom Spawns API.", + UX.ShowMessage(new TextObject("{=SpawnAPIMsg010}{NAME} is now integrated into the Custom Spawns API.").SetTextVariable("NAME", subMod.SubModuleName).ToString(), Color.ConvertStringToColor("#001FFFFF")); } } diff --git a/CustomSpawns/Spawn/Spawner.cs b/CustomSpawns/Spawn/Spawner.cs index b8c7186..5046c5b 100755 --- a/CustomSpawns/Spawn/Spawner.cs +++ b/CustomSpawns/Spawn/Spawner.cs @@ -30,9 +30,7 @@ public MobileParty SpawnParty(Settlement spawnedSettlement, Clan clan, PartyTemp { //get name and show message. TextObject name = partyName ?? clan.Name; - _modDebug.ShowMessage( - "CustomSpawns: Spawning " + name + " at " + spawnedSettlement.GatePosition + " in settlement " + - spawnedSettlement.Name, DebugMessageType.Spawn); + _modDebug.ShowMessage(new TextObject("{=SpawnAPIDebug001}CustomSpawns: Spawning {NAME} at {POSITION} in settlement {SETTLEMENT}", new System.Collections.Generic.Dictionary { { "NAME", name}, { "POSITION", spawnedSettlement.GatePosition}, { "SETTLEMENT", spawnedSettlement.Name} }).ToString(), DebugMessageType.Spawn); if (clan.IsBanditFaction) { @@ -42,7 +40,7 @@ public MobileParty SpawnParty(Settlement spawnedSettlement, Clan clan, PartyTemp } catch (System.Exception e) { - _messageBoxService.ShowMessage("Possible invalid spawn data. Spawning of party terminated."); + _messageBoxService.ShowMessage(new TextObject("{=SpawnAPIWarn002}Possible invalid spawn data. Spawning of party terminated.").ToString()); _messageBoxService.ShowCustomSpawnsErrorMessage(e, "party spawning"); return null; } diff --git a/CustomSpawns/Utils/MessageBoxService.cs b/CustomSpawns/Utils/MessageBoxService.cs index c3850e0..3e28810 100644 --- a/CustomSpawns/Utils/MessageBoxService.cs +++ b/CustomSpawns/Utils/MessageBoxService.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using BUTR.MessageBoxPInvoke.Helpers; using TaleWorlds.Library; +using TaleWorlds.Localization; namespace CustomSpawns.Utils { @@ -20,7 +21,7 @@ public void ShowCustomSpawnsErrorMessage(System.Exception? e, string during = "" { errorMessage = e.Message + " AT " + e.Source + " " + duringMessage + "TRACE: " + e.StackTrace; } - string shown = "CustomSpawns error has occured, please report to mod developer: " + errorMessage; + string shown = new TextObject("{=SpawnAPIErr001}CustomSpawns error has occured, please report to mod developer: ").ToString() + errorMessage; ShowMessage(shown); } diff --git a/CustomSpawns/Utils/UX.cs b/CustomSpawns/Utils/UX.cs index 37f11b5..46a756b 100644 --- a/CustomSpawns/Utils/UX.cs +++ b/CustomSpawns/Utils/UX.cs @@ -1,15 +1,15 @@ using System; using System.Collections.Generic; -using System.Text; using TaleWorlds.Library; +using TaleWorlds.Localization; namespace CustomSpawns.Utils { public static class UX { - private static readonly string SpawnPlaceIdentifier = "spawnplace"; + public static readonly string SpawnPlaceIdentifier = "spawnplace"; - private static readonly string DeathPlaceIdentifier = "deathplace"; + public static readonly string DeathPlaceIdentifier = "deathplace"; private static readonly Dictionary FlagToMessageColour = new () { @@ -39,24 +39,7 @@ public static string GetMessageColour(string flag) private static string ResolveVariables(string message, string settlementName) { - string[] codes = message.Split(new [] { "[", "]"}, StringSplitOptions.None); - if (codes.Length == 1) { - return message; - } - StringBuilder spawnMessageBuilder = new(); - foreach(string code in codes) - { - string variable = code.ToLower(); - if (variable.Equals(SpawnPlaceIdentifier) || variable.Equals(DeathPlaceIdentifier)) - { - spawnMessageBuilder.Append(settlementName); - } - else - { - spawnMessageBuilder.Append(code); - } - } - return spawnMessageBuilder.ToString(); + return new TextObject(message, new Dictionary() { { SpawnPlaceIdentifier, settlementName }, { DeathPlaceIdentifier, settlementName} }).ToString(); } } } diff --git a/CustomSpawns/_Module/ModuleData/Languages/JP/language_data.xml b/CustomSpawns/_Module/ModuleData/Languages/JP/language_data.xml new file mode 100644 index 0000000..366a817 --- /dev/null +++ b/CustomSpawns/_Module/ModuleData/Languages/JP/language_data.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/CustomSpawns/_Module/ModuleData/Languages/JP/strings-JP.xml b/CustomSpawns/_Module/ModuleData/Languages/JP/strings-JP.xml new file mode 100644 index 0000000..e0c2cda --- /dev/null +++ b/CustomSpawns/_Module/ModuleData/Languages/JP/strings-JP.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CustomSpawns/_Module/ModuleData/Languages/strings-EN.xml b/CustomSpawns/_Module/ModuleData/Languages/strings-EN.xml new file mode 100644 index 0000000..81d03ba --- /dev/null +++ b/CustomSpawns/_Module/ModuleData/Languages/strings-EN.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +