├── BannerKings.TroopOverhaul ├── _Module │ ├── ModuleData │ │ ├── settlements_distance_cache.bin │ │ ├── Languages │ │ │ ├── language_data.xml │ │ │ └── DE │ │ │ │ ├── common_strings.xml │ │ │ │ ├── language_data.xml │ │ │ │ └── std_module_strings_xml.xml │ │ ├── equipments │ │ │ └── equipment_sets.xslt │ │ ├── lords.xslt │ │ ├── bodyproperties.xml │ │ ├── gt_common.xslt │ │ ├── Characters │ │ │ └── lords.xml │ │ ├── spclans.xslt │ │ ├── heroes.xml │ │ ├── kingdoms.xslt │ │ ├── skill_templates.xml │ │ ├── settlements.xslt │ │ └── recruits.xml │ └── SubModule.xml ├── Religions │ ├── Rites │ │ ├── SiriCow.cs │ │ ├── Liberatio.cs │ │ ├── SiriHoney.cs │ │ └── Lustratio.cs │ ├── BKCEReligions.cs │ ├── BKCEFaithGroups.cs │ ├── LegionariesSarapios.cs │ ├── Calradism.cs │ ├── Siri.cs │ ├── Ahhakism.cs │ ├── Jumne.cs │ └── ImmortalFlame.cs ├── Models │ ├── BKCESecurityModel.cs │ ├── BKCEEconomyModel.cs │ ├── BKCEMilitiaModel.cs │ ├── BKCETroopUpgradeModel.cs │ ├── BKCEFoodModel.cs │ ├── BKCEDeathModel.cs │ ├── BKCEGrowthModel.cs │ ├── BKCERaidModel.cs │ ├── BKCEPartyHealingModel.cs │ ├── BKCEReligionModel.cs │ ├── BKCELoyaltyModel.cs │ ├── BKCEPartyFoodModel.cs │ ├── BKCETradeModel.cs │ ├── BKCEBattleSimulationModel.cs │ ├── BKCEStabilityModel.cs │ ├── BKCEEquipmentModel.cs │ ├── BKCEVolunteerModel.cs │ ├── BKCEInfluenceModel.cs │ ├── BKCEPartyWageModel.cs │ ├── BKCECultureModel.cs │ ├── BKCELegitimacyModel.cs │ ├── BKCEPartyMorale.cs │ ├── BKCEPartySpeedModel.cs │ ├── BKCETaxModel.cs │ ├── BKCEVillageProductionModel.cs │ └── BKCEProsperityModel.cs ├── SaveDefiner.cs ├── BKCESettings.cs ├── Goals │ ├── BKTOGoals.cs │ └── CrownGuardGoal.cs ├── BannerKings - Backup.TroopOverhaul.csproj ├── Behaviors │ ├── Invasions │ │ └── BKCEInvasions.cs │ ├── CrownGuardBehavior.cs │ └── FeatBehavior.cs ├── BannerKings.CulturesExpanded.csproj ├── CC │ └── BKCEGameManager.cs ├── Cultures │ ├── BKCEShippingLanes.cs │ └── BKCEMarketGroups.cs ├── Main.cs └── Patches │ └── CharacterCreationPatches.cs ├── BannerKings.CulturesExpanded.sln ├── README.md ├── .gitattributes └── .gitignore /BannerKings.TroopOverhaul/_Module/ModuleData/settlements_distance_cache.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Vaccari/BannerKings.CulturesExpanded/HEAD/BannerKings.TroopOverhaul/_Module/ModuleData/settlements_distance_cache.bin -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/Languages/language_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/Languages/DE/common_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/Languages/DE/language_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/Languages/DE/std_module_strings_xml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/Rites/SiriCow.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths.Rites; 2 | using TaleWorlds.Core; 3 | using TaleWorlds.Localization; 4 | using TaleWorlds.ObjectSystem; 5 | 6 | namespace BannerKings.CulturesExpanded.Religions.Rites 7 | { 8 | public class SiriCow : Offering 9 | { 10 | public SiriCow() : base(MBObjectManager.Instance.GetObject("cow"), 11 | 5) 12 | { 13 | } 14 | 15 | public override TextObject GetName() => new TextObject("{=!}Tuygu Darpne"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/Rites/Liberatio.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths.Rites; 2 | using TaleWorlds.Core; 3 | using TaleWorlds.Localization; 4 | using TaleWorlds.ObjectSystem; 5 | 6 | namespace BannerKings.CulturesExpanded.Religions.Rites 7 | { 8 | public class Liberatio : Offering 9 | { 10 | public Liberatio() : base(MBObjectManager.Instance.GetObject("wine"), 11 | 20) 12 | { 13 | } 14 | 15 | public override TextObject GetName() => new TextObject("{=!}Liberatio"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/Rites/SiriHoney.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths.Rites; 2 | using TaleWorlds.Core; 3 | using TaleWorlds.Localization; 4 | using TaleWorlds.ObjectSystem; 5 | 6 | namespace BannerKings.CulturesExpanded.Religions.Rites 7 | { 8 | public class SiriHoney : Offering 9 | { 10 | public SiriHoney() : base(MBObjectManager.Instance.GetObject("honey"), 11 | 20) 12 | { 13 | } 14 | 15 | public override TextObject GetName() => new TextObject("{=!}Honey Darpne"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/equipments/equipment_sets.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCESecurityModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | 6 | namespace BannerKings.CulturesExpanded.Models 7 | { 8 | public class BKCESecurityModel : BKSecurityModel 9 | { 10 | public override ExplainedNumber CalculateSecurityChange(Town town, bool includeDescriptions = false) 11 | { 12 | ExplainedNumber result = base.CalculateSecurityChange(town, includeDescriptions); 13 | 14 | Utils.Helpers.ApplyFeat(BKCEFeats.Instance.Massa2, town.Owner, ref result); 15 | return result; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEEconomyModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | 6 | namespace BannerKings.CulturesExpanded.Models 7 | { 8 | public class BKCEEconomyModel : BKEconomyModel 9 | { 10 | public override ExplainedNumber CalculateTradePower(Settlement settlement, bool descriptions = false) 11 | { 12 | ExplainedNumber result = base.CalculateTradePower(settlement, descriptions); 13 | Utils.Helpers.ApplyFeat(BKCEFeats.Instance.Geroia1, settlement.Party, ref result); 14 | 15 | return result; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEMilitiaModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | 6 | namespace BannerKings.CulturesExpanded.Models 7 | { 8 | public class BKCEMilitiaModel : BKMilitiaModel 9 | { 10 | public override ExplainedNumber CalculateMilitiaChange(Settlement settlement, bool includeDescriptions = false) 11 | { 12 | ExplainedNumber result = base.CalculateMilitiaChange(settlement, includeDescriptions); 13 | 14 | Utils.Helpers.ApplyFeat(BKCEFeats.Instance.VillageMilitia, settlement.Party, ref result); 15 | return result; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCETroopUpgradeModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Party; 5 | 6 | namespace BannerKings.CulturesExpanded.Models 7 | { 8 | public class BKCETroopUpgradeModel : BKTroopUpgradeModel 9 | { 10 | public override int GetXpCostForUpgrade(PartyBase party, CharacterObject characterObject, CharacterObject upgradeTarget) 11 | { 12 | float result = base.GetXpCostForUpgrade(party, characterObject, upgradeTarget); 13 | if (characterObject.Culture.HasFeat(BKCEFeats.Instance.Darshi1)) 14 | { 15 | result *= 1f + BKCEFeats.Instance.Darshi1.EffectBonus; 16 | } 17 | 18 | return (int)result; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEFoodModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Managers.Populations; 3 | using BannerKings.Models.Vanilla; 4 | using TaleWorlds.CampaignSystem; 5 | using TaleWorlds.Core; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCEFoodModel : BKFoodModel 10 | { 11 | public override ExplainedNumber GetPopulationFoodConsumption(PopulationData data) 12 | { 13 | ExplainedNumber result = base.GetPopulationFoodConsumption(data); 14 | if (data.Settlement.Culture.HasFeat(BKCEFeats.Instance.FoodConsumption)) 15 | { 16 | result.AddFactor(BKCEFeats.Instance.FoodConsumption.EffectBonus, GameTexts.FindText("str_culture")); 17 | } 18 | 19 | return result; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEDeathModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Religions; 2 | using TaleWorlds.CampaignSystem; 3 | using TaleWorlds.CampaignSystem.GameComponents; 4 | 5 | namespace BannerKings.CulturesExpanded.Models 6 | { 7 | public class BKCEDeathModel : DefaultHeroDeathProbabilityCalculationModel 8 | { 9 | public override float CalculateHeroDeathProbability(Hero hero) 10 | { 11 | float chance = base.CalculateHeroDeathProbability(hero); 12 | if (!CampaignOptions.IsLifeDeathCycleDisabled) 13 | { 14 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(hero, BKCEDivinities.Instance.Ahhak)) 15 | { 16 | chance *= 0.1f; 17 | } 18 | } 19 | 20 | return chance; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEGrowthModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Managers.Populations; 3 | using BannerKings.Models.BKModels; 4 | using TaleWorlds.CampaignSystem; 5 | using TaleWorlds.CampaignSystem.Settlements; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCEGrowthModel: BKGrowthModel 10 | { 11 | public override ExplainedNumber CalculateSettlementCap(Settlement settlement, PopulationData data, bool descriptions = false) 12 | { 13 | ExplainedNumber result = base.CalculateSettlementCap(settlement, data, descriptions); 14 | 15 | if (settlement.IsTown) 16 | { 17 | Utils.Helpers.ApplyFeat(BKCEFeats.Instance.Megalopolis, settlement.Town.Owner, ref result); 18 | } 19 | 20 | return result; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCERaidModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem.MapEvents; 4 | 5 | namespace BannerKings.CulturesExpanded.Models 6 | { 7 | public class BKCERaidModel : BKRaidModel 8 | { 9 | public override float CalculateHitDamage(MapEventSide attackerSide, float settlementHitPoints) 10 | { 11 | float result = base.CalculateHitDamage(attackerSide, settlementHitPoints); 12 | var attacker = attackerSide.LeaderParty; 13 | if (attacker is { LeaderHero: { } }) 14 | { 15 | if (attacker.Culture.HasFeat(BKCEFeats.Instance.Massa1)) 16 | { 17 | result *= 1f + BKCEFeats.Instance.Massa1.EffectBonus; 18 | } 19 | } 20 | 21 | return result; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEPartyHealingModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Religions; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Party; 5 | 6 | namespace BannerKings.CulturesExpanded.Models 7 | { 8 | public class BKCEPartyHealingModel : BKPartyHealingModel 9 | { 10 | public override ExplainedNumber GetDailyHealingForRegulars(MobileParty party, bool includeDescriptions = false) 11 | { 12 | ExplainedNumber result = base.GetDailyHealingForRegulars(party, includeDescriptions); 13 | 14 | Hero leader = party.LeaderHero; 15 | if (leader != null) 16 | { 17 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Jinn)) 18 | { 19 | result.Add(0.8f, BKCEDivinities.Instance.Jinn.Name); 20 | } 21 | } 22 | 23 | return result; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/SaveDefiner.cs: -------------------------------------------------------------------------------- 1 | using TaleWorlds.SaveSystem; 2 | using BannerKings.CulturesExpanded.Religions; 3 | using BannerKings.Managers.Institutions.Religions.Faiths.Empire; 4 | 5 | namespace BannerKings 6 | { 7 | internal class SaveDefiner : SaveableTypeDefiner 8 | { 9 | public SaveDefiner() : base(83828290) 10 | { 11 | } 12 | 13 | protected override void DefineClassTypes() 14 | { 15 | AddClassDefinition(typeof(Calradism), 1); 16 | AddClassDefinition(typeof(LegionariesSarapios), 2); 17 | AddClassDefinition(typeof(Jumne), 3); 18 | AddClassDefinition(typeof(Rodovera), 4); 19 | AddClassDefinition(typeof(ImmortalFlame), 5); 20 | AddClassDefinition(typeof(Siri), 6); 21 | AddClassDefinition(typeof(Kannic), 7); 22 | AddClassDefinition(typeof(Ahhakism), 8); 23 | } 24 | 25 | protected override void DefineContainerDefinitions() 26 | { 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEReligionModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions; 2 | using BannerKings.Models.BKModels; 3 | using TaleWorlds.CampaignSystem.Settlements; 4 | using TaleWorlds.CampaignSystem; 5 | using BannerKings.CulturesExpanded.Religions; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCEReligionModel : BKReligionModel 10 | { 11 | public new ExplainedNumber CalculateReligionWeight(Religion religion, Settlement settlement) 12 | { 13 | ExplainedNumber result = base.CalculateReligionWeight(religion, settlement); 14 | if (settlement.OwnerClan != null) 15 | { 16 | Hero leader = settlement.OwnerClan.Leader; 17 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Erithrians)) 18 | { 19 | result.Add(5f, BKCEDivinities.Instance.Erithrians.Name); 20 | } 21 | } 22 | 23 | return result; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCELoyaltyModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Religions; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | 6 | namespace BannerKings.CulturesExpanded.Models 7 | { 8 | public class BKCELoyaltyModel : BKLoyaltyModel 9 | { 10 | public override ExplainedNumber CalculateLoyaltyChange(Town town, bool includeDescriptions = false) 11 | { 12 | ExplainedNumber result = base.CalculateLoyaltyChange(town, includeDescriptions); 13 | if (town.OwnerClan != null) 14 | { 15 | Hero leader = town.OwnerClan.Leader; 16 | if (town.Culture.StringId == BannerKingsConfig.EmpireCulture && 17 | BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Erithrians)) 18 | { 19 | result.Add(0.5f, BKCEDivinities.Instance.Erithrians.Name); 20 | } 21 | } 22 | 23 | return result; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/BKCESettings.cs: -------------------------------------------------------------------------------- 1 | using TaleWorlds.Localization; 2 | using MCM.Abstractions.Attributes.v1; 3 | using MCM.Abstractions.Base.Global; 4 | 5 | namespace BannerKings.Settings 6 | { 7 | public class BKCESettings : AttributeGlobalSettings 8 | { 9 | public override string Id => "BannerKings.CulturesExpanded"; 10 | public override string DisplayName => new TextObject("{=!}Banner Kings: Cultures Expanded").ToString(); 11 | public override string FolderName => "BannerKings.CulturesExpanded"; 12 | public override string FormatType => "json2"; 13 | 14 | [SettingProperty("{=!}Imperial Latin Titles", RequireRestart = true, HintText = "{=!}For Empire titles, switch the use of Hellenic titles to Latin titles. Default: False.")] 15 | public bool LatinTitles { get; set; } = false; 16 | 17 | [SettingProperty("{=!}Battanian Goidelic Titles", RequireRestart = true, HintText = "{=!}For Battanian titles, switch the use of Brythonic titles to Goedelic titles. Default: False.")] 18 | public bool GoidelicTitles { get; set; } = false; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEPartyFoodModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Models.Vanilla; 2 | using TaleWorlds.CampaignSystem; 3 | using TaleWorlds.CampaignSystem.Party; 4 | using TaleWorlds.Core; 5 | 6 | namespace BannerKings.CulturesExpanded.Models 7 | { 8 | public class BKCEPartyFoodModel : BKPartyConsumptionModel 9 | { 10 | public override ExplainedNumber CalculateDailyFoodConsumptionf(MobileParty party, ExplainedNumber baseConsumption) 11 | { 12 | ExplainedNumber result = base.CalculateDailyFoodConsumptionf(party, baseConsumption); 13 | if (TaleWorlds.CampaignSystem.Campaign.Current.MapSceneWrapper.GetFaceTerrainType(party.CurrentNavigationFace) == TerrainType.Swamp) 14 | { 15 | float mounts = CalculateAnimalFoodNeed(party, false); 16 | result.Add(mounts / 2f, new TaleWorlds.Localization.TextObject("{=!}Carrying {COUNT} animals while sailing (inventory, party and prisoners)") 17 | .SetTextVariable("COUNT", mounts.ToString("0"))); 18 | } 19 | 20 | return result; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCETradeModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Religions; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Party; 5 | using TaleWorlds.Core; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCEPriceModel : BKPriceFactorModel 10 | { 11 | public override float GetTradePenalty(ItemObject item, MobileParty clientParty, PartyBase merchant, bool isSelling, float inStore, float supply, float demand) 12 | { 13 | ExplainedNumber result = new ExplainedNumber(base.GetTradePenalty(item, clientParty, merchant, isSelling, inStore, supply, demand)); 14 | if (clientParty != null) 15 | { 16 | Hero hero = clientParty.LeaderHero; 17 | if (hero != null) 18 | { 19 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(hero, BKCEDivinities.Instance.VineGoddess)) 20 | { 21 | result.AddFactor(-0.1f); 22 | } 23 | } 24 | } 25 | 26 | return result.ResultNumber; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/lords.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Culture.rhodok 11 | 12 | 13 | 14 | Culture.rhodok 15 | 16 | 17 | 18 | Culture.swadia 19 | 20 | 21 | 22 | Culture.swadia 23 | 24 | 25 | 26 | Culture.swadia 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /BannerKings.CulturesExpanded.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32819.101 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BannerKings.CulturesExpanded", "BannerKings.TroopOverhaul\BannerKings.CulturesExpanded.csproj", "{E822D013-8806-4B16-93F9-92752E79F705}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {E822D013-8806-4B16-93F9-92752E79F705}.Debug|Any CPU.ActiveCfg = Debug|x64 15 | {E822D013-8806-4B16-93F9-92752E79F705}.Debug|Any CPU.Build.0 = Debug|x64 16 | {E822D013-8806-4B16-93F9-92752E79F705}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {E822D013-8806-4B16-93F9-92752E79F705}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {C5381BA8-771A-41CD-8C01-5C3CB1F1DF49} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/bodyproperties.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 17 | 18 | 20 | 26 | 32 | 33 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/gt_common.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEBattleSimulationModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Models.Vanilla; 2 | using TaleWorlds.CampaignSystem; 3 | using TaleWorlds.CampaignSystem.MapEvents; 4 | using TaleWorlds.CampaignSystem.Party; 5 | using TaleWorlds.Core; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCEBattleSimulationModel : BKBattleSimulationModel 10 | { 11 | public override int SimulateHit(CharacterObject strikerTroop, CharacterObject struckTroop, PartyBase strikerParty, PartyBase struckParty, float strikerAdvantage, MapEvent battle) 12 | { 13 | float result = base.SimulateHit(strikerTroop, struckTroop, strikerParty, struckParty, strikerAdvantage, battle); 14 | 15 | if (strikerParty.IsMobile && TaleWorlds.CampaignSystem.Campaign.Current.MapSceneWrapper 16 | .GetFaceTerrainType(strikerParty.MobileParty.CurrentNavigationFace) == TerrainType.Swamp) 17 | { 18 | if (strikerTroop.IsMounted) 19 | { 20 | result *= 0.6f; 21 | } 22 | 23 | if (struckTroop.IsMounted) 24 | { 25 | result = 1.2f; 26 | } 27 | } 28 | 29 | return (int)result; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEStabilityModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Religions; 2 | using BannerKings.Models.BKModels; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | 6 | namespace BannerKings.CulturesExpanded.Models 7 | { 8 | public class BKCEStabilityModel : BKStabilityModel 9 | { 10 | public override ExplainedNumber CalculateStabilityTarget(Settlement settlement, bool descriptions = false) 11 | { 12 | ExplainedNumber result = base.CalculateStabilityTarget(settlement, descriptions); 13 | 14 | if (settlement.OwnerClan != null) 15 | { 16 | Hero leader = settlement.OwnerClan.Leader; 17 | var rel = BannerKingsConfig.Instance.ReligionsManager.GetHeroReligion(leader); 18 | if (rel != null) 19 | { 20 | if (settlement.Culture.StringId == "darshi" && 21 | BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.ImmortalFlame, rel)) 22 | { 23 | result.Add(0.1f, BKCEDivinities.Instance.ImmortalFlame.Name); 24 | } 25 | } 26 | } 27 | 28 | return result; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Goals/BKTOGoals.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Goals; 2 | using BannerKings.Managers.Goals.Decisions; 3 | using System.Collections.Generic; 4 | 5 | namespace BannerKings.CulturesExpanded.Goals 6 | { 7 | internal class BKTOGoals : DefaultTypeInitializer 8 | { 9 | public CrownGuardGoal CrownGuard { get; } = new CrownGuardGoal(); 10 | public Goal VlandiaGoal { get; } = new VlandiaEmpireGoal(); 11 | public Goal BattaniaGoal { get; } = new GreaterBattaniaGoal(); 12 | public Goal AseraiGoal { get; } = new AseraiEmpireGoal(); 13 | public Goal SturgiaGoal { get; } = new SturgiaEmpireGoal(); 14 | public Goal DarshiGoal { get; } = new DarshiEmpireGoal(); 15 | public override IEnumerable All 16 | { 17 | get 18 | { 19 | yield return CrownGuard; 20 | yield return VlandiaGoal; 21 | yield return BattaniaGoal; 22 | yield return AseraiGoal; 23 | yield return SturgiaGoal; 24 | yield return DarshiGoal; 25 | } 26 | } 27 | 28 | public override void Initialize() 29 | { 30 | foreach (Goal goal in All) 31 | { 32 | DefaultGoals.Instance.AddObject(goal); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEEquipmentModel.cs: -------------------------------------------------------------------------------- 1 | using TaleWorlds.CampaignSystem; 2 | using TaleWorlds.CampaignSystem.Extensions; 3 | using TaleWorlds.CampaignSystem.GameComponents; 4 | using TaleWorlds.Core; 5 | using TaleWorlds.Library; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCEEquipmentModel : DefaultEquipmentSelectionModel 10 | { 11 | public override MBList GetEquipmentRostersForHeroComeOfAge(Hero hero, bool isCivilian) 12 | { 13 | MBList result = base.GetEquipmentRostersForHeroComeOfAge(hero, isCivilian); 14 | if (result.IsEmpty()) 15 | { 16 | foreach (MBEquipmentRoster mbequipmentRoster in MBEquipmentRosterExtensions.All) 17 | { 18 | if (mbequipmentRoster.EquipmentCulture == hero.Culture) 19 | { 20 | if (!isCivilian && mbequipmentRoster.HasEquipmentFlags(EquipmentFlags.IsCombatantTemplate)) 21 | result.Add(mbequipmentRoster); 22 | else if (isCivilian && mbequipmentRoster.HasEquipmentFlags(EquipmentFlags.IsCivilianTemplate)) 23 | result.Add(mbequipmentRoster); 24 | } 25 | } 26 | } 27 | 28 | return result; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEVolunteerModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Models.Vanilla; 2 | using TaleWorlds.CampaignSystem.Settlements; 3 | using TaleWorlds.CampaignSystem; 4 | using BannerKings.CulturesExpanded.Religions; 5 | using BannerKings.CulturesExpanded.Cultures; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCEVolunteerModel : BKVolunteerModel 10 | { 11 | public new ExplainedNumber GetMilitarism(Settlement settlement) 12 | { 13 | ExplainedNumber result = base.GetMilitarism(settlement); 14 | if (settlement.Culture.StringId == BannerKingsConfig.EmpireCulture && settlement.OwnerClan != null) 15 | { 16 | Hero leader = settlement.OwnerClan.Leader; 17 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Ireos)) 18 | { 19 | result.Add(0.04f, BKCEDivinities.Instance.Ireos.Name); 20 | } 21 | } 22 | 23 | return result; 24 | } 25 | 26 | public override ExplainedNumber GetDraftEfficiency(Hero hero, Settlement settlement) 27 | { 28 | ExplainedNumber result = base.GetDraftEfficiency(hero, settlement); 29 | 30 | Utils.Helpers.ApplyFeat(BKCEFeats.Instance.Demobilization, settlement.Party, ref result); 31 | return result; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEInfluenceModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Religions; 2 | using BannerKings.Models.Vanilla; 3 | using TaleWorlds.CampaignSystem; 4 | 5 | namespace BannerKings.CulturesExpanded.Models 6 | { 7 | public class BKCEInfluenceModel : BKInfluenceModel 8 | { 9 | public override ExplainedNumber CalculateInfluenceChange(Clan clan, bool includeDescriptions = false) 10 | { 11 | ExplainedNumber result = base.CalculateInfluenceChange(clan, includeDescriptions); 12 | Hero leader = clan.Leader; 13 | if (leader != null) 14 | { 15 | var rel = BannerKingsConfig.Instance.ReligionsManager.GetHeroReligion(leader); 16 | if (rel != null) 17 | { 18 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(clan.Leader, BKCEDivinities.Instance.Calradios, rel)) 19 | { 20 | result.AddFactor(result.BaseNumber > 0f ? 0.3f : -0.3f, BKCEDivinities.Instance.Calradios.Name); 21 | } 22 | 23 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(clan.Leader, BKCEDivinities.Instance.GreatLion, rel)) 24 | { 25 | result.AddFactor(result.BaseNumber > 0f ? 0.25f : -0.25f, BKCEDivinities.Instance.Calradios.Name); 26 | } 27 | } 28 | } 29 | 30 | return result; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/Rites/Lustratio.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths.Rites; 2 | using System.Collections.Generic; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.Core; 5 | using TaleWorlds.Localization; 6 | using TaleWorlds.ObjectSystem; 7 | 8 | namespace BannerKings.CulturesExpanded.Religions.Rites 9 | { 10 | internal class Lustratio : CompositeOffering 11 | { 12 | public Lustratio() : base(new Dictionary() 13 | { 14 | { MBObjectManager.Instance.GetObject("hog"), 1 }, 15 | { MBObjectManager.Instance.GetObject("sheep"), 1 }, 16 | { MBObjectManager.Instance.GetObject("cow"), 1 } 17 | }) 18 | { 19 | } 20 | 21 | public override TextObject GetDescription() => new TextObject("{=!}An ancient Calradoi ritual to honor Ireos, the spear-wielder. The rite consists of sacrificing a sheep, a hog and a cow. It is considered a form of purification and begets the favor of the war god, granting various helpful blessings."); 22 | 23 | public override TextObject GetName() => new TextObject("{=!}Lustratio"); 24 | 25 | public override float GetPietyReward() 26 | { 27 | return 100f; 28 | } 29 | 30 | public override TextObject GetRequirementsText(Hero hero) 31 | { 32 | return new TextObject("{=6Yj8erp7}May be performed every {YEARS} years\nRequires a cow, a hog and a sheep") 33 | .SetTextVariable("YEARS", GetTimeInterval(hero)); 34 | } 35 | 36 | public override void SetDialogue() 37 | { 38 | MBTextManager.SetTextVariable("CLERGYMAN_RITE_CONFIRM", 39 | new TextObject("{=!}Will you sacrifice a bull, a ram and a pig to Ireos, the god of war?")); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEPartyWageModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Models.Vanilla; 3 | using Helpers; 4 | using TaleWorlds.CampaignSystem; 5 | using TaleWorlds.CampaignSystem.Party; 6 | using TaleWorlds.Core; 7 | 8 | namespace BannerKings.CulturesExpanded.Models 9 | { 10 | public class BKCEPartyWageModel : BKPartyWageModel 11 | { 12 | public override ExplainedNumber GetTotalWage(MobileParty mobileParty, bool includeDescriptions = false) 13 | { 14 | ExplainedNumber wage = base.GetTotalWage(mobileParty, includeDescriptions); 15 | 16 | if (mobileParty.IsLordParty) 17 | { 18 | if (TaleWorlds.CampaignSystem.Campaign.Current.MapSceneWrapper.GetFaceTerrainType(mobileParty.CurrentNavigationFace) == TerrainType.Swamp) 19 | { 20 | wage.AddFactor(0.25f, new TaleWorlds.Localization.TextObject("{=!}Sailing")); 21 | } 22 | } 23 | 24 | if (PartyBaseHelper.HasFeat(mobileParty.Party, BKCEFeats.Instance.Kannic1)) 25 | { 26 | wage.AddFactor(BKCEFeats.Instance.Kannic1.EffectBonus, GameTexts.FindText("str_culture")); 27 | } 28 | 29 | return wage; 30 | } 31 | 32 | public override int GetTroopRecruitmentCost(CharacterObject troop, Hero buyerHero, bool withoutItemCost = false) 33 | { 34 | float cost = base.GetTroopRecruitmentCost(troop, buyerHero, withoutItemCost); 35 | 36 | if (buyerHero != null && buyerHero.Culture.HasFeat(BKCEFeats.Instance.Siri1)) 37 | { 38 | if (!troop.HasMount() && troop.Equipment.HasWeaponOfClass(WeaponClass.Bow)) 39 | { 40 | cost *= 1f + BKCEFeats.Instance.Siri1.EffectBonus; 41 | } 42 | } 43 | 44 | return (int)cost; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/BannerKings - Backup.TroopOverhaul.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.8.0 5 | net48 6 | x64 7 | 9.0 8 | disable 9 | $(MSBuildProjectName) 10 | $(MSBuildProjectName) 11 | $(BANNERLORD_GAME_DIR) 12 | 13 | 14 | 15 | embedded 16 | 17 | 18 | 19 | embedded 20 | 21 | 22 | 23 | 24 | %(Identity) 25 | False 26 | 27 | 28 | %(Identity) 29 | False 30 | 31 | 32 | %(Identity) 33 | False 34 | 35 | 36 | %(Identity) 37 | False 38 | 39 | 40 | %(Identity) 41 | False 42 | 43 | 44 | %(Identity) 45 | False 46 | 47 | 48 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCECultureModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Populations; 2 | using BannerKings.Models.BKModels; 3 | using TaleWorlds.CampaignSystem.Settlements; 4 | using TaleWorlds.CampaignSystem; 5 | using BannerKings.CulturesExpanded.Religions; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCECultureModel : BKCultureModel 10 | { 11 | public new ExplainedNumber CalculateCultureWeight(Settlement settlement, CultureDataClass data, float baseWeight = 0f) 12 | { 13 | ExplainedNumber result = base.CalculateCultureWeight(settlement, data, baseWeight); 14 | if (settlement.OwnerClan != null) 15 | { 16 | Hero leader = settlement.OwnerClan.Leader; 17 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Erithrians)) 18 | { 19 | result.Add(5f, BKCEDivinities.Instance.Erithrians.Name); 20 | } 21 | 22 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Sarapios)) 23 | { 24 | result.Add(8f, BKCEDivinities.Instance.Sarapios.Name); 25 | } 26 | } 27 | 28 | return result; 29 | } 30 | 31 | public new ExplainedNumber CalculateAcceptanceGain(CultureDataClass data) 32 | { 33 | ExplainedNumber result = base.CalculateAcceptanceGain(data); 34 | Settlement settlement = data.Settlement; 35 | if (settlement.OwnerClan != null) 36 | { 37 | Hero leader = settlement.OwnerClan.Leader; 38 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Sarapios)) 39 | { 40 | result.Add(0.05f, BKCEDivinities.Instance.Sarapios.Name); 41 | } 42 | } 43 | 44 | return result; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCELegitimacyModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Behaviours.Diplomacy; 2 | using BannerKings.CulturesExpanded.Religions; 3 | using BannerKings.Models.BKModels; 4 | using BannerKings.Utils.Models; 5 | using TaleWorlds.CampaignSystem; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCELegitimacyModel : BKLegitimacyModel 10 | { 11 | public override BKExplainedNumber CalculateEffect(KingdomDiplomacy diplomacy, bool explanations = false) 12 | { 13 | BKExplainedNumber result = base.CalculateEffect(diplomacy, explanations); 14 | Hero leader = diplomacy.Kingdom.Leader; 15 | string cultureId = leader.Culture.StringId; 16 | var rel = BannerKingsConfig.Instance.ReligionsManager.GetHeroReligion(leader); 17 | if (rel != null) 18 | { 19 | if (cultureId == "siri") 20 | { 21 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.GreatLion, rel)) 22 | { 23 | result.Add(0.1f, BKCEDivinities.Instance.GreatLion.Name); 24 | } 25 | } 26 | 27 | if (cultureId == "kannic") 28 | { 29 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Eshora, rel)) 30 | { 31 | result.Add(0.1f, BKCEDivinities.Instance.Eshora.Name); 32 | } 33 | } 34 | 35 | if (cultureId == "darshi") 36 | { 37 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.ImmortalFlame, rel)) 38 | { 39 | result.Add(0.1f, BKCEDivinities.Instance.ImmortalFlame.Name); 40 | } 41 | } 42 | } 43 | 44 | return result; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Behaviors/Invasions/BKCEInvasions.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Behaviors.Invasions; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using TaleWorlds.CampaignSystem; 5 | using TaleWorlds.CampaignSystem.Settlements; 6 | using TaleWorlds.Localization; 7 | 8 | namespace BannerKings.CulturesExpanded.Behaviors.Invasions 9 | { 10 | public class BKCEInvasions : DefaultTypeInitializer 11 | { 12 | public Invasion Darshi { get; } = new Invasion("Darshi"); 13 | public override IEnumerable All 14 | { 15 | get 16 | { 17 | yield return Darshi; 18 | } 19 | } 20 | 21 | public override void Initialize() 22 | { 23 | //western empire banner 11.6.40.1836.1836.768.774.1.0.0.106.143.149.610.617.764.762.1.1.0.529.149.149.52.53.727.907.1.0.0.511.116.116.35.35.687.914.1.0.-91.511.116.116.35.35.687.900.1.1.90.527.116.116.50.50.778.906.1.1.0.527.116.116.50.50.774.906.1.0.0.510.116.116.32.28.797.919.1.0.90.527.116.116.50.50.834.908.1.0.0 24 | CultureObject darshi = Utils.Helpers.GetCulture("darshi"); 25 | Clan darshiRuler = new Clan(); 26 | darshiRuler.InitializeClan(new TextObject(), 27 | new TextObject(), 28 | darshi, 29 | new TaleWorlds.Core.Banner()); 30 | darshiRuler.StringId = "bk_clan_darshi_1"; 31 | 32 | Kingdom darshiKingdom = new Kingdom(); 33 | darshiKingdom.InitializeKingdom(new TextObject(), 34 | new TextObject(), 35 | darshi, 36 | new TaleWorlds.Core.Banner(), 37 | 0, 38 | 0, 39 | Settlement.All.First(), 40 | new TextObject(), 41 | new TextObject(), 42 | new TextObject()); 43 | 44 | /*Darshi.Initialize("bk_darshi_1_1", 45 | darshiRuler, 46 | Settlement.All.First(x => x.StringId == ""), 47 | , 48 | new Dictionary() 49 | { 50 | 51 | });*/ 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Banner Kings: Cultures Expanded 2 | 3 | Read [Installation](https://github.com/R-Vaccari/BannerKings.CulturesExpanded/wiki/Installation) in order to install the mod correctly. 4 | 5 | ## FAQ 6 | ### ***What is this mod?*** 7 | Banner Kings: Cultures Expanded is the official expansion to the Banner Kings mod. It contains our lore and game-world interpretation. In the same spirit of Banner Kings, this interpretation aims to be lore-accurate to the Mount & Blade world (not just Bannerlord), while expanding on gaps left by the creators. 8 | 9 | ### ***What does it do?*** 10 | - What Banner Kings: Cultures Expanded IS NOT: 11 | - A mod that adds a variety of systems that run in parallel and in conjunction to the base game, that is [Banner Kings](https://github.com/R-Vaccari/bannerlord-banner-kings); 12 | - A mod that made to be sub-modded by other mods. 13 | - What Banner Kings: Cultures Expanded IS: 14 | - A mod that adds religions to Banner Kings embedded Religions system 15 | - A mod that alters the map; 16 | - A mod that alters and adds factions; 17 | - A mod that alters and adds cultures; 18 | - A mod that overhauls troop trees. 19 | 20 | 21 | ### ***Does it work with X mod?*** 22 | If the mod has overlapping features, no. 23 | Troops mod? NO. 24 | Factions mod? NO. 25 | ATC? NO. 26 | Map mod? NO. 27 | 28 | ### ***I can't enable the mod!*** 29 | READ [Installation](https://github.com/R-Vaccari/BannerKings.CulturesExpanded/wiki/Installation) 30 | 31 | ### ***Crashes on startup!*** 32 | READ [Installation](https://github.com/R-Vaccari/BannerKings.CulturesExpanded/wiki/Installation) 33 | 34 | ### ***No image for cultures on character creation!*** 35 | READ [Installation](https://github.com/R-Vaccari/BannerKings.CulturesExpanded/wiki/Installation) 36 | 37 | ### ***I have an issue!*** 38 | READ [Installation](https://github.com/R-Vaccari/BannerKings.CulturesExpanded/wiki/Installation) 39 | 40 | ### ***I have read the installation and followed as steps exactly as described, but it still does not solve my issue. What to do?*** 41 | BKCE support is the same as support for Banner Kings. Instructions on BK support are here: [BK: Bug Reporting](https://github.com/R-Vaccari/bannerlord-banner-kings?tab=readme-ov-file#bug-reporting) 42 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEPartyMorale.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.CulturesExpanded.Religions; 3 | using BannerKings.Models.Vanilla; 4 | using TaleWorlds.CampaignSystem; 5 | using TaleWorlds.CampaignSystem.Party; 6 | using TaleWorlds.Core; 7 | 8 | namespace BannerKings.CulturesExpanded.Models 9 | { 10 | public class BKCEPartyMorale : BKPartyMoraleModel 11 | { 12 | public override ExplainedNumber GetEffectivePartyMorale(MobileParty mobileParty, bool includeDescription = false) 13 | { 14 | ExplainedNumber result = base.GetEffectivePartyMorale(mobileParty, includeDescription); 15 | 16 | if (mobileParty.LeaderHero != null) 17 | { 18 | Hero leader = mobileParty.LeaderHero; 19 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Ireos)) 20 | { 21 | float proportion = 0f; 22 | foreach (var element in mobileParty.MemberRoster.GetTroopRoster()) 23 | { 24 | if (element.Character.Culture.StringId == BannerKingsConfig.EmpireCulture) 25 | { 26 | proportion += element.Number; 27 | } 28 | } 29 | 30 | proportion = proportion / (float)mobileParty.MemberRoster.TotalManCount; 31 | result.Add(15f * proportion, BKCEDivinities.Instance.Ireos.Name); 32 | } 33 | 34 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.VineGoddess)) 35 | { 36 | result.Add(8f, BKCEDivinities.Instance.VineGoddess.Name); 37 | } 38 | } 39 | 40 | if (mobileParty.IsLordParty) 41 | { 42 | if (mobileParty.ActualClan.Culture.HasFeat(BKCEFeats.Instance.SailingSpeed) && 43 | TaleWorlds.CampaignSystem.Campaign.Current.MapSceneWrapper.GetFaceTerrainType(mobileParty.CurrentNavigationFace) == TerrainType.Swamp) 44 | { 45 | result.Add(-12f, new TaleWorlds.Localization.TextObject("{=!}Sailing")); 46 | } 47 | } 48 | 49 | return result; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Behaviors/CrownGuardBehavior.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Behaviours; 2 | using BannerKings.CulturesExpanded.Cultures; 3 | using BannerKings.CulturesExpanded.Goals; 4 | using System.Collections.Generic; 5 | using TaleWorlds.CampaignSystem; 6 | 7 | namespace BannerKings.CulturesExpanded.Behaviors 8 | { 9 | public class CrownGuardBehavior : BannerKingsBehavior 10 | { 11 | private Dictionary kingdoms = new Dictionary(6); 12 | 13 | public bool IsTimeReady(Kingdom kingdom) => !kingdoms.ContainsKey(kingdom) || kingdoms[kingdom].ElapsedYearsUntilNow >= 5f; 14 | public void SetTime(Kingdom kingdom) => kingdoms[kingdom] = CampaignTime.Now; 15 | 16 | public CharacterObject GetKingdomTroop(Kingdom kingdom) 17 | { 18 | if (kingdom.StringId == "empire") return TaleWorlds.CampaignSystem.Campaign.Current.ObjectManager.GetObject("bk_laconian_guard"); 19 | if (kingdom.Culture.StringId == "battania") return TaleWorlds.CampaignSystem.Campaign.Current.ObjectManager.GetObject("bk_battanian_teulu"); 20 | if (kingdom.Culture.StringId == "khuzait") return TaleWorlds.CampaignSystem.Campaign.Current.ObjectManager.GetObject("bk_khuzait_glaiveman"); 21 | return null; 22 | } 23 | 24 | public override void RegisterEvents() 25 | { 26 | CampaignEvents.WeeklyTickEvent.AddNonSerializedListener(this, OnWeeklyTick); 27 | CampaignEvents.OnSessionLaunchedEvent.AddNonSerializedListener(this, (CampaignGameStarter starter) => BKCEFeats.Instance.UpdateVanilla()); 28 | } 29 | 30 | public override void SyncData(IDataStore dataStore) 31 | { 32 | dataStore.SyncData("bkto_crown_guard_timer", ref kingdoms); 33 | if (kingdoms == null) kingdoms = new Dictionary(6); 34 | } 35 | 36 | private void OnWeeklyTick() 37 | { 38 | foreach (var kingdom in Kingdom.All) 39 | { 40 | if (kingdom.IsEliminated) continue; 41 | 42 | Hero ruler = kingdom.RulingClan.Leader; 43 | if (ruler == Hero.MainHero) continue; 44 | 45 | CrownGuardGoal goal = new CrownGuardGoal(ruler); 46 | goal.DoAiDecision(); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEPartySpeedModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Models.Vanilla; 2 | using TaleWorlds.CampaignSystem.Party; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.Core; 5 | using TaleWorlds.Localization; 6 | using BannerKings.Settings; 7 | using BannerKings.CulturesExpanded.Cultures; 8 | using TaleWorlds.CampaignSystem.ComponentInterfaces; 9 | using Helpers; 10 | 11 | namespace BannerKings.CulturesExpanded.Models 12 | { 13 | public class BKCEPartySpeedModel : BKPartySpeedModel 14 | { 15 | public override ExplainedNumber CalculateFinalSpeed(MobileParty mobileParty, ExplainedNumber finalSpeed) 16 | { 17 | if (TaleWorlds.CampaignSystem.Campaign.Current.MapSceneWrapper.GetFaceTerrainType(mobileParty.CurrentNavigationFace) == TerrainType.Swamp) 18 | { 19 | bool description = mobileParty.ActualClan == Clan.PlayerClan; 20 | ExplainedNumber speed = new ExplainedNumber(2f, description); 21 | 22 | if (mobileParty.Army != null) speed.AddFactor(-0.2f, new TextObject("{=!}Sailing army")); 23 | else if (mobileParty.IsCaravan) speed.AddFactor(0.12f, new TextObject("{=!}Sailing caravan")); 24 | 25 | Utils.Helpers.ApplyFeat(BKCEFeats.Instance.SailingSpeed, mobileParty.Party, ref speed); 26 | if (BannerKingsSettings.Instance.SlowerParties > 0f) 27 | { 28 | speed.AddFactor(-BannerKingsSettings.Instance.SlowerParties, new TextObject("{=OohdenyR}Slower Parties setting")); 29 | } 30 | 31 | return speed; 32 | } 33 | 34 | ExplainedNumber newFinalSpeed = base.CalculateFinalSpeed(mobileParty, finalSpeed); 35 | 36 | if (PartyBaseHelper.HasFeat(mobileParty.Party, BKCEFeats.Instance.Vakken2)) 37 | { 38 | MapWeatherModel.WeatherEvent weatherEventInPosition = TaleWorlds.CampaignSystem.Campaign.Current.Models.MapWeatherModel 39 | .GetWeatherEventInPosition(mobileParty.Position2D); 40 | if (weatherEventInPosition == MapWeatherModel.WeatherEvent.Snowy || weatherEventInPosition == MapWeatherModel.WeatherEvent.Blizzard) 41 | { 42 | finalSpeed.AddFactor(0.1f, GameTexts.FindText("str_culture")); 43 | } 44 | } 45 | 46 | return newFinalSpeed; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/Characters/lords.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/spclans.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Legio Ulterior 11 | 12 | 13 | 14 | Legio Ulterior 15 | 16 | 17 | 18 | Crwyn Bleiddiaid 19 | 20 | 21 | 22 | Culture.rhodok 23 | 24 | 25 | 26 | Culture.rhodok 27 | 28 | 29 | 30 | 31 | daz Arromanc 32 | 33 | 34 | 35 | daz Rothad 36 | 37 | 38 | 39 | 40 | Culture.swadia 41 | 42 | 43 | 44 | Culture.swadia 45 | 46 | 47 | 48 | Culture.swadia 49 | 50 | 51 | 52 | 53 | des Gunric 54 | 55 | 56 | 57 | des Fortes 58 | 59 | 60 | 61 | des Jelind 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCETaxModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.Managers.Policies; 3 | using BannerKings.Managers.Populations; 4 | using BannerKings.Managers.Titles; 5 | using BannerKings.Models.Vanilla; 6 | 7 | namespace BannerKings.CulturesExpanded.Models 8 | { 9 | public class BKCETaxModel : BKTaxModel 10 | { 11 | public override float GetSlaveTaxRate(FeudalTitle title, PopulationData data, BKTaxPolicy policy) 12 | { 13 | float result = base.GetSlaveTaxRate(title, data, policy); 14 | if (data.Settlement.Culture.HasFeat(BKCEFeats.Instance.Geroia2)) 15 | { 16 | result *= 1f - BKCEFeats.Instance.Geroia2.EffectBonus; 17 | } 18 | 19 | return result; 20 | } 21 | 22 | public override float GetNobleTaxRate(FeudalTitle title, PopulationData data, BKTaxPolicy policy) 23 | { 24 | float result = base.GetSlaveTaxRate(title, data, policy); 25 | if (data.Settlement.Culture.HasFeat(BKCEFeats.Instance.Geroia2)) 26 | { 27 | result *= 1f + BKCEFeats.Instance.Geroia2.EffectBonus; 28 | } 29 | 30 | return result; 31 | } 32 | 33 | public override float GetSerfTaxRate(FeudalTitle title, PopulationData data, BKTaxPolicy policy) 34 | { 35 | float result = base.GetSlaveTaxRate(title, data, policy); 36 | if (data.Settlement.Culture.HasFeat(BKCEFeats.Instance.Geroia2)) 37 | { 38 | result *= 1f + BKCEFeats.Instance.Geroia2.EffectBonus; 39 | } 40 | 41 | return result; 42 | } 43 | 44 | public override float GetTenantTaxRate(FeudalTitle title, PopulationData data, BKTaxPolicy policy) 45 | { 46 | float result = base.GetSlaveTaxRate(title, data, policy); 47 | if (data.Settlement.Culture.HasFeat(BKCEFeats.Instance.Geroia2)) 48 | { 49 | result *= 1f + BKCEFeats.Instance.Geroia2.EffectBonus; 50 | } 51 | 52 | return result; 53 | } 54 | 55 | public override float GetCraftsmenTaxRate(FeudalTitle title, PopulationData data, BKTaxPolicy policy) 56 | { 57 | float result = base.GetSlaveTaxRate(title, data, policy); 58 | if (data.Settlement.Culture.HasFeat(BKCEFeats.Instance.Geroia2)) 59 | { 60 | result *= 1f + BKCEFeats.Instance.Geroia2.EffectBonus; 61 | } 62 | 63 | return result; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Behaviors/FeatBehavior.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Behaviours; 2 | using BannerKings.CulturesExpanded.Cultures; 3 | using BannerKings.Extensions; 4 | using System.Collections.Generic; 5 | using TaleWorlds.CampaignSystem; 6 | using TaleWorlds.CampaignSystem.Actions; 7 | using TaleWorlds.CampaignSystem.Party; 8 | using TaleWorlds.CampaignSystem.Settlements; 9 | using TaleWorlds.Library; 10 | using TaleWorlds.Localization; 11 | 12 | namespace BannerKings.CulturesExpanded.Behaviors 13 | { 14 | public class FeatBehavior : BannerKingsBehavior 15 | { 16 | public override void RegisterEvents() 17 | { 18 | CampaignEvents.OnSiegeAftermathAppliedEvent.AddNonSerializedListener(this, OnSiegeAftermath); 19 | } 20 | 21 | public override void SyncData(IDataStore dataStore) 22 | { 23 | } 24 | 25 | private void OnSiegeAftermath(MobileParty attackerParty, Settlement settlement, 26 | SiegeAftermathAction.SiegeAftermath aftermathType, 27 | Clan previousSettlementOwner, 28 | Dictionary partyContributions) 29 | { 30 | if (aftermathType == SiegeAftermathAction.SiegeAftermath.ShowMercy) return; 31 | 32 | if (attackerParty.LeaderHero != null && attackerParty.LeaderHero.Culture.HasFeat(BKCEFeats.Instance.Massa1)) 33 | { 34 | var data = settlement.PopulationData(); 35 | if (data != null) 36 | { 37 | float gold = data.TotalPop; 38 | foreach (var pair in partyContributions) 39 | { 40 | Hero leader = pair.Key.LeaderHero; 41 | if (leader != null) 42 | { 43 | int bonus = (int)(gold * pair.Value); 44 | leader.ChangeHeroGold(bonus); 45 | 46 | if (leader == Hero.MainHero) 47 | { 48 | InformationManager.DisplayMessage(new InformationMessage( 49 | new TextObject("{=!}{GOLD}{GOLD_ICON} extra from the pillaging of {TOWN} due to the culture of {LEADER}.") 50 | .SetTextVariable("LEADER", attackerParty.LeaderHero.Name) 51 | .SetTextVariable("TOWN", settlement.Name) 52 | .SetTextVariable("GOLD", bonus) 53 | .ToString())); 54 | } 55 | } 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEVillageProductionModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Campaign; 2 | using BannerKings.CulturesExpanded.Cultures; 3 | using BannerKings.Extensions; 4 | using BannerKings.Managers.Items; 5 | using BannerKings.Models.Vanilla; 6 | using TaleWorlds.CampaignSystem; 7 | using TaleWorlds.CampaignSystem.Settlements; 8 | using TaleWorlds.Core; 9 | 10 | namespace BannerKings.CulturesExpanded.Models 11 | { 12 | public class BKCEVillageProductionModel : BKVillageProductionModel 13 | { 14 | public override float CalculateDailyProductionAmount(Village village, ItemObject item) 15 | { 16 | float result = base.CalculateDailyProductionAmount(village, item); 17 | Hero owner = village.Settlement.OwnerClan.Leader; 18 | ItemCategory category = item.ItemCategory; 19 | 20 | if (owner.Culture.HasFeat(BKCEFeats.Instance.SouthernAgriculture)) 21 | { 22 | if (category == DefaultItemCategories.Grain || category == BKItemCategories.Instance.Papyrus || 23 | category == DefaultItemCategories.DateFruit) 24 | { 25 | result *= 1f + BKCEFeats.Instance.SouthernAgriculture.EffectBonus; 26 | } 27 | } 28 | 29 | if (owner.Culture.HasFeat(BKCEFeats.Instance.Bragantia1)) 30 | { 31 | if (category == DefaultItemCategories.Cow || category == DefaultItemCategories.Grape || 32 | category == DefaultItemCategories.Olives) 33 | { 34 | result *= 1f + BKCEFeats.Instance.Bragantia1.EffectBonus; 35 | } 36 | } 37 | 38 | if (owner.Culture.HasFeat(BKCEFeats.Instance.Vakken1)) 39 | { 40 | if (category == DefaultItemCategories.Fur || category == DefaultItemCategories.Wood || 41 | category == BKItemCategories.Instance.Honey) 42 | { 43 | result *= 1f + BKCEFeats.Instance.Vakken1.EffectBonus; 44 | } 45 | } 46 | 47 | if (owner.Culture.HasFeat(BKCEFeats.Instance.Vakken3)) 48 | { 49 | if (village.IsFarmingVillage() || village.IsAnimalVillage()) 50 | { 51 | result *= 1f + BKCEFeats.Instance.Vakken3.EffectBonus; 52 | } 53 | } 54 | 55 | if (owner.Culture.HasFeat(BKCEFeats.Instance.Iltanlar1)) 56 | { 57 | if (village.IsMiningVillage() || village.VillageType == BKVillageTypes.Instance.Limestone || 58 | village.VillageType == BKVillageTypes.Instance.Marble) 59 | { 60 | result *= 1f + BKCEFeats.Instance.Iltanlar1.EffectBonus; 61 | } 62 | } 63 | 64 | return result; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/BannerKings.CulturesExpanded.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.8.0 5 | net481 6 | x64 7 | 9.0 8 | disable 9 | $(MSBuildProjectName) 10 | $(MSBuildProjectName) 11 | $(BANNERLORD_GAME_DIR) 12 | false 13 | C:\Program Files (x86)\Steam\steamapps\common\Mount & Blade II Bannerlord\Modules\BannerKings.CulturesExpanded\bin\Win64_Shipping_Client 14 | 15 | 16 | 17 | embedded 18 | 19 | 20 | 21 | embedded 22 | 23 | 24 | 25 | 26 | %(Identity) 27 | False 28 | 29 | 30 | %(Identity) 31 | False 32 | 33 | 34 | %(Identity) 35 | False 36 | 37 | 38 | %(Identity) 39 | False 40 | 41 | 42 | %(Identity) 43 | False 44 | 45 | 46 | %(Identity) 47 | False 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/CC/BKCEGameManager.cs: -------------------------------------------------------------------------------- 1 | using SandBox; 2 | using System; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.CharacterCreationContent; 5 | using TaleWorlds.CampaignSystem.Encounters; 6 | using TaleWorlds.CampaignSystem.GameState; 7 | using TaleWorlds.CampaignSystem.Party; 8 | using TaleWorlds.CampaignSystem.Settlements; 9 | using TaleWorlds.ModuleManager; 10 | using TaleWorlds.MountAndBlade; 11 | using TaleWorlds.SaveSystem.Load; 12 | 13 | namespace BannerKings.CulturesExpanded.CC 14 | { 15 | internal class BKCEGameManager : SandBoxGameManager 16 | { 17 | private bool _loadingSavedGame; 18 | private LoadResult _loadedGameResult; 19 | 20 | public BKCEGameManager() 21 | { 22 | _loadingSavedGame = false; 23 | } 24 | 25 | public BKCEGameManager(LoadResult loadedGameResult) 26 | { 27 | _loadingSavedGame = true; 28 | _loadedGameResult = loadedGameResult; 29 | } 30 | 31 | public override void OnLoadFinished() 32 | { 33 | if (!this._loadingSavedGame) 34 | { 35 | if (!TaleWorlds.Core.Game.Current.IsDevelopmentMode) 36 | { 37 | VideoPlaybackState videoPlaybackState = TaleWorlds.Core.Game.Current.GameStateManager.CreateState(); 38 | string str = ModuleHelper.GetModuleFullPath("SandBox") + "Videos/CampaignIntro/"; 39 | string subtitleFileBasePath = str + "campaign_intro"; 40 | string videoPath = str + "campaign_intro.ivf"; 41 | string audioPath = str + "campaign_intro.ogg"; 42 | videoPlaybackState.SetStartingParameters(videoPath, audioPath, subtitleFileBasePath, 30f, true); 43 | videoPlaybackState.SetOnVideoFinisedDelegate(new Action(this.LaunchSandboxCharacterCreation)); 44 | TaleWorlds.Core.Game.Current.GameStateManager.CleanAndPushState(videoPlaybackState, 0); 45 | } 46 | else 47 | { 48 | this.LaunchSandboxCharacterCreation(); 49 | } 50 | } 51 | else 52 | { 53 | TaleWorlds.Core.Game.Current.GameStateManager.OnSavedGameLoadFinished(); 54 | TaleWorlds.Core.Game.Current.GameStateManager.CleanAndPushState(TaleWorlds.Core.Game.Current.GameStateManager.CreateState(), 0); 55 | MapState mapState = TaleWorlds.Core.Game.Current.GameStateManager.ActiveState as MapState; 56 | string text = (mapState != null) ? mapState.GameMenuId : null; 57 | if (!string.IsNullOrEmpty(text)) 58 | { 59 | PlayerEncounter playerEncounter = PlayerEncounter.Current; 60 | if (playerEncounter != null) 61 | { 62 | playerEncounter.OnLoad(); 63 | } 64 | TaleWorlds.CampaignSystem.Campaign.Current.GameMenuManager.SetNextMenu(text); 65 | } 66 | PartyBase.MainParty.SetVisualAsDirty(); 67 | TaleWorlds.CampaignSystem.Campaign.Current.CampaignInformationManager.OnGameLoaded(); 68 | foreach (Settlement settlement in Settlement.All) 69 | { 70 | settlement.Party.SetLevelMaskIsDirty(); 71 | } 72 | CampaignEventDispatcher.Instance.OnGameLoadFinished(); 73 | if (mapState != null) 74 | { 75 | mapState.OnLoadingFinished(); 76 | } 77 | } 78 | base.IsLoaded = true; 79 | } 80 | 81 | private void LaunchSandboxCharacterCreation() 82 | { 83 | CharacterCreationState gameState = TaleWorlds.Core.Game.Current.GameStateManager.CreateState(new object[] 84 | { 85 | new BKCECreationContent() 86 | }); 87 | TaleWorlds.Core.Game.Current.GameStateManager.CleanAndPushState(gameState, 0); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Cultures/BKCEShippingLanes.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Shipping; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | using TaleWorlds.Localization; 6 | 7 | namespace BannerKings.CulturesExpanded.Cultures 8 | { 9 | public class BKCEShippingLanes : DefaultTypeInitializer 10 | { 11 | public ShippingLane Balion { get; } = new ShippingLane("Balion"); 12 | public ShippingLane Darshi { get; } = new ShippingLane("Darshi"); 13 | public override IEnumerable All 14 | { 15 | get 16 | { 17 | yield return Balion; 18 | yield return Darshi; 19 | } 20 | } 21 | 22 | public override void Initialize() 23 | { 24 | Balion.Initialize(new TextObject("{=!}Balion Trade Connection"), 25 | new TextObject(), 26 | new List() 27 | { 28 | Settlement.All.First(x => x.StringId == "town_Isles"), 29 | Settlement.All.First(x => x.StringId == "castle_Isles"), 30 | Settlement.All.First(x => x.StringId == "town_V4") 31 | }, 32 | false, 33 | Utils.Helpers.GetCulture("balion")); 34 | 35 | Darshi.Initialize(new TextObject("{=!}Darshi Sea Network"), 36 | new TextObject(), 37 | new List() 38 | { 39 | Settlement.All.First(x => x.StringId == "town_Darshi_4"), 40 | Settlement.All.First(x => x.StringId == "town_Darshi_1"), 41 | Settlement.All.First(x => x.StringId == "castle_Darshi_5") 42 | }); 43 | 44 | DefaultShippingLanes.Instance.Western.Initialize(new TextObject("{=tySxydya}Western Sea Network"), 45 | new TextObject(), 46 | new List() 47 | { 48 | Settlement.All.First(x => x.StringId == "town_Isles"), 49 | Settlement.All.First(x => x.StringId == "castle_Isles"), 50 | Settlement.All.First(x => x.StringId == "town_Massa_1"), 51 | Settlement.All.First(x => x.StringId == "town_Massa_2"), 52 | Settlement.All.First(x => x.StringId == "town_Kanic_1"), 53 | Settlement.All.First(x => x.StringId == "town_V4"), 54 | Settlement.All.First(x => x.StringId == "town_V7"), 55 | Settlement.All.First(x => x.StringId == "town_V8") 56 | }); 57 | 58 | DefaultShippingLanes.Instance.Junme.Initialize(new TextObject("{=FGXR8tdb}Junme Trade Network"), 59 | new TextObject(), 60 | new List() 61 | { 62 | Settlement.All.First(x => x.StringId == "town_Tihr"), 63 | Settlement.All.First(x => x.StringId == "town_V11"), 64 | Settlement.All.First(x => x.StringId == "castle_village_Jumne_1_1"), 65 | Settlement.All.First(x => x.StringId == "castle_S7"), 66 | Settlement.All.First(x => x.StringId == "town_S2"), 67 | Settlement.All.First(x => x.StringId == "town_V8") 68 | }, 69 | false, 70 | Utils.Helpers.GetCulture("nord")); 71 | 72 | DefaultShippingLanes.Instance.Perassic.Initialize(new TextObject("{=TFoGRBnG}Perassic Trade Network"), 73 | new TextObject(), 74 | new List() 75 | { 76 | Settlement.All.First(x => x.StringId == "town_ES2"), 77 | Settlement.All.First(x => x.StringId == "town_A4"), 78 | Settlement.All.First(x => x.StringId == "town_A8"), 79 | Settlement.All.First(x => x.StringId == "town_EW2"), 80 | Settlement.All.First(x => x.StringId == "town_EW4"), 81 | Settlement.All.First(x => x.StringId == "town_A1"), 82 | Settlement.All.First(x => x.StringId == "town_Geroia_1"), 83 | Settlement.All.First(x => x.StringId == "town_Geroia_2"), 84 | Settlement.All.First(x => x.StringId == "town_Geroia_3"), 85 | Settlement.All.First(x => x.StringId == "town_A6") 86 | }); 87 | 88 | foreach (var l in All) 89 | { 90 | DefaultShippingLanes.Instance.AddObject(l); 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/heroes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Models/BKCEProsperityModel.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Cultures; 2 | using BannerKings.CulturesExpanded.Religions; 3 | using BannerKings.Extensions; 4 | using BannerKings.Managers.Institutions.Religions; 5 | using BannerKings.Models.Vanilla; 6 | using TaleWorlds.CampaignSystem; 7 | using TaleWorlds.CampaignSystem.Settlements; 8 | 9 | namespace BannerKings.CulturesExpanded.Models 10 | { 11 | public class BKCEProsperityModel : BKProsperityModel 12 | { 13 | public override ExplainedNumber CalculateProsperityChange(Town fortification, bool includeDescriptions = false) 14 | { 15 | ExplainedNumber result = base.CalculateProsperityChange(fortification, includeDescriptions); 16 | if (fortification.OwnerClan != null) 17 | { 18 | Hero leader = fortification.OwnerClan.Leader; 19 | if (fortification.Culture.StringId == BannerKingsConfig.EmpireCulture && 20 | BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Erithrians)) 21 | { 22 | result.Add(0.5f, BKCEDivinities.Instance.Erithrians.Name); 23 | } 24 | 25 | if (fortification.Culture.StringId == "kannic" && 26 | BannerKingsConfig.Instance.ReligionsManager.HasBlessing(leader, BKCEDivinities.Instance.Eshora)) 27 | { 28 | result.Add(0.5f, BKCEDivinities.Instance.Eshora.Name); 29 | } 30 | } 31 | 32 | Utils.Helpers.ApplyFeat(BKCEFeats.Instance.Massa2, fortification.Owner, ref result); 33 | return result; 34 | } 35 | 36 | public override ExplainedNumber CalculateHearthChange(Village village, bool includeDescriptions = false) 37 | { 38 | ExplainedNumber baseResult = base.CalculateHearthChange(village, includeDescriptions); 39 | 40 | var owner = village.GetActualOwner(); 41 | var rel = BannerKingsConfig.Instance.ReligionsManager.GetHeroReligion(owner); 42 | 43 | if (rel != null) 44 | { 45 | if ((village.VillageType == DefaultVillageTypes.DateFarm || village.VillageType == DefaultVillageTypes.DesertHorseRanch) 46 | && BannerKingsConfig.Instance.ReligionsManager.HasBlessing(owner, DefaultDivinities.Instance.AseraSecondary3, rel)) 47 | { 48 | baseResult.Add(0.1f, DefaultDivinities.Instance.AseraSecondary3.Name); 49 | } 50 | 51 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(owner, DefaultDivinities.Instance.AmraMain, rel) 52 | && (village.VillageType == DefaultVillageTypes.HogFarm || village.VillageType == DefaultVillageTypes.CattleRange || 53 | village.VillageType == DefaultVillageTypes.Lumberjack)) 54 | { 55 | baseResult.Add(0.2f, DefaultDivinities.Instance.AmraMain.Name); 56 | } 57 | 58 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(owner, DefaultDivinities.Instance.Mehns, rel)) 59 | { 60 | if (rel.FavoredCultures.Contains(village.Settlement.Culture)) 61 | { 62 | baseResult.Add(0.08f, DefaultDivinities.Instance.Mehns.Name); 63 | } 64 | } 65 | 66 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(owner, DefaultDivinities.Instance.Horsa, rel)) 67 | { 68 | baseResult.Add(0.05f, DefaultDivinities.Instance.Horsa.Name); 69 | } 70 | 71 | if (BannerKingsConfig.Instance.ReligionsManager.HasBlessing(owner, DefaultDivinities.Instance.WindEast, rel)) 72 | { 73 | baseResult.Add(0.05f, DefaultDivinities.Instance.WindEast.Name); 74 | } 75 | 76 | if (village.Settlement.Culture.StringId == "kannic" && 77 | BannerKingsConfig.Instance.ReligionsManager.HasBlessing(owner, BKCEDivinities.Instance.Jinn, rel)) 78 | { 79 | baseResult.Add(0.06f, BKCEDivinities.Instance.Jinn.Name); 80 | } 81 | 82 | if (village.Settlement.Culture.StringId == "siri" && 83 | BannerKingsConfig.Instance.ReligionsManager.HasBlessing(owner, BKCEDivinities.Instance.SiriRam, rel) && 84 | (village.IsAnimalVillage() || village.IsFarmingVillage())) 85 | { 86 | baseResult.Add(0.1f, BKCEDivinities.Instance.SiriRam.Name); 87 | } 88 | } 89 | 90 | return baseResult; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Cultures/BKCEMarketGroups.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Campaign.Economy.Markets; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using TaleWorlds.CampaignSystem; 5 | 6 | namespace BannerKings.CulturesExpanded.Cultures 7 | { 8 | public class BKCEMarketGroups : DefaultTypeInitializer 9 | { 10 | public MarketGroup SiriGroup = new MarketGroup("siri"); 11 | public MarketGroup MassaGroup = new MarketGroup("massa"); 12 | public MarketGroup NordGroup = new MarketGroup("nord"); 13 | public MarketGroup VakkenGroup = new MarketGroup("vakken"); 14 | public MarketGroup BragantiaGroup = new MarketGroup("bragantia"); 15 | public MarketGroup KannicGroup = new MarketGroup("kannic"); 16 | public MarketGroup DarshiGroup = new MarketGroup("darshi"); 17 | public MarketGroup GeroiaGroup = new MarketGroup("geroia"); 18 | 19 | public override IEnumerable All 20 | { 21 | get 22 | { 23 | yield return SiriGroup; 24 | yield return MassaGroup; 25 | yield return NordGroup; 26 | yield return VakkenGroup; 27 | yield return BragantiaGroup; 28 | yield return KannicGroup; 29 | yield return DarshiGroup; 30 | yield return GeroiaGroup; 31 | } 32 | } 33 | 34 | public override void Initialize() 35 | { 36 | var cultures = TaleWorlds.CampaignSystem.Campaign.Current.ObjectManager.GetObjectTypeList(); 37 | var siri = cultures.First(x => x.StringId == "siri"); 38 | var nord = cultures.First(x => x.StringId == "nord"); 39 | var vakken = cultures.First(x => x.StringId == "vakken"); 40 | var massa = cultures.First(x => x.StringId == "massa"); 41 | var aserai = cultures.First(x => x.StringId == "aserai"); 42 | var vlandia = cultures.First(x => x.StringId == "vlandia"); 43 | var empire = cultures.First(x => x.StringId == "empire"); 44 | var sturgia = cultures.First(x => x.StringId == "sturgia"); 45 | var kannic = cultures.First(x => x.StringId == "kannic"); 46 | var darshi = cultures.First(x => x.StringId == "darshi"); 47 | var khuzait = cultures.First(x => x.StringId == "khuzait"); 48 | var geroia = cultures.First(x => x.StringId == "geroia"); 49 | var bragantia = cultures.First(x => x.StringId == "bragantia"); 50 | 51 | GeroiaGroup.Initialize(null, 52 | null, 53 | geroia, 54 | new Dictionary 55 | { 56 | { aserai, 0.2f }, 57 | { empire, 0.8f } 58 | }); 59 | 60 | KannicGroup.Initialize(null, 61 | null, 62 | kannic, 63 | new Dictionary 64 | { 65 | { aserai, 0.5f } 66 | }); 67 | 68 | DarshiGroup.Initialize(null, 69 | null, 70 | darshi, 71 | new Dictionary 72 | { 73 | { aserai, 0.2f }, 74 | { khuzait, 0.2f } 75 | }); 76 | 77 | SiriGroup.Initialize(null, 78 | null, 79 | siri, 80 | new Dictionary 81 | { 82 | { aserai, 0.4f } 83 | }); 84 | 85 | MassaGroup.Initialize(null, 86 | null, 87 | massa, 88 | new Dictionary 89 | { 90 | { vlandia, 0.8f } 91 | }); 92 | 93 | BragantiaGroup.Initialize(null, 94 | null, 95 | bragantia, 96 | new Dictionary 97 | { 98 | { vlandia, 0.6f }, 99 | { empire, 0.4f } 100 | }); 101 | 102 | NordGroup.Initialize(null, 103 | null, 104 | nord, 105 | new Dictionary 106 | { 107 | { vlandia, 0.2f }, 108 | { sturgia, 0.8f } 109 | }); 110 | 111 | VakkenGroup.Initialize(null, 112 | null, 113 | vakken, 114 | new Dictionary 115 | { 116 | { sturgia, 0.8f }, 117 | { nord, 0.2f } 118 | }); 119 | 120 | foreach (var group in All) 121 | { 122 | DefaultMarketGroups.Instance.AddObject(group); 123 | } 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Main.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Behaviors; 2 | using BannerKings.CulturesExpanded.Cultures; 3 | using BannerKings.CulturesExpanded.Goals; 4 | using BannerKings.CulturesExpanded.Models; 5 | using BannerKings.CulturesExpanded.Religions; 6 | using System; 7 | using TaleWorlds.CampaignSystem; 8 | using TaleWorlds.Core; 9 | using TaleWorlds.Library; 10 | using TaleWorlds.Localization; 11 | using TaleWorlds.MountAndBlade; 12 | using System.Collections.Generic; 13 | using System.Linq; 14 | using BannerKings.CulturesExpanded.CC; 15 | using HarmonyLib; 16 | using BannerKings.Managers.Recruits; 17 | 18 | namespace BannerKings.CulturesExpanded 19 | { 20 | public class Main : MBSubModuleBase 21 | { 22 | protected override void OnGameStart(Game game, IGameStarter gameStarter) 23 | { 24 | base.OnGameStart(game, gameStarter); 25 | if (gameStarter is not CampaignGameStarter campaignStarter) 26 | { 27 | return; 28 | } 29 | 30 | campaignStarter.AddBehavior(new CrownGuardBehavior()); 31 | campaignStarter.AddBehavior(new FeatBehavior()); 32 | //campaignStarter.AddBehavior(new DryaticBehavior()); 33 | 34 | campaignStarter.AddModel(new BKCEInfluenceModel()); 35 | campaignStarter.AddModel(new BKCELoyaltyModel()); 36 | campaignStarter.AddModel(new BKCEProsperityModel()); 37 | campaignStarter.AddModel(new BKCEVolunteerModel()); 38 | campaignStarter.AddModel(new BKCEPartySpeedModel()); 39 | campaignStarter.AddModel(new BKCEDeathModel()); 40 | campaignStarter.AddModel(new BKCEPartyHealingModel()); 41 | campaignStarter.AddModel(new BKCEPartyMorale()); 42 | campaignStarter.AddModel(new BKCEPriceModel()); 43 | campaignStarter.AddModel(new BKCESecurityModel()); 44 | campaignStarter.AddModel(new BKCETaxModel()); 45 | campaignStarter.AddModel(new BKCETroopUpgradeModel()); 46 | campaignStarter.AddModel(new BKCEVillageProductionModel()); 47 | campaignStarter.AddModel(new BKCEEconomyModel()); 48 | campaignStarter.AddModel(new BKCEMilitiaModel()); 49 | campaignStarter.AddModel(new BKCERaidModel()); 50 | campaignStarter.AddModel(new BKCEPartyWageModel()); 51 | campaignStarter.AddModel(new BKCEBattleSimulationModel()); 52 | campaignStarter.AddModel(new BKCEPartyFoodModel()); 53 | campaignStarter.AddModel(new BKCEEquipmentModel()); 54 | 55 | BannerKingsConfig.Instance.AddInitializer(BKCERecruitSpawns.Instance); 56 | BannerKingsConfig.Instance.AddInitializer(BKCEPopulationNames.Instance); 57 | BannerKingsConfig.Instance.AddInitializer(BKCETitleNames.Instance); 58 | BannerKingsConfig.Instance.AddInitializer(BKTOGoals.Instance); 59 | BannerKingsConfig.Instance.AddInitializer(BKCEDivinities.Instance); 60 | BannerKingsConfig.Instance.AddInitializer(BKCEFaithGroups.Instance); 61 | BannerKingsConfig.Instance.AddInitializer(BKCEFaiths.Instance); 62 | BannerKingsConfig.Instance.AddInitializer(BKCEReligions.Instance); 63 | BannerKingsConfig.Instance.AddInitializer(BKCELanguages.Instance); 64 | BannerKingsConfig.Instance.AddInitializer(BKCEMarketGroups.Instance); 65 | BannerKingsConfig.Instance.AddInitializer(BKCEShippingLanes.Instance); 66 | 67 | BannerKingsConfig.Instance.CultureModel = new BKCECultureModel(); 68 | BannerKingsConfig.Instance.ReligionModel = new BKCEReligionModel(); 69 | BannerKingsConfig.Instance.LegitimacyModel = new BKCELegitimacyModel(); 70 | BannerKingsConfig.Instance.GrowthModel = new BKCEGrowthModel(); 71 | 72 | BKCEFeats.Instance.Initialize(); 73 | BannerKingsConfig.Instance.TitlesGeneratorPath = BasePath.Name + "Modules/BannerKings.CulturesExpanded/ModuleData/titles.xml"; 74 | BannerKingsConfig.Instance.RecruitsXmlPath = BasePath.Name + "Modules/BannerKings.CulturesExpanded/ModuleData/recruits.xml"; 75 | } 76 | 77 | protected override void OnSubModuleLoad() 78 | { 79 | new Harmony("BannerKings.CulturesExpanded").PatchAll(); 80 | List _initialStateOptions = (List)Module.CurrentModule.GetType() 81 | .GetField("_initialStateOptions", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) 82 | .GetValue(Module.CurrentModule); 83 | 84 | InitialStateOption story = _initialStateOptions.First(x => x.Id == "StoryModeNewGame"); 85 | InitialStateOption sb = _initialStateOptions.First(x => x.Id == "SandBoxNewGame"); 86 | 87 | if (story != null) _initialStateOptions.Remove(story); 88 | if (sb != null) _initialStateOptions.Remove(sb); 89 | 90 | Module.CurrentModule.AddInitialStateOption(new InitialStateOption("BKCE", new TextObject("{=!}Banner Kings", null), 3, delegate () 91 | { 92 | MBGameManager.StartNewGame(new BKCEGameManager()); 93 | }, () => new ValueTuple(Module.CurrentModule.IsOnlyCoreContentEnabled, new TextObject("{=V8BXjyYq}Disabled during installation.")))); 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/BKCEReligions.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions; 2 | using System.Collections.Generic; 3 | using TaleWorlds.CampaignSystem; 4 | 5 | namespace BannerKings.CulturesExpanded.Religions 6 | { 7 | public class BKCEReligions : DefaultTypeInitializer 8 | { 9 | public Religion ImmortalFlame { get; } = new Religion("atash"); 10 | public Religion Calradism { get; } = new Religion("calradian"); 11 | public Religion Legionaries { get; } = new Religion("legionaries"); 12 | public Religion AseraCode { get; } = new Religion("asera"); 13 | public Religion Amra { get; } = new Religion("amra"); 14 | public Religion Martyrdom { get; } = new Religion("darusosian"); 15 | public Religion Canticles { get; } = new Religion("canticles"); 16 | public Religion Treelore { get; } = new Religion("treelore"); 17 | public Religion Osfeyd { get; } = new Religion("osfeyd"); 18 | public Religion SixWinds { get; } = new Religion("sixWinds"); 19 | public Religion Jumne { get; } = new Religion("junme"); 20 | public Religion Rodovera { get; } = new Religion("rodovera"); 21 | public Religion Siri { get; } = new Religion("siri"); 22 | public Religion Kannic { get; } = new Religion("kannic"); 23 | public Religion Ahhak { get; } = new Religion("ahhak"); 24 | public override IEnumerable All 25 | { 26 | get 27 | { 28 | yield return Martyrdom; 29 | yield return Legionaries; 30 | yield return Calradism; 31 | yield return Osfeyd; 32 | yield return Amra; 33 | yield return AseraCode; 34 | yield return Ahhak; 35 | yield return ImmortalFlame; 36 | yield return SixWinds; 37 | yield return Siri; 38 | yield return Kannic; 39 | yield return Jumne; 40 | yield return Rodovera; 41 | yield return Treelore; 42 | } 43 | } 44 | 45 | public override void Initialize() 46 | { 47 | var aserai = Utils.Helpers.GetCulture("aserai"); 48 | var khuzait = Utils.Helpers.GetCulture("khuzait"); 49 | var imperial = Utils.Helpers.GetCulture("empire"); 50 | var battania = Utils.Helpers.GetCulture("battania"); 51 | var vlandia = Utils.Helpers.GetCulture("vlandia"); 52 | var sturgia = Utils.Helpers.GetCulture("sturgia"); 53 | var vakken = Utils.Helpers.GetCulture("vakken"); 54 | var nord = Utils.Helpers.GetCulture("nord"); 55 | var darshi = Utils.Helpers.GetCulture("darshi"); 56 | var siri = Utils.Helpers.GetCulture("siri"); 57 | var swadia = Utils.Helpers.GetCulture("swadia"); 58 | var rhodok = Utils.Helpers.GetCulture("rhodok"); 59 | var massa = Utils.Helpers.GetCulture("massa"); 60 | var kannic = Utils.Helpers.GetCulture("kannic"); 61 | var balion = Utils.Helpers.GetCulture("balion"); 62 | var geroia = Utils.Helpers.GetCulture("geroia"); 63 | 64 | Ahhak.Initialize(BKCEFaiths.Instance.Ahhak, 65 | new List() 66 | { 67 | darshi, khuzait 68 | }); 69 | 70 | Kannic.Initialize(BKCEFaiths.Instance.Kannic, 71 | new List() 72 | { 73 | kannic, geroia 74 | }); 75 | 76 | ImmortalFlame.Initialize(BKCEFaiths.Instance.ImmortalFlame, 77 | new List() 78 | { 79 | darshi 80 | }); 81 | 82 | Siri.Initialize(BKCEFaiths.Instance.Siri, 83 | new List() 84 | { 85 | siri 86 | }); 87 | 88 | Legionaries.Initialize(BKCEFaiths.Instance.Legionaries, 89 | new List() 90 | { 91 | imperial 92 | }); 93 | 94 | 95 | Calradism.Initialize(BKCEFaiths.Instance.Calradism, 96 | new List() 97 | { 98 | imperial 99 | }); 100 | 101 | AseraCode.Initialize(BKCEFaiths.Instance.AseraCode, 102 | new List { aserai, khuzait, imperial }); 103 | 104 | Amra.Initialize(BKCEFaiths.Instance.AmraOllahm, 105 | new List { battania }); 106 | 107 | Treelore.Initialize(BKCEFaiths.Instance.Treelore, 108 | new List { vakken, sturgia }); 109 | 110 | Rodovera.Initialize(BKCEFaiths.Instance.Rodovera, 111 | new List { sturgia }); 112 | 113 | Martyrdom.Initialize(BKCEFaiths.Instance.Darusosian, 114 | new List { imperial }); 115 | 116 | Osfeyd.Initialize(BKCEFaiths.Instance.Osfeyd, 117 | new List { vlandia, massa, swadia, rhodok, balion }); 118 | 119 | SixWinds.Initialize(BKCEFaiths.Instance.SixWinds, 120 | new List { khuzait }); 121 | 122 | Jumne.Initialize(BKCEFaiths.Instance.Jumne, 123 | new List { nord }); 124 | 125 | foreach (var religion in All) 126 | { 127 | DefaultReligions.Instance.AddObject(religion); 128 | } 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/kingdoms.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Vlandia 13 | 14 | 15 | 16 | Wilundinga Ríce 17 | 18 | 19 | 20 | Wilundinga Ríce 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Battania 31 | 32 | 33 | 34 | Uchelbrenhinaeth y Battaniaid 35 | 36 | 37 | 38 | Uchelbrenhinaeth y Battaniaid 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Sturgia 49 | 50 | 51 | 52 | Sturgiskyy Knjazývstvo 53 | 54 | 55 | 56 | Sturgiskyy Knjazývstvo 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Aserai 67 | 68 | 69 | 70 | Saltana al-Aserai 71 | 72 | 73 | 74 | Saltana al-Aserai 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | Khuzaits 85 | 86 | 87 | 88 | Khaganlik Devseglar 89 | 90 | 91 | 92 | Khaganlik Devseglar 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | Northern Calradoi 103 | 104 | 105 | 106 | Politeia ton Calradoi 107 | 108 | 109 | 110 | Politeia ton Calradoi 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | Western Calradoi 121 | 122 | 123 | 124 | Diktatoría ton Calradoi 125 | 126 | 127 | 128 | Diktatoría ton Calradoi 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | Southern Calradoi 139 | 140 | 141 | 142 | Basileia ton Calradoi 143 | 144 | 145 | 146 | Basileia ton Calradoi 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/BKCEFaithGroups.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths; 2 | using System.Collections.Generic; 3 | using TaleWorlds.Localization; 4 | 5 | namespace BannerKings.CulturesExpanded.Religions 6 | { 7 | public class BKCEFaithGroups : DefaultTypeInitializer 8 | { 9 | public FaithGroup AseraGroup { get; } = new FaithGroup("AseraGroup"); 10 | public FaithGroup BattaniaGroup { get; } = new FaithGroup("BattaniaGroup"); 11 | public FaithGroup ImperialGroup { get; } = new FaithGroup("ImperialGroup"); 12 | public FaithGroup VlandiaGroup { get; } = new FaithGroup("VlandiaGroup"); 13 | public FaithGroup SturgiaGroup { get; } = new FaithGroup("SturgiaGroup"); 14 | public FaithGroup DevsegGroup { get; } = new FaithGroup("DevsegGroup"); 15 | public FaithGroup DarshiGroup { get; } = new FaithGroup("DarshiGroup"); 16 | 17 | public override IEnumerable All 18 | { 19 | get 20 | { 21 | yield return AseraGroup; 22 | yield return BattaniaGroup; 23 | yield return ImperialGroup; 24 | yield return VlandiaGroup; 25 | yield return SturgiaGroup; 26 | yield return DevsegGroup; 27 | yield return DarshiGroup; 28 | } 29 | } 30 | 31 | public override void Initialize() 32 | { 33 | DarshiGroup.Initialize(new TextObject("{=!}Darshi Faiths"), 34 | new TextObject("{=!}The Darshi faiths are a group of religions developed by the Darshi. It is mainly represented by the Atash Amesha, the faith of most Darshi and of the Darshianshahr, represented in their cities by the fire temples. However, a small, heretic cult was developed in Odokh, one that believes in sorcery rather than the Immortal Flame, and it has been adopted by its Khuzait overlords.")); 35 | 36 | AseraGroup.Initialize(new TextObject("{=!}Nahasan Faiths"), 37 | new TextObject("{=!}The Nahasa and its tribes have historically bred a plethora of faiths. In Calradia, these are represented mainly by the Code of Asera, the faith and law of self-acclaimed Aserai confederate tribes. But there are also the Siri, with their Great Lion and animal gods, lie at the very core of the Nahasa, and have worshiped their gods long before the Nahawasi nomads gathered as the Aserai sultanate. Lastly, the Kannic faith, relinquished to the remainings of Kannic Politeia at Lys and secret groups of cultists along the Perassic sea, where the Kannic once ruled.")); 38 | 39 | BattaniaGroup.Initialize(new TextObject("{=GbQpgQat}Derwyddon Faiths"), 40 | new TextObject("{=!}Long ago, when Calradoi attempted to communicate with local Battanians, one word appeared to them as distinctly important: 'Derwyddon'. In their ignorance, they assumed it to mean 'faith'. The word however was spoken by fur and cloak clad, elderly men: the druids, or in other words, Derwyddon. Though the ancient pre-Imperial faiths are often oral traditions and differ from tribe to tribe, important druids have come to agree on theological matters through the existence of the Battanian High-Kingdom, which stimulates this integration.{newline}{newline}Apart from the Battanians, this group is also represented by the Palaic, local kinsmen of the Battanians, and who share important beliefs in their faiths, such as the importance of lakes. However, scarcely exists anymore, after centuries of Imperial dominance.")); 41 | 42 | ImperialGroup.Initialize(new TextObject("{=NWqkTdMt}Calradian Faiths"), 43 | new TextObject("{=!}The Imperial Calradoi faiths. Long ago, the Calradoi prayed only to godly, ethereal figures, who could not be engaged by men unless they chose to descend to our plane. Today these are known as the Erythryans. However, throughout the Imperial history, the concept of Divus and the deification of flesh and blood figures become more and more prevalent. Calradios is the epitome of such concept, but many since him have claimed to be his descendent, and thus descendents of the Gods themselves. Beloved emperors, empress and even military commanders, who held much sway over their legionaires, would foster such cults, if not simply allow them to thrive once they naturally developed. Such cults have grown apart, at times with different Senate factions favoring one over the other, and now through the separate Empire claimants, who favor cults that support their claim and worldview.")); 44 | 45 | VlandiaGroup.Initialize(new TextObject("{=!}Wilunding Faiths"), 46 | new TextObject("{=!}The faiths brought through the seas by the Vlandic peoples. Though different among the original tribes that migrated to Calradia, the Wilunding tribes find theri faiths represented in Osfeyd. The Wilunding believe their gods are heroes, sometimes half-animal or fully animal as well, but still capable of the desires and begrudings of man.")); 47 | 48 | SturgiaGroup.Initialize(new TextObject("{=!}Ircaran Faiths"), 49 | new TextObject("{=!}The faiths born within the Kachyar peninsula and Ircaran Wildlands. These are represented by the sister faiths of the Sturgians and Vakken.")); 50 | 51 | DevsegGroup.Initialize(new TextObject("{=!}Devseg Faiths"), 52 | new TextObject("{=!}The group of faiths brought of the Devseg peoples. Most Devseg in Calradia are part of the Khuzait realm, and thus have come to the continent by hordes. However, Devseg tribes had already settled parts of eastern Calradia, such as the Iltanlar. These scarcce tribes however are overshadowed by their semi-nomadic horde cousins, who have certainly lifted the Devseg threat to the neighbouring cultures.")); 53 | 54 | foreach (var item in All) 55 | { 56 | DefaultFaithGroups.Instance.AddObject(item); 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/skill_templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 21 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | 36 | 38 | 39 | 40 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 58 | 59 | 61 | 63 | 65 | 67 | 69 | 71 | 73 | 75 | 76 | 77 | 78 | 80 | 82 | 84 | 86 | 88 | 90 | 92 | 94 | 95 | 96 | 98 | 100 | 102 | 104 | 106 | 108 | 110 | 112 | 113 | 114 | 115 | 117 | 119 | 121 | 123 | 125 | 127 | 129 | 131 | 132 | 133 | 135 | 137 | 139 | 141 | 143 | 145 | 147 | 149 | 150 | 151 | 153 | 155 | 157 | 159 | 161 | 163 | 165 | 167 | 168 | 169 | 171 | 173 | 175 | 177 | 179 | 181 | 183 | 185 | 186 | 187 | 188 | 190 | 192 | 194 | 196 | 198 | 200 | 202 | 204 | 205 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/SubModule.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/LegionariesSarapios.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using TaleWorlds.CampaignSystem; 3 | using TaleWorlds.CampaignSystem.Settlements; 4 | using TaleWorlds.Core; 5 | using TaleWorlds.Localization; 6 | 7 | namespace BannerKings.Managers.Institutions.Religions.Faiths.Empire 8 | { 9 | public class LegionariesSarapios : MonotheisticFaith 10 | { 11 | public override Settlement FaithSeat => Settlement.All.First(x => x.StringId == "town_EN1"); 12 | public override Banner GetBanner() => new Banner("11.14.40.1836.1836.768.774.1.0.0.512.35.149.187.13.954.627.0.0.-90.510.96.149.381.68.954.804.1.1.-90.512.35.149.187.13.914.627.0.0.-90.510.96.149.381.68.914.804.1.1.-90.343.44.149.440.445.764.821.1.1.0.147.44.149.239.242.764.647.1.1.0.423.2.149.128.136.764.484.1.1.0.512.35.149.187.13.614.627.0.0.-90.510.96.149.381.68.614.804.1.1.-90.512.35.149.187.13.574.627.0.0.-90.510.96.149.381.68.574.804.1.1.-90"); 13 | 14 | public override TextObject GetBlessingAction() 15 | { 16 | return new TextObject("{=!}I would like to pray to Sarapios Invictus."); 17 | } 18 | 19 | public override TextObject GetBlessingActionName() 20 | { 21 | return new TextObject("{=!}pray to"); 22 | } 23 | 24 | public override TextObject GetBlessingConfirmQuestion() 25 | { 26 | return new TextObject("{=!}Confirm your devotion upon the name of Sarapios Invictus, our hallowed protector."); 27 | } 28 | 29 | public override TextObject GetBlessingQuestion() 30 | { 31 | return new TextObject("{=!}Do you seek the wisdom of Sarapios Invictus, or do you seek Ireos, the god of war himself?"); 32 | } 33 | 34 | public override TextObject GetBlessingQuickInformation() 35 | { 36 | return new TextObject("{=!}{HERO} is medidating upon {DIVINITY}."); 37 | } 38 | 39 | public override TextObject GetClergyForbiddenAnswer(int rank) 40 | { 41 | return new TextObject("{=!}"); 42 | } 43 | 44 | public override TextObject GetClergyForbiddenAnswerLast(int rank) 45 | { 46 | return new TextObject("{=!}"); 47 | } 48 | 49 | public override TextObject GetClergyGreeting(int rank) 50 | { 51 | return new TextObject("{=!}"); 52 | } 53 | 54 | public override TextObject GetClergyGreetingInducted(int rank) 55 | { 56 | return new TextObject("{=!}"); 57 | } 58 | 59 | public override TextObject GetClergyInduction(int rank) 60 | { 61 | return new TextObject("{=!}"); 62 | } 63 | 64 | public override TextObject GetClergyInductionLast(int rank) 65 | { 66 | return new TextObject("{=!}"); 67 | } 68 | 69 | public override TextObject GetClergyPreachingAnswer(int rank) 70 | { 71 | return new TextObject("{=!}"); 72 | } 73 | 74 | public override TextObject GetClergyPreachingAnswerLast(int rank) 75 | { 76 | return new TextObject("{=!}"); 77 | } 78 | 79 | public override TextObject GetClergyProveFaith(int rank) 80 | { 81 | return new TextObject("{=!}"); 82 | } 83 | 84 | public override TextObject GetClergyProveFaithLast(int rank) 85 | { 86 | return new TextObject("{=!}"); 87 | } 88 | 89 | public override TextObject GetCultsDescription() => new TextObject("{=!}Cults"); 90 | 91 | public override TextObject GetDescriptionHint() => new TextObject("{=!}Sarapios Divus was a commander of exceptional performance, to whom the founding of Epicrotea was honored. He was acclaimed Invictus in his lifetime - undefeated, a most honorable title - and Divus in his afterlife - a divinity. Though the rite becoming Divus is otherwise reserved to emperors and their families, the Senate had no choice but to concede to the demands of the deceased Sarapios' followers, thousands of legionaries and officers. So it is that rather than a state formality or political manoeuvre, his worship was a natural development, as the practice first began."); 92 | 93 | public override TextObject GetFaithDescription() => new TextObject("{=!}Sarapios Divus was a commander of exceptional performance, to whom the founding of Epicrotea was honored. He was acclaimed Invictus in his lifetime - undefeated, a most honorable title - and Divus in his afterlife - a divinity. Though the rite becoming Divus is otherwise reserved to emperors and their families, the Senate had no choice but to concede to the demands of the deceased Sarapios' followers, thousands of legionaries and officers. So it is that rather than a state formality or political manoeuvre, his worship was a natural development, as the practice first began. His cult is naturally aligned with the cult of Ireos, one of the Erithryans. Ireos is the spear-wielding god of war, and protector of the nation, an thus closely associated with bravery and military conquest. Sarapios' legionaries believed him to be blessed by the god, if not one of his descendants."); 94 | 95 | public override TextObject GetFaithName() => new TextObject("{=!}Legionaries of Sarapios Invictus"); 96 | 97 | public override string GetId() => "legionaries"; 98 | 99 | public override int GetIdealRank(Settlement settlement) 100 | { 101 | if (FaithSeat == settlement) return 2; 102 | return 1; 103 | } 104 | 105 | public override (bool, TextObject) GetInductionAllowed(Hero hero, int rank) 106 | { 107 | var text = new TextObject("{=aSkNfvzG}Induction is possible."); 108 | var kingdom = hero.Clan.Kingdom; 109 | if (!IsHeroNaturalFaith(hero) && (kingdom == null || kingdom.StringId != "empire_w")) 110 | { 111 | text = new TextObject("{=!}Not a member of the Western Empire."); 112 | return new(false, text); 113 | } 114 | 115 | return new(true, text); 116 | } 117 | 118 | public override TextObject GetInductionExplanationText() => new TextObject("{=!}Any Imperials may be inducted. Non-Imperials need to be part of the Western Empire."); 119 | 120 | public override int GetMaxClergyRank() => 2; 121 | 122 | public override TextObject GetRankTitle(int rank) 123 | { 124 | if (rank == 2) return new TextObject("{=!}Flamines Ireoilis"); 125 | return new TextObject("{=!}Flamines"); 126 | } 127 | 128 | public override TextObject GetZealotsGroupName() 129 | { 130 | return TextObject.Empty; 131 | } 132 | 133 | public override bool IsCultureNaturalFaith(CultureObject culture) => culture.StringId == "empire"; 134 | 135 | public override bool IsHeroNaturalFaith(Hero hero) 136 | { 137 | if (hero.Clan != null && hero.Clan.StringId == "legion_of_the_betrayed") 138 | { 139 | return true; 140 | } 141 | 142 | if (IsCultureNaturalFaith(hero.Culture) && hero.MapFaction != null && hero.MapFaction.IsKingdomFaction && 143 | hero.MapFaction.StringId == "empire_w") 144 | { 145 | if (hero.IsLord) return true; 146 | else if (MBRandom.RandomFloat < 0.9f) return true; 147 | } 148 | 149 | return false; 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/Calradism.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths; 2 | using System.Linq; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | using TaleWorlds.Core; 6 | using TaleWorlds.Localization; 7 | 8 | namespace BannerKings.CulturesExpanded.Religions 9 | { 10 | public class Calradism : MonotheisticFaith 11 | { 12 | public override Settlement FaithSeat => Settlement.All.First(x => x.StringId == "town_ES4"); 13 | public override Banner GetBanner() => new Banner("11.8.40.1836.1836.768.774.1.0.0.512.35.149.328.24.983.592.0.0.45.510.92.149.668.120.764.812.1.1.45.512.35.149.328.24.545.593.0.0.-45.510.92.149.668.120.764.812.1.1.-45.344.40.149.320.324.764.810.1.1.0.423.2.149.489.494.764.812.1.1.0.108.121.149.225.228.764.552.1.1.0"); 14 | 15 | public override TextObject GetBlessingAction() => new TextObject("{=!}I would like to pray to Augoustos Calradios."); 16 | 17 | public override TextObject GetBlessingActionName() => new TextObject("{=!}pray to"); 18 | 19 | public override TextObject GetBlessingConfirmQuestion() => new TextObject("{=!}Confirm your devotion upon the name of Calradios and the good Gods of Heaven."); 20 | 21 | public override TextObject GetBlessingQuestion() => new TextObject("{=!}Would you pray to Calradios, Augoustos Divi Filius, or our sacred gods of Heaven?"); 22 | 23 | public override TextObject GetBlessingQuickInformation() 24 | { 25 | return new TextObject("{=!}{HERO} is medidating upon {DIVINITY}."); 26 | } 27 | 28 | public override TextObject GetClergyForbiddenAnswer(int rank) 29 | { 30 | return new TextObject("{=!}"); 31 | } 32 | 33 | public override TextObject GetClergyForbiddenAnswerLast(int rank) 34 | { 35 | return new TextObject("{=!}"); 36 | } 37 | 38 | public override TextObject GetClergyGreeting(int rank) 39 | { 40 | return new TextObject("{=!}Ave, newcomer. I represent here the good citizens of the empire, those pious to Heaven. I see you do not share that with us, regardless, you shall be welcome. As their Flamines, the citizens allow me to speak for them in most matters, trusting the good judgement of the gods."); 41 | } 42 | 43 | public override TextObject GetClergyGreetingInducted(int rank) 44 | { 45 | return new TextObject("{=!}Salve, citizen! As you may see, I represent our peers here at {SETTLEMENT}. We here respect the way of Heaven as you yourself do. As their flamines, I speak for them in most matters.") 46 | .SetTextVariable("SETTLEMENT", Settlement.CurrentSettlement.Name); 47 | } 48 | 49 | public override TextObject GetClergyInduction(int rank) 50 | { 51 | return new TextObject("{=!}"); 52 | } 53 | 54 | public override TextObject GetClergyInductionLast(int rank) 55 | { 56 | return new TextObject("{=!}"); 57 | } 58 | 59 | public override TextObject GetClergyPreachingAnswer(int rank) 60 | { 61 | return new TextObject("{=!}We uphold the values of the gods in Heaven. Calradios was their messenger, and he instructed us to build the world. That is what we preach. To expand, cultivate, assimilate, rule. For centuries we have done so. At times, erronously, such as these times of the Internecine. But Heaven is just and corrects our path."); 62 | } 63 | 64 | public override TextObject GetClergyPreachingAnswerLast(int rank) 65 | { 66 | return new TextObject("{=!}But to answer your question: we preach the dominion of Heaven, the Empire, the Senate and the Calradoi. We do not wish for the demise of others, but instead that they join us in this holy mission. A single flag where all the peaples converge, under the council of Heaven, to unite Calradia."); 67 | } 68 | 69 | public override TextObject GetClergyProveFaith(int rank) 70 | { 71 | return new TextObject("{=!}Many are the virtues of Heaven we ought to practice. Such ways they have passed onto us through the hallowed Calradios and his descendants, and through our rites. To sacrifice a bull or a ram to them, that a man pious to Heaven should do. Or instead, offer the gods wine through Lustratio, for even the gods need amusement."); 72 | } 73 | 74 | public override TextObject GetClergyProveFaithLast(int rank) 75 | { 76 | return new TextObject("{=!}Above all, uphold their values. Veritas, be true to your word, which will not escape the ears of the Sky-Father. Industria, work as hard as you can, as did our ancestors, as did Augoustos Calradios, so that we and our descendants may live in glory. Finally, Justitia, to give good judgement and fair punishment, for above all, the gods are just."); 77 | } 78 | 79 | public override TextObject GetCultsDescription() => new TextObject("{=!}Cults"); 80 | 81 | public override TextObject GetDescriptionHint() => new TextObject("{=!}Calradiolismus for a long time was the main religious cult throughout the empire. The faith revolves around the concept of Divus, or, in other words, divinities materialized in great men. Calradios, of course, is the greatest Divus known to history, descendant of Ireos, son of Iovis, the Sky-Father. Iovis and his cohort of gods are believed to take residence upon mount Erithrys - the Erithryans. Collectively, these gods are refered to by folks as 'Heaven', for their home reaches the sky."); 82 | 83 | public override TextObject GetFaithDescription() => new TextObject("{=!}Calradiolismus for a long time was the main religious cult throughout the empire. The faith revolves around the concept of Divus, or, in other words, divinities materialized in great men. Many a time great emperors or generals have either cults created around them, or incited such cults themselves. Eventually, the concept was formalized through the Divus annointment. Naturally, however, the Senate is highly resistant to granting such status to living people, in fear of granting them too much popular influence. None but the most heterodox could, however, deny Calradios' status as Divus and Founder of the empire. In addition to Calradios, the cult of the Erithryans is widespread, and forms the basis of Calradian theology. Erithryans are the traditional pantheon of Gods for the Calradoi, believed to have made residence on mount Erithrys and thus bless and watch over the Calradoi. Collectively, these gods are refered to by folks as 'Heaven', for their home reaches the sky."); 84 | 85 | public override TextObject GetFaithName() => new TextObject("{=!}Calradiolismus"); 86 | 87 | public override string GetId() => "calradian"; 88 | 89 | public override int GetIdealRank(Settlement settlement) 90 | { 91 | if (FaithSeat == settlement) return 2; 92 | return 1; 93 | } 94 | 95 | public override (bool, TextObject) GetInductionAllowed(Hero hero, int rank) => 96 | new(true, new TextObject("{=GAuAoQDG}You will be converted")); 97 | 98 | public override TextObject GetInductionExplanationText() => new TextObject("{=!}Anyone may be inducted."); 99 | 100 | public override int GetMaxClergyRank() => 2; 101 | 102 | public override TextObject GetRankTitle(int rank) 103 | { 104 | if (rank == 2) return new TextObject("{=!}Flamines Iovilis"); 105 | return new TextObject("{=!}Flamines"); 106 | } 107 | 108 | public override TextObject GetZealotsGroupName() 109 | { 110 | return TextObject.Empty; 111 | } 112 | 113 | public override bool IsCultureNaturalFaith(CultureObject culture) => culture.StringId == "empire"; 114 | 115 | 116 | public override bool IsHeroNaturalFaith(Hero hero) => IsCultureNaturalFaith(hero.Culture); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/Siri.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths; 2 | using System.Linq; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | using TaleWorlds.Core; 6 | using TaleWorlds.Localization; 7 | 8 | namespace BannerKings.CulturesExpanded.Religions 9 | { 10 | public class Siri : PolytheisticFaith 11 | { 12 | public override Settlement FaithSeat => Settlement.All.First(x => x.StringId == "town_A10"); 13 | public override Banner GetBanner() => new Banner("11.162.166.1528.1528.764.764.1.0.0.10134.212.116.400.400.755.755.0.0.0"); 14 | 15 | public override TextObject GetBlessingAction() => new TextObject("{=!}I would like to be blessed by the gods."); 16 | 17 | public override TextObject GetBlessingActionName() => new TextObject("{=!}be blessed by."); 18 | 19 | public override TextObject GetBlessingConfirmQuestion() => 20 | new TextObject("{=!}Confirm to me thy pledge to me before I commune with the godly realm."); 21 | 22 | public override TextObject GetBlessingQuestion() => 23 | new TextObject("{=!}Dost thou seek the blessing of Laha Mouei, king of the Nahasa?"); 24 | 25 | public override TextObject GetBlessingQuickInformation() => 26 | new TextObject("{=!}{HERO} is blessed by {DIVINITY}."); 27 | 28 | public override TextObject GetClergyForbiddenAnswer(int rank) => 29 | new TextObject("{=!}Above all, being prey to thy enemies. This any of the Siri knows. Does the lion flee from the sheep? To count among the pride of the gods is to follow their teachings."); 30 | 31 | public override TextObject GetClergyForbiddenAnswerLast(int rank) => 32 | new TextObject("{=!}Be not afraid of thy enemies. Accept not disrepect. Twist not thy words: let them be direct and truthful. A lion does not bend his word. Pay tribute to the gods and teach thy children our ways."); 33 | 34 | public override TextObject GetClergyGreeting(int rank) => 35 | new TextObject("{=!}Hail to thee, stranger. I see thou art not part of our pride. Here my Siri kinsfolk come to me, their Tillik-Itt. A woman of the gods, if you must. Thou art welcome to hear about the wisdom of our gods."); 36 | 37 | public override TextObject GetClergyGreetingInducted(int rank) => 38 | new TextObject("{=!}Be welcome, {?PLAYER.GENDER}lioness{?}lion{\\?} brethen. I serve the gods here as their Tillik-Itt. Come to me if thou wishest to commune with them, or hear their wisdom."); 39 | 40 | public override TextObject GetClergyInduction(int rank) 41 | { 42 | var induction = GetInductionAllowed(Hero.MainHero, rank); 43 | if (!induction.Item1) 44 | { 45 | return new TextObject("{=!}Thou art not fit to be of our pride. If thou wishest to be with the gods, learnest our ways, the Siri ways.[if:convo_bored]"); 46 | } 47 | 48 | return new TextObject("{=!}Be welcome to our pride, {PLAYER.NAME}. You shall now be known as a {?PLAYER.GENDER}lioness{?}lion{\\?} amongst our kinsfolk."); 49 | } 50 | 51 | public override TextObject GetClergyInductionLast(int rank) 52 | { 53 | var induction = GetInductionAllowed(Hero.MainHero, rank); 54 | if (!induction.Item1) 55 | { 56 | return new TextObject("{=!}{?PLAYER.GENDER}Or if thou wishest to prove thyself as a lioness, hunt as one. All Siri women learn the way of the hunt: to pursue and kill.{?}As a man, that is all thou canst do. Learn our ways, perhaps take thyself a good Siri wife - one that could provide strong cubs.{\\?}[if:convo_bored]"); 57 | } 58 | 59 | return new TextObject("{=!}Comest to me whenever thou needest guidance or wisdom from the gods. Now go, and bolster the strength of our pride!"); 60 | } 61 | 62 | public override TextObject GetClergyPreachingAnswer(int rank) => 63 | new TextObject("{=!}We Tillik-Itt, the wisewomen of the Siri, teach our kinsfolk the wisdom of the gods. For the gods have many good things to teach us: strength, honor, pride."); 64 | 65 | public override TextObject GetClergyPreachingAnswerLast(int rank) => 66 | new TextObject("{=!}Such is the way we Siri have lived by the Aman, the holy water, since a time woman and man were but children."); 67 | 68 | public override TextObject GetClergyProveFaith(int rank) => 69 | new TextObject("{=!}If thou wishest to prove thy faith: the Great Lion takes kindly to offerings of food. Bring honey, the nectar of the gods, and they surely shall be pleased. Or if thou wishest, bring a bull to Laha Mouei. The lion must feed, and so a sacrifice must be made."); 70 | 71 | public override TextObject GetClergyProveFaithLast(int rank) => 72 | new TextObject("{=!}And of course, live by the wisdom of the gods."); 73 | 74 | public override TextObject GetCultsDescription() => new TextObject("{=!}Gods"); 75 | 76 | public override TextObject GetDescriptionHint() => new TextObject("{=!}The ancient beliefs of the Siri revolve around the river Aman, the holy water, and various animal or animalistic gods. Each of them a symbol to the Siri culture and faith. Highest among them all is the lion, represented by Laha Mouei, the Great Lion God. The Tillik-Itt, Siri wisewomen, tell such tales through glyphs and oral traditions, and claim the Siri are descendants of Laha Mouei."); 77 | 78 | public override TextObject GetFaithDescription() => new TextObject("{=!}The ancient beliefs of the Siri revolve around the river Aman, the holy water, and various animal or animalistic gods. Each of them a symbol to the Siri culture and faith. Highest among them all is the lion, represented by Laha Mouei, the Great Lion God. Among other animals, the cow is often associated with ferility and abundance, while the ram brings protection. The Tillik-Itt, Siri wisewomen, tell such tales through glyphs and oral traditions, and claim the Siri are descendants of Laha Mouei. In their matriarchal traditions, women of honour are expected to hunt and kill, not unlike lionesses."); 79 | 80 | public override TextObject GetFaithName() => new TextObject("{=!}Tillik-Deger"); 81 | 82 | public override string GetId() => "siri"; 83 | 84 | public override int GetIdealRank(Settlement settlement) 85 | { 86 | if (settlement == FaithSeat) return 2; 87 | return 1; 88 | } 89 | 90 | public override (bool, TextObject) GetInductionAllowed(Hero hero, int rank) 91 | { 92 | if (IsCultureNaturalFaith(hero.Culture)) 93 | { 94 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 95 | } 96 | 97 | if (hero.IsFemale && hero.GetSkillValue(DefaultSkills.Athletics) >= 50 && hero.GetSkillValue(DefaultSkills.Bow) >= 50) 98 | { 99 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 100 | } 101 | 102 | return new(false, GetInductionExplanationText()); 103 | } 104 | 105 | public override TextObject GetInductionExplanationText() => new TextObject("{=!}The faith only accepts those of Siri culture, or women with at least 50 Athletics and Bow skills"); 106 | 107 | public override int GetMaxClergyRank() => 2; 108 | 109 | public override TextObject GetRankTitle(int rank) 110 | { 111 | if (rank == 2) new TextObject("{=!}Tillik-Unnol"); 112 | return new TextObject("{=!}Tillik-Itt"); 113 | } 114 | 115 | public override TextObject GetZealotsGroupName() => new TextObject("{=!}Amana Mooui"); //Aman's lions 116 | 117 | public override bool IsCultureNaturalFaith(CultureObject culture) => culture.StringId == "siri"; 118 | 119 | public override bool IsHeroNaturalFaith(Hero hero) => IsCultureNaturalFaith(hero.Culture); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/Ahhakism.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths; 2 | using System.Linq; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | using TaleWorlds.Core; 6 | using TaleWorlds.Localization; 7 | 8 | namespace BannerKings.CulturesExpanded.Religions 9 | { 10 | public class Ahhakism : PolytheisticFaith 11 | { 12 | public override Settlement FaithSeat => Settlement.All.First(x => x.StringId == "town_K6"); 13 | public override Banner GetBanner() => new Banner("11.4.2.1528.1528.764.764.1.0.0.10058.22.3.483.483.764.764.0.0.0"); 14 | 15 | public override TextObject GetBlessingAction() => new TextObject("{=!}I would like to pay tribute to the Yazatas."); 16 | 17 | public override TextObject GetBlessingActionName() => new TextObject("{=!}pay tribute to."); 18 | 19 | public override TextObject GetBlessingConfirmQuestion() => new TextObject("{=!}Confirm to me thy tribute to the Yazatas."); 20 | 21 | public override TextObject GetBlessingQuestion() => new TextObject("{=!}Thou wishest to pay tribute to Ahhak, Yatuanshah?"); 22 | 23 | public override TextObject GetBlessingQuickInformation() => new TextObject("{=!}{HERO} has paid tributed to {DIVINITY}."); 24 | 25 | public override TextObject GetClergyForbiddenAnswer(int rank) => new TextObject("{=!}Take not heed of the fools of the Atashyasna. They will try to impose rules on thee. What is forbidden? Naught!"); 26 | 27 | public override TextObject GetClergyForbiddenAnswerLast(int rank) => new TextObject("{=!}Ahhak, Yatuanshah taught us his wisdom: to take what is ours. He killed our enemies and fed to his snakes. Their wives and children, enslaved for his kingdom. We must not meet the enemy with mercy, for they will have none towards us."); 28 | 29 | public override TextObject GetClergyGreeting(int rank) => 30 | new TextObject("{=!}Drod, stranger. I see thou art not one of our flock. Perhaps thou wishest to hear the wisdom of Ahhak, Yatuanshah?"); 31 | 32 | public override TextObject GetClergyGreetingInducted(int rank) => 33 | new TextObject("{=!}Drod abar to, follower of the Yatuanshah. I serve our Shah, Ahhak, as his Yatugar. Comest to me if thou needest the wisdom of the Yazatas and sorceries."); 34 | 35 | public override TextObject GetClergyInduction(int rank) 36 | { 37 | var induction = GetInductionAllowed(Hero.MainHero, rank); 38 | if (!induction.Item1) 39 | { 40 | return new TextObject("{=!}Thou art not one fit for the wisdom of the Yazatas, foreign blood.[rf:convo_bored]"); 41 | } 42 | 43 | return new TextObject("{=!}Be welcome, {PLAYER.NAME}. Thou art wise to ignore the fools of the Atashyasna and take ear for the wisdom of Ahhak, King of Sorcery![if:convo_excited]"); 44 | } 45 | 46 | public override TextObject GetClergyInductionLast(int rank) 47 | { 48 | var induction = GetInductionAllowed(Hero.MainHero, rank); 49 | if (!induction.Item1) 50 | { 51 | return new TextObject("{=!}Embrace our ancestors, the Darshi, or perhaps join the Devseg horselords in their pursuit. We have embraced the horselords of Odokh, for they have embraced our ways in return.[rf:convo_bored]"); 52 | } 53 | 54 | return new TextObject("{=!}Whenever thou needest sorcery, come to me and I shall help thee. Many outside our flock will try to pursue and shame thee, but here thou art welcome, and through the wisdom of the Yazatas thou shalt prevail![if:convo_excited]"); 55 | } 56 | 57 | public override TextObject GetClergyPreachingAnswer(int rank) => 58 | new TextObject("{=!}The wisdom of Ahhak, Yatuanshah. Havest though heard of him? Perhaps thou havest heard lies from the Herbads and Mowbeds of the Atashyasna. They lie because of their ignorance, their fear of the truth - that their Flame does not burn as bright as they would like to believe!"); 59 | 60 | public override TextObject GetClergyPreachingAnswerLast(int rank) => 61 | new TextObject("{=!}Ahhak, our king, made streams spring from the Kohi Rohini. Erected the walls of Odokh. We own our livelihoods to him. For this we uphold his teachings - that of strength, and sorcery."); 62 | 63 | public override TextObject GetClergyProveFaith(int rank) => 64 | new TextObject("{=!}Thou shalt be worthy of Ahhak when thou upholdest his teachings. Beest strong and show no quarter to thy enemies."); 65 | 66 | public override TextObject GetClergyProveFaithLast(int rank) => 67 | new TextObject("{=!}Ahhak, our king, made streams spring from the Kohi Rohini. Erected the walls of Odokh. We own our livelihoods to him. For this we uphold his teachings - that of strength, and sorcery."); 68 | 69 | public override TextObject GetCultsDescription() => new TextObject("{=!}Yazatas"); 70 | 71 | public override TextObject GetDescriptionHint() => new TextObject("{=!}Ahhakyasna is a cult developed in the Kohi Rohini region, when it was still ruled by the Darshi. Ahhak, King of Sorcery, is the core of the faith. Darshi of the Atashyasna claim he was a demon and tyrant, all but the opposite of good. Ahhakyasna, his followers, claim the Immortal Flame lies, and that Ahhak founded Odokh and its surroundings, bringing prosperity to his subjects."); 72 | 73 | public override TextObject GetFaithDescription() => new TextObject("{=!}Ahhakyasna is a cult developed in the Kohi Rohini region, when it was still ruled by the Darshi. Ahhak, King of Sorcery, is the core of the faith. Darshi of the Atashyasna claim he was a demon and tyrant, all but the opposite of good. Ahhakyasna, his followers, claim the Immortal Flame lies, and that Ahhak founded Odokh and its surroundings, bringing prosperity to his subjects. Faithful of the Ahhakyasna hold Ahhak to be one the Yazatas - holy beings within the Darshi theology. They recognize the Atash Amesha - the main Yazata of the Atashyasna - but claim the clergy of the Atashyasna lie, are ignorant and corrupt on the nature of their faith. Both faiths remain entirely hostile to each other."); 74 | 75 | public override TextObject GetFaithName() => new TextObject("{=!}Ahhakyasna"); 76 | 77 | public override string GetId() => "ahhak"; 78 | 79 | public override int GetIdealRank(Settlement settlement) => 1; 80 | 81 | public override (bool, TextObject) GetInductionAllowed(Hero hero, int rank) 82 | { 83 | if (IsCultureNaturalFaith(hero.Culture) || hero.Culture.StringId == "khuzait") 84 | { 85 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 86 | } 87 | 88 | if (hero.MapFaction != null && hero.MapFaction.IsKingdomFaction && hero.MapFaction.Culture.StringId == BannerKingsConfig.KhuzaitCulture) 89 | { 90 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 91 | } 92 | 93 | return new(false, GetInductionExplanationText()); 94 | } 95 | 96 | public override TextObject GetInductionExplanationText() => new TextObject("{=!}Must be of Darshi or Devseg culture, or serve a Devseg realm"); 97 | 98 | public override int GetMaxClergyRank() => 1; 99 | 100 | public override TextObject GetRankTitle(int rank) => new TextObject("{=!}Yatugar"); //sorcerer 101 | 102 | public override TextObject GetZealotsGroupName() => new TextObject("{=!}Ahhakan Hamrahan"); 103 | 104 | public override bool IsCultureNaturalFaith(CultureObject culture) => false; 105 | 106 | public override bool IsHeroNaturalFaith(Hero hero) 107 | { 108 | if (hero.IsNotable) return hero.CurrentSettlement.StringId == "town_K6"; 109 | else if (hero.Clan != null) return hero.Clan.StringId == "clan_khuzait_5"; 110 | 111 | return false; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Patches/CharacterCreationPatches.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System.Collections.Generic; 3 | using TaleWorlds.CampaignSystem.ViewModelCollection.CharacterCreation; 4 | using TaleWorlds.CampaignSystem; 5 | using TaleWorlds.Core; 6 | using System.Linq; 7 | using TaleWorlds.MountAndBlade.ViewModelCollection.FaceGenerator; 8 | 9 | namespace BannerKings.CulturesExpanded.Patches 10 | { 11 | internal class CharacterCreationPatches 12 | { 13 | [HarmonyPatch(typeof(FaceGenVM))] 14 | public class BKCEDressedPatch 15 | { 16 | [HarmonyPrefix] 17 | [HarmonyPatch("RefreshValues")] 18 | static void Refresh(FaceGenVM __instance) 19 | { 20 | __instance.IsDressed = false; 21 | __instance.ExecuteChangeClothing(); 22 | } 23 | } 24 | 25 | [HarmonyPatch(typeof(CharacterCreationCultureStageVM), "InitializePlayersFaceKeyAccordingToCultureSelection")] 26 | public class BKCECultureFaceKeyPatch 27 | { 28 | static void Postfix(CharacterCreationCultureVM selectedCulture) 29 | { 30 | Dictionary dic = new Dictionary(15); 31 | var cultures = TaleWorlds.CampaignSystem.Campaign.Current.ObjectManager.GetObjectTypeList(); 32 | dic.Add(cultures.First(x => x.StringId == BannerKingsConfig.EmpireCulture), 33 | ""); 34 | dic.Add(cultures.First(x => x.StringId == BannerKingsConfig.VlandiaCulture), 35 | ""); 36 | dic.Add(cultures.First(x => x.StringId == BannerKingsConfig.SturgiaCulture), 37 | ""); 38 | dic.Add(cultures.First(x => x.StringId == BannerKingsConfig.AseraiCulture), 39 | ""); 40 | dic.Add(cultures.First(x => x.StringId == BannerKingsConfig.KhuzaitCulture), 41 | ""); 42 | dic.Add(cultures.First(x => x.StringId == BannerKingsConfig.BattaniaCulture), 43 | ""); 44 | 45 | dic.Add(cultures.First(x => x.StringId == "balion"), 46 | ""); 47 | dic.Add(cultures.First(x => x.StringId == "bragantia"), 48 | ""); 49 | dic.Add(cultures.First(x => x.StringId == "kannic"), 50 | ""); 51 | dic.Add(cultures.First(x => x.StringId == "darshi"), 52 | ""); 53 | dic.Add(cultures.First(x => x.StringId == "siri"), 54 | ""); 55 | dic.Add(cultures.First(x => x.StringId == "nord"), 56 | ""); 57 | dic.Add(cultures.First(x => x.StringId == "geroia"), 58 | ""); 59 | dic.Add(cultures.First(x => x.StringId == "massa"), 60 | ""); 61 | dic.Add(cultures.First(x => x.StringId == "vakken"), 62 | ""); 63 | dic.Add(cultures.First(x => x.StringId == "lokti"), 64 | ""); 65 | dic.Add(cultures.First(x => x.StringId == "zendar"), 66 | ""); 67 | dic.Add(cultures.First(x => x.StringId == "swadia"), 68 | ""); 69 | dic.Add(cultures.First(x => x.StringId == "rhodok"), 70 | ""); 71 | dic.Add(cultures.First(x => x.StringId == "iltanlar"), 72 | ""); 73 | dic.Add(cultures.First(x => x.StringId == "dryatic"), 74 | ""); 75 | 76 | 77 | BodyProperties properties; 78 | if (BodyProperties.FromString(dic[selectedCulture.Culture], out properties)) 79 | { 80 | CharacterObject.PlayerCharacter.UpdatePlayerCharacterBodyProperties(properties, CharacterObject.PlayerCharacter.Race, 81 | CharacterObject.PlayerCharacter.IsFemale); 82 | } 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/settlements.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Faction.bk_clan_kannic_2 12 | 13 | 14 | 15 | Faction.clan_vlandia_6 16 | 17 | 18 | 19 | Faction.fulq 20 | 21 | 22 | 23 | Faction.bk_clan_vakken_2 24 | 25 | 26 | 27 | Faction.bk_clan_jumne_4 28 | 29 | 30 | 31 | Faction.clan_sturgia_5 32 | 33 | 34 | 35 | Faction.bk_clan_jumne_3 36 | 37 | 38 | 39 | Faction.bk_clan_jumne_1 40 | 41 | 42 | 43 | Faction.bk_clan_jumne_2 44 | 45 | 46 | 47 | 48 | 1 49 | 50 | 51 | 52 | 2 53 | 54 | 55 | 56 | 1 57 | 58 | 59 | 60 | 1 61 | 62 | 63 | 64 | 1 65 | 66 | 67 | 68 | 1 69 | 70 | 71 | 72 | 1 73 | 74 | 75 | 76 | 2 77 | 78 | 79 | 80 | 1 81 | 82 | 83 | 84 | 1 85 | 86 | 87 | 88 | 2 89 | 90 | 91 | 92 | 2 93 | 94 | 95 | 96 | 1 97 | 98 | 99 | 100 | 1 101 | 102 | 103 | 104 | 2 105 | 106 | 107 | 108 | 1 109 | 110 | 111 | 112 | 1 113 | 114 | 115 | 116 | 1 117 | 118 | 119 | 120 | 1 121 | 122 | 123 | 124 | 2 125 | 126 | 127 | 128 | 2 129 | 130 | 131 | 132 | 2 133 | 134 | 135 | 136 | 2 137 | 138 | 139 | 140 | 1 141 | 142 | 143 | 144 | 2 145 | 146 | 147 | 148 | 1 149 | 150 | 151 | 152 | 2 153 | 154 | 155 | 156 | 2 157 | 158 | 159 | 160 | 2 161 | 162 | 163 | 164 | 1 165 | 166 | 167 | 168 | 2 169 | 170 | 171 | 172 | 1 173 | 174 | 175 | 176 | 2 177 | 178 | 179 | 180 | 1 181 | 182 | 183 | 184 | 1 185 | 186 | 187 | 188 | 2 189 | 190 | 191 | 192 | 2 193 | 194 | 195 | 196 | 2 197 | 198 | 199 | 200 | 1 201 | 202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Goals/CrownGuardGoal.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.CulturesExpanded.Behaviors; 2 | using BannerKings.Managers.Goals; 3 | using BannerKings.Managers.Populations; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using TaleWorlds.CampaignSystem; 7 | using TaleWorlds.CampaignSystem.Party; 8 | using TaleWorlds.Core; 9 | using TaleWorlds.Library; 10 | using TaleWorlds.Localization; 11 | 12 | namespace BannerKings.CulturesExpanded.Goals 13 | { 14 | public class CrownGuardGoal : Goal 15 | { 16 | private int guardsAmount = -1; 17 | 18 | public CrownGuardGoal(Hero fulfiller = null) : base("goal_royal_guard_decision", GoalCategory.Kingdom, GoalUpdateType.Manual, fulfiller) 19 | { 20 | var name = new TextObject("{=!}Summon Crown Guards"); 21 | var description = new TextObject("{=!}\n"); 22 | 23 | Initialize(name, description); 24 | } 25 | 26 | public override bool IsAvailable() => Clan.PlayerClan.Kingdom != null && Clan.PlayerClan.Kingdom.RulingClan == Clan.PlayerClan; 27 | 28 | public override bool IsFulfilled(out List failedReasons) 29 | { 30 | failedReasons = new List(); 31 | 32 | var behavior = TaleWorlds.CampaignSystem.Campaign.Current.GetCampaignBehavior(); 33 | Kingdom kingdom = GetFulfiller().Clan.Kingdom; 34 | 35 | if (!behavior.IsTimeReady(kingdom)) 36 | { 37 | failedReasons.Add(new TextObject("{=!}It has been less than 5 years since guards were drawn")); 38 | } 39 | 40 | if (behavior.GetKingdomTroop(kingdom) == null) 41 | { 42 | failedReasons.Add(new TextObject("{=!}No guard template available for your kingdom")); 43 | } 44 | 45 | if (GetAvailableManpower(kingdom) < 20) 46 | { 47 | failedReasons.Add(new TextObject("{=!}Insufficient noble manpower in the realm")); 48 | } 49 | 50 | return failedReasons.IsEmpty(); 51 | } 52 | 53 | private int GetAvailableManpower(Kingdom kingdom) 54 | { 55 | int result = 0; 56 | foreach (var fief in kingdom.Fiefs) 57 | { 58 | PopulationData data = BannerKingsConfig.Instance.PopulationManager.GetPopData(fief.Settlement); 59 | result += (int)(data.MilitaryData.NobleManpower * 0.5f); 60 | } 61 | 62 | return result; 63 | } 64 | 65 | public override void ShowInquiry() 66 | { 67 | var options = new List(); 68 | Kingdom kingdom = Clan.PlayerClan.Kingdom; 69 | int manpower = GetAvailableManpower(kingdom); 70 | int div = MathF.Floor(manpower / 10f); 71 | 72 | var behavior = TaleWorlds.CampaignSystem.Campaign.Current.GetCampaignBehavior(); 73 | CharacterObject troop = behavior.GetKingdomTroop(kingdom); 74 | int cost = (int)(TaleWorlds.CampaignSystem.Campaign.Current.Models.PartyWageModel.GetTroopRecruitmentCost(troop, Hero.MainHero) * 3f); 75 | 76 | for (int i = 1; i <= div; i++) 77 | { 78 | int count = (int)(10f * i); 79 | int totalCost = (int)(cost * count); 80 | bool enabled = true; 81 | TextObject hint = TextObject.Empty; 82 | 83 | if (count > MobileParty.MainParty.LimitedPartySize - MobileParty.MainParty.MemberRoster.TotalManCount) 84 | { 85 | enabled = false; 86 | hint = new TextObject("{=!}Not enough party space."); 87 | } 88 | 89 | if (totalCost > Hero.MainHero.Gold) 90 | { 91 | enabled = false; 92 | hint = new TextObject("{=!}Not enough money."); 93 | } 94 | 95 | options.Add(new InquiryElement(count, 96 | new TextObject("{=!}{COUNT} {TROOP} - {GOLD}{GOLD_ICON}") 97 | .SetTextVariable("GOLD", totalCost) 98 | .SetTextVariable("TROOP", troop.Name) 99 | .SetTextVariable("COUNT", count) 100 | .ToString(), 101 | new ImageIdentifier(CharacterCode.CreateFrom(troop)), 102 | enabled, 103 | hint.ToString() 104 | )); 105 | } 106 | 107 | int space = MathF.Max(MobileParty.MainParty.LimitedPartySize - MobileParty.MainParty.MemberRoster.TotalManCount, 0); 108 | MBInformationManager.ShowMultiSelectionInquiry(new MultiSelectionInquiryData( 109 | new TextObject("{=!}Summon Crown Guards").ToString(), 110 | new TextObject("{=!}Summon volunteers to serve as guards for the crown. Such volunteers are drawn from the nobility and are excellent combatants in their fighting tradition, as well as exceptionally equipped. There are {CANDIDATES} available candidates while your retinue can accomodate {TROOPS} more troops.") 111 | .SetTextVariable("CANDIDATES", manpower) 112 | .SetTextVariable("TROOPS", space) 113 | .ToString(), 114 | options, 115 | true, 116 | 1, 117 | 1, 118 | GameTexts.FindText("str_done").ToString(), 119 | GameTexts.FindText("str_cancel").ToString(), 120 | delegate (List selectedOptions) 121 | { 122 | guardsAmount = (int)selectedOptions.First().Identifier; 123 | ApplyGoal(); 124 | }, 125 | null, 126 | string.Empty)); 127 | } 128 | 129 | public override void ApplyGoal() 130 | { 131 | var party = GetFulfiller().PartyBelongedTo; 132 | if (guardsAmount < 0) 133 | { 134 | int space = MathF.Max(party.LimitedPartySize - party.MemberRoster.TotalManCount, 0); 135 | if (space >= 20) guardsAmount = space; 136 | else return; 137 | } 138 | 139 | var kingdom = GetFulfiller().Clan.Kingdom; 140 | var behavior = TaleWorlds.CampaignSystem.Campaign.Current.GetCampaignBehavior(); 141 | CharacterObject troop = behavior.GetKingdomTroop(kingdom); 142 | int cost = (int)(TaleWorlds.CampaignSystem.Campaign.Current.Models.PartyWageModel.GetTroopRecruitmentCost(troop, GetFulfiller()) * 3f); 143 | 144 | if (GetFulfiller().Gold < cost) 145 | { 146 | return; 147 | } 148 | 149 | behavior.SetTime(kingdom); 150 | for (int i = 0; i < guardsAmount; i++) 151 | { 152 | var fief = kingdom.Fiefs.GetRandomElement(); 153 | var data = BannerKingsConfig.Instance.PopulationManager.GetPopData(fief.Settlement); 154 | int max = MathF.Min(1, (int)data.MilitaryData.NobleManpower); 155 | if (max > 0) 156 | { 157 | data.MilitaryData.DeduceManpower(data, max, Managers.PopulationManager.PopType.Nobles); 158 | } 159 | 160 | party.MemberRoster.AddToCounts(troop, 1); 161 | } 162 | 163 | GetFulfiller().ChangeHeroGold(-cost); 164 | } 165 | 166 | public override void DoAiDecision() 167 | { 168 | Hero hero = GetFulfiller(); 169 | Kingdom kingdom = hero.Clan.Kingdom; 170 | MobileParty party = hero.PartyBelongedTo; 171 | if (hero.Clan.Leader != hero || hero.IsPrisoner || party == null || party.LeaderHero != hero || 172 | kingdom == null || hero.Clan != kingdom.RulingClan) 173 | { 174 | return; 175 | } 176 | 177 | var list = new List(); 178 | if (!IsFulfilled(out list)) 179 | { 180 | return; 181 | } 182 | 183 | var behavior = TaleWorlds.CampaignSystem.Campaign.Current.GetCampaignBehavior(); 184 | CharacterObject troop = behavior.GetKingdomTroop(kingdom); 185 | int manpower = GetAvailableManpower(kingdom); 186 | int cost = (int)(TaleWorlds.CampaignSystem.Campaign.Current.Models.PartyWageModel.GetTroopRecruitmentCost(troop, GetFulfiller()) * 3f); 187 | int take = MathF.Min(manpower, party.LimitedPartySize - party.MemberRoster.TotalManCount); 188 | int totalCost = (int)(cost * take); 189 | if (hero.Gold >= totalCost * 2f) 190 | { 191 | ApplyGoal(); 192 | } 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/_Module/ModuleData/recruits.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/Jumne.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths; 2 | using System.Linq; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | using TaleWorlds.Core; 6 | using TaleWorlds.Localization; 7 | 8 | namespace BannerKings.CulturesExpanded.Religions 9 | { 10 | public class Jumne : PolytheisticFaith 11 | { 12 | public override Settlement FaithSeat => Settlement.All.First(x => x.StringId == "town_S2"); 13 | public override TextObject GetZealotsGroupName() => new TextObject("{=!}Truvarlithum"); 14 | 15 | public override TextObject GetDescriptionHint() 16 | { 17 | return new TextObject("{=!}Jumnartruva, the faith of Jumne, is the religion of those most Calradians call 'nords'. The Great Oak they say, much like some native Calradian beliefs, is where all life blossoms. Their many gods are said to write fate itself, Urthr, and they reward the virtuous with bountiful fate. Their faith has spread to the Sturgian realm through ascending dynasties of Jumne descent, such as the Gundavoring, who are now grand princes of Sturgia. However, common folk often in Sturgia still adhere to their ancestral faith, while Jumnartruva finds itself among the rulers and Jumne immigrants."); 18 | } 19 | 20 | public override Banner GetBanner() => new Banner("11.127.2.1528.1528.764.764.1.0.0.437.227.3.483.483.764.764.0.0.0"); 21 | 22 | public override bool IsCultureNaturalFaith(CultureObject culture) => culture.StringId == "nord"; 23 | 24 | public override bool IsHeroNaturalFaith(Hero hero) 25 | { 26 | if (hero.Clan != null) 27 | { 28 | string id = hero.Clan.StringId; 29 | return id == "clan_sturgia_1" || id == "clan_sturgia_3" || id == "clan_sturgia_4" || 30 | id == "clan_sturgia_6" || id == "skolderbrotva"; 31 | } 32 | else if (hero.IsNotable && hero.Culture.StringId == BannerKingsConfig.SturgiaCulture) 33 | { 34 | return MBRandom.RandomFloat < 0.1f; 35 | } 36 | 37 | return IsCultureNaturalFaith(hero.Culture); 38 | } 39 | 40 | public override TextObject GetBlessingAction() => new TextObject("{=!}I would like to pray to the gods and our ancestors."); 41 | 42 | public override TextObject GetBlessingActionName() => new TextObject("{=!}pray to."); 43 | 44 | 45 | public override TextObject GetBlessingConfirmQuestion() => 46 | new TextObject("{=!}Confirm thy pledge to me and I shall ask the spirits to influence thy Urthr."); 47 | 48 | public override TextObject GetBlessingQuestion() 49 | { 50 | return new TextObject("{=!}To whom would you pledge yourself? The Gods of Fate themselves?"); 51 | } 52 | 53 | public override TextObject GetBlessingQuickInformation() 54 | { 55 | return new TextObject("{=j1U1juRf}{HERO} has pledged an oath to {DIVINITY}."); 56 | } 57 | 58 | public override TextObject GetClergyForbiddenAnswer(int rank) => new TextObject("{=!}It is not my position to tell thee what thou shalt or not do - thy Urthr is for the gods. Take heed, however, of the deeds of our ancestors."); 59 | 60 | public override TextObject GetClergyForbiddenAnswerLast(int rank) => new TextObject("{=!}To flee a battle is the worst shame thou canst have. Our Urthr is written by the gods. If they fated thee to die, thou shalt die. Thy craveness will only have thee die in shame, and cursed out of the gods' hall. Face death with courage: if thou art fated to die, thou shalt meet the gods in their hall, if not, thou shallst take victory."); 61 | 62 | public override TextObject GetClergyGreeting(int rank) => new TextObject("{=!}Heill, erlendr. I serve here as the Gothi. Do not take me for a Volkvhs, those are the Sturgian fools who worship the moon. I bring to this place the ways of Jumne."); 63 | 64 | public override TextObject GetClergyGreetingInducted(int rank) => new TextObject("{=!}Heill! I see thou art of us - one of Jumne. Beest welcome, and come to me when thou needest guidance from the gods, or our ancestors."); 65 | 66 | public override TextObject GetClergyInduction(int rank) 67 | { 68 | var induction = GetInductionAllowed(Hero.MainHero, rank); 69 | if (!induction.Item1) 70 | { 71 | return new TextObject("{=!}If thou wishest to join our Truva, then first adopt our ways, the ways of Jumne. Or, if thou wishest, serve the Sturgians, whose princes have embraced our ways and are blood of our blood, and so the gods have embraced them back.[if:convo_bored]"); 72 | } 73 | 74 | return new TextObject("{=!}The gods smile on thy fate, friend. Be welcome in our community. Come to me, your Gothi, when thou needest to commune with the spirits."); 75 | } 76 | 77 | public override TextObject GetClergyInductionLast(int rank) 78 | { 79 | var induction = GetInductionAllowed(Hero.MainHero, rank); 80 | if (!induction.Item1) 81 | { 82 | return new TextObject("{=!}Until then, thou art not amongst those the gods weave favored fates for.[rf:convo_bored]"); 83 | } 84 | 85 | return new TextObject("{=!}Set sail and take up on the sword. Conquer thy fate as the gods instruct us.[if:convo_excited]"); 86 | } 87 | 88 | public override TextObject GetClergyPreachingAnswer(int rank) 89 | => new TextObject("{=!}Folks come to me to hear of our Truva, passed on to us by our ancestors. We uphold their way, and that of the gods. What way, you may ask? Simple: havest thou heard the saga of Gundar?"); 90 | 91 | public override TextObject GetClergyPreachingAnswerLast(int rank) 92 | => new TextObject("{=!}Gundar came to this continent and conquered his part of the world. That is our way. To take what is ours. We do it, because the gods allow it. And the gods allow it to those with the resolve to do so. Our venture is holy, and our success proves it."); 93 | 94 | public override TextObject GetClergyProveFaith(int rank) => 95 | new TextObject("{=!}If thou wishest to prove thyself, do as our ancestors did. Set sail to lands far, found a dynasty, and most of all, achieve conquest over thy enemies. To fight is to prove thy faith - that is the only way thou wilt know what fate the gods have weaved for thee."); 96 | 97 | public override TextObject GetClergyProveFaithLast(int rank) => 98 | new TextObject("{=!}Thy actions shall be how the gods judge thee."); 99 | 100 | public override TextObject GetFaithDescription() => new TextObject("{=!}Far north, where the land is frozen water, lies the realm of the giants. The gods once fought them, slaying their master and creating the land for man. The Great Oak they say, much like some native Calradian beliefs, is where all life blossoms. From dark corners and depths, evil forces continuously try to unroot the Oak. Among these stands out Ásbani, the God-Devouring Serpent.{newline}The Jumne believe the gods reward the virtuous with bountiful fate. That is how they justify invading and conquering foreign lands - if they won, it is because the gods wished so, and so their exploits were justified. As such, great heroes and conquerors are, within Jumne tradition, annointed as quasi-divine figures. Their beliefs have flourished within the Sturgian realm, whose nobility has been gradually being replaced or assimilated by Jumne descendants. Among them stands out the ruling dynasty itself, Gundavoring, the descendants of the Jumne hero Gundar."); 101 | 102 | public override TextObject GetFaithName() => new TextObject("{=!}Jumnartruva"); 103 | public override string GetId() => "junme"; 104 | 105 | public override int GetIdealRank(Settlement settlement) 106 | { 107 | if (settlement.IsVillage || settlement.IsTown) 108 | { 109 | return 1; 110 | } 111 | 112 | return 0; 113 | } 114 | 115 | public override (bool, TextObject) GetInductionAllowed(Hero hero, int rank) 116 | { 117 | if (IsCultureNaturalFaith(hero.Culture)) 118 | { 119 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 120 | } 121 | 122 | if (hero.MapFaction != null && hero.MapFaction.IsKingdomFaction && hero.MapFaction.Culture.StringId == BannerKingsConfig.SturgiaCulture) 123 | { 124 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 125 | } 126 | 127 | return new(false, GetInductionExplanationText()); 128 | } 129 | 130 | public override int GetMaxClergyRank() => 1; 131 | 132 | public override TextObject GetRankTitle(int rank) => new TextObject("{=!}Gothi"); 133 | 134 | public override TextObject GetCultsDescription() => new TextObject("{=J4D4X2XJ}Cults"); 135 | 136 | public override TextObject GetInductionExplanationText() => new TextObject("{=!}The faith only accepts those of Jumne culture or that serve a Sturgian realm"); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /BannerKings.TroopOverhaul/Religions/ImmortalFlame.cs: -------------------------------------------------------------------------------- 1 | using BannerKings.Managers.Institutions.Religions.Faiths; 2 | using System.Linq; 3 | using TaleWorlds.CampaignSystem; 4 | using TaleWorlds.CampaignSystem.Settlements; 5 | using TaleWorlds.Core; 6 | using TaleWorlds.Localization; 7 | 8 | namespace BannerKings.CulturesExpanded.Religions 9 | { 10 | public class ImmortalFlame : PolytheisticFaith 11 | { 12 | public override Settlement FaithSeat => Settlement.All.First(x => x.StringId == "town_Darshi_1"); 13 | //34.212.149.1716.1948.768.746.0.0.0.10079.207.41.712.540.755.755.0.0.0 14 | public override Banner GetBanner() => new Banner("11.149.40.1836.1836.768.774.1.0.0.321.128.149.184.186.764.884.1.1.0.218.85.149.270.250.804.664.1.1.338.218.85.149.270.250.724.664.1.1.22.218.71.149.280.282.764.664.1.1.0"); 15 | 16 | public override TextObject GetBlessingAction() => new TextObject("{=!}I would like to be blessed by the Yazatas."); 17 | 18 | public override TextObject GetBlessingActionName() => new TextObject("{=!}pay tribute to"); 19 | 20 | public override TextObject GetBlessingConfirmQuestion() => new TextObject("{=!}Confirm to me thy tribute to the Yazatas."); 21 | 22 | public override TextObject GetBlessingQuestion() => new TextObject("{=!}Thou wishest to give kindling to the Atash Amesha?"); 23 | 24 | public override TextObject GetBlessingQuickInformation() => new TextObject("{=!}{HERO} has paid tributed to {DIVINITY}."); 25 | 26 | public override TextObject GetClergyForbiddenAnswer(int rank) => new TextObject("{=!}To stray from the way of the Atash and the Darshianshahr. The tomes of the Atash teach us of good and evil. To be a follower of the Atash is to uphold good. For this reason, thou shalt not conspire with those of the Ahhakyasna. They pray to demons, and shall be purified by the Flame."); 27 | 28 | public override TextObject GetClergyForbiddenAnswerLast(int rank) => new TextObject("{=!}Above all, wield thy wisdom against thy vices. Uphold thy word, gather thy strength and protect thy kin. Beest kind and selfless to thy neighbour, and expect not rewards."); 29 | 30 | public override TextObject GetClergyGreeting(int rank) => 31 | new TextObject("{=!}Drod, stranger. This is the place of the Atash Amesha. Perhaps though wishest to feel the warmth of the Flame?"); 32 | 33 | public override TextObject GetClergyGreetingInducted(int rank) 34 | { 35 | 36 | return new TextObject("{=!}Drod abar to, {?PLAYER.GENDER}kinswoman{?}kinsman{\\?}. I serve here as a {PREACHER} of our people, and keeper of the Atash. Comest to me if thou wishest to feel its tender warmth.") 37 | .SetTextVariable("PREACHER", GetRankTitle(rank)); 38 | } 39 | 40 | 41 | public override TextObject GetClergyInduction(int rank) 42 | { 43 | var induction = GetInductionAllowed(Hero.MainHero, rank); 44 | if (!induction.Item1) 45 | { 46 | return new TextObject("{=!}Thou art not yet fit to be part of our Yasna. Uphold the ways of the Darshianshahr and cleanse thy sins. Until then, I would not grant you the warmth of the Flame."); 47 | } 48 | 49 | return new TextObject("{=!}I see thou upholdest the values of our wise ancestors. Beest welcome, {PLAYER.NAME}, to the warmth of our Yasna."); 50 | } 51 | 52 | public override TextObject GetClergyInductionLast(int rank) 53 | { 54 | var induction = GetInductionAllowed(Hero.MainHero, rank); 55 | if (!induction.Item1) 56 | { 57 | return new TextObject("{=!}Uphold the values of the Flame and of the Darshianshahr. Take thyself a good spouse of our ways to guide thee into our faith, become one of us, or serve the Shahanshah. Only then thou wouldst be fit for our Yasna."); 58 | } 59 | 60 | return new TextObject("{=!}Now, stray not thyself from the Atash. Wherever though goest, live by its tenets: wisdom, just and good judgement, benevolence and strength."); 61 | } 62 | 63 | public override TextObject GetClergyPreachingAnswer(int rank) 64 | { 65 | return new TextObject("{=!}The way of the Atash Amesha, known to foreigners as the Immortal Flame. The Atash we keep burning since countless generations of our ancestors. They have written down their wisdom for us, and we, learned keepers of the Flame, guard this treasure."); 66 | } 67 | 68 | public override TextObject GetClergyPreachingAnswerLast(int rank) 69 | { 70 | return new TextObject("{=!}We Darshi serve our Shahanshah, King of Kings, yet he himself serves the Atash. We preach not for others to follow our ways. When the Shahanshah conquers a king, he, in good wisdom, allows his new subjects to remain misaligned. But for those that wish to serve Truth, we are here to guide them."); 71 | } 72 | 73 | public override TextObject GetClergyProveFaith(int rank) 74 | { 75 | return new TextObject("{=!}Take thyself a good spouse of our ways to guide thee into our faith, {?PLAYER.GENDER}he{?}she{\\?} will be thy light out of the ignorant darkness."); 76 | } 77 | 78 | public override TextObject GetClergyProveFaithLast(int rank) 79 | { 80 | return new TextObject("{=!}Alternatively, become one of us. Assume the way of the Darshi. Or if though wishest, serve the Shahanshah as one of his vassals. If he judges you fit to serve the Darshianshahr, then thou wouldst be welcome in our Yasna."); 81 | } 82 | 83 | public override TextObject GetCultsDescription() => new TextObject("{=!}Yazatas"); 84 | 85 | public override TextObject GetDescriptionHint() => 86 | new TextObject("{=!}Atashyasna is the ancient belief system of the Darshi. They believe the Immortal Flame, Atash Amesha, is a force both of creation and desctruction - or in sum, purification. The Flame is the primary Yazata, or Divine Force, within their theology, and responsible for the creation of the world and mankind. Other Yazatas are also part of their faith, such as Aspas Suras, the Holy Waters, associated with bountiful prosperity."); 87 | 88 | public override TextObject GetFaithDescription() => 89 | new TextObject("{=!}Atashyasna is the ancient belief system of the Darshi. They believe the Immortal Flame, Atash Amesha, is a force both of creation and desctruction - or in sum, purification. The Flame is the primary Yazata, or Divine Force, within their theology, and responsible for the creation of the world and mankind. Other Yazatas are also part of their faith, such as Aspas Suras, the Holy Waters, associated with bountiful prosperity. In sum, their belief is centered around divine forces that govern the cosmos, and these forces do not take human form. In the end of the world, the Darshi believe, all land will be inundated with molten, sacred metal, and only those already purified by the Flame will survive it, while the rest will burn away."); 90 | 91 | public override TextObject GetFaithName() => new TextObject("{=!}Atashyasna"); 92 | 93 | public override string GetId() => "atash"; 94 | 95 | public override int GetIdealRank(Settlement settlement) 96 | { 97 | if (settlement == FaithSeat) return 3; 98 | if (settlement.Town != null) return 2; 99 | return 1; 100 | } 101 | 102 | public override (bool, TextObject) GetInductionAllowed(Hero hero, int rank) 103 | { 104 | if (IsCultureNaturalFaith(hero.Culture)) 105 | { 106 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 107 | } 108 | 109 | if (hero.Spouse != null && IsCultureNaturalFaith(hero.Spouse.Culture) && 110 | BannerKingsConfig.Instance.ReligionsManager.GetHeroReligion(hero.Spouse) == BKCEReligions.Instance.ImmortalFlame) 111 | { 112 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 113 | } 114 | 115 | if (hero.MapFaction != null && hero.MapFaction.IsKingdomFaction && hero.MapFaction.Culture.StringId == "darshi") 116 | { 117 | return new(true, new TextObject("{=GAuAoQDG}You will be converted")); 118 | } 119 | 120 | return new(false, GetInductionExplanationText()); 121 | } 122 | 123 | public override TextObject GetInductionExplanationText() => new TextObject("{=!}The faith only accepts those of Darshi culture, spouses of a Darshi faithful or that serve a Darshi realm"); 124 | 125 | public override int GetMaxClergyRank() => 3; 126 | 127 | public override TextObject GetRankTitle(int rank) 128 | { 129 | if (rank == 3) return new TextObject("{=!}Dastur"); 130 | if (rank == 2) return new TextObject("{=!}Mowbed"); 131 | return new TextObject("{=!}Hirbad"); 132 | } 133 | 134 | public override TextObject GetZealotsGroupName() => new TextObject("{=!}Anausaran"); 135 | 136 | public override bool IsCultureNaturalFaith(CultureObject culture) => culture.StringId == "darshi"; 137 | 138 | public override bool IsHeroNaturalFaith(Hero hero) => IsCultureNaturalFaith(hero.Culture); 139 | } 140 | } 141 | --------------------------------------------------------------------------------