private static void Postfix( DefaultPartySpeedCalculatingModel __instance, ref MobileParty mobileParty, ref float baseSpeed, ref StatExplainer explanation, ref float __result) { TerrainType faceTerrainType = Campaign.Current.MapSceneWrapper.GetFaceTerrainType(mobileParty.CurrentNavigationFace); if (faceTerrainType == TerrainType.Forest && mobileParty.Leader != null && mobileParty.Leader.GetFeatValue(DefaultFeats.Cultural.BattanianForestAgility)) { var explainedNumber = new ExplainedNumber(baseSpeed, explanation, null); var movingAtForestEffectField = AccessTools.Field(typeof(DefaultPartySpeedCalculatingModel), "MovingAtForestEffect"); var movingAtForestEffect = (float)movingAtForestEffectField.GetValue(__instance); var battanianAgilityBonus = DefaultFeats.Cultural.BattanianForestAgility.EffectBonus * Math.Abs(movingAtForestEffect); explainedNumber.AddFactor(battanianAgilityBonus, DefaultFeats.Cultural.BattanianForestAgility.Name); __result = explainedNumber.ResultNumber; } }
private static void Postfix( DefaultPartySpeedCalculatingModel __instance, ref MobileParty mobileParty, ref StatExplainer explanation, ref int additionalTroopOnFootCount, ref int additionalTroopOnHorseCount, ref float __result) { // Only calculate if party leader is Khuzait (should apply to NPC lords) if (mobileParty.Leader != null && mobileParty.Leader.GetFeatValue(DefaultFeats.Cultural.KhuzaitCavalryAgility)) { // Get private methods needed for calculation var calculateBaseSpeedForPartyMethod = AccessTools.Method(__instance.GetType(), "CalculateBaseSpeedForParty"); var getCavalryRatioModifierMethod = AccessTools.Method(__instance.GetType(), "GetCavalryRatioModifier"); var getMountedFootmenRatioModifierMethod = AccessTools.Method(__instance.GetType(), "GetMountedFootmenRatioModifier"); // Recalculate Cavalry and Footmen on horses speed modifiers based on int menCount = mobileParty.MemberRoster.TotalManCount + additionalTroopOnFootCount + additionalTroopOnHorseCount; float baseNumber = (float)calculateBaseSpeedForPartyMethod.Invoke(__instance, new object[] { menCount }); int horsemenCount = mobileParty.Party.NumberOfMenWithHorse + additionalTroopOnHorseCount; int footmenCount = mobileParty.Party.NumberOfMenWithoutHorse + additionalTroopOnFootCount; int numberOfAvailableMounts = mobileParty.ItemRoster.NumberOfMounts; // Do this instead of calling AddCargoStats() if (mobileParty.AttachedParties.Count != 0) { foreach (var attachedParty in mobileParty.AttachedParties) { menCount += attachedParty.MemberRoster.TotalManCount; horsemenCount += attachedParty.Party.NumberOfMenWithHorse; footmenCount += attachedParty.Party.NumberOfMenWithoutHorse; numberOfAvailableMounts += attachedParty.ItemRoster.NumberOfMounts; // Do this instead of calling AddCargoStats() } } int minFootmenCountNumberOfAvailableMounts = Math.Min(footmenCount, numberOfAvailableMounts); float cavalryRatioModifier = (float)getCavalryRatioModifierMethod.Invoke(__instance, new object[] { menCount, horsemenCount }); float mountedFootmenRatioModifier = (float)getMountedFootmenRatioModifierMethod.Invoke(__instance, new object[] { menCount, minFootmenCountNumberOfAvailableMounts }); // calculate Khuzait bonus and apply float khuzaitRatioModifier = DefaultFeats.Cultural.KhuzaitCavalryAgility.EffectBonus * (cavalryRatioModifier + mountedFootmenRatioModifier); var explainedNumber = new ExplainedNumber(baseNumber, explanation, null); explainedNumber.AddFactor(khuzaitRatioModifier, DefaultFeats.Cultural.KhuzaitCavalryAgility.Name); __result = explainedNumber.ResultNumber; } }
static void Postfix(DefaultPartySpeedCalculatingModel __instance, MobileParty mobileParty, float baseSpeed, StatExplainer explanation, ref float __result) { if (mobileParty.Name.Contains("Patrol")) { if (mobileParty.HomeSettlement.OwnerClan == Clan.PlayerClan) { __result += Settings.Instance.AddPatrolSpeed; } else { __result += Settings.Instance.AddPatrolSpeedForAi; } } }
private static void Postfix(DefaultPartySpeedCalculatingModel __instance, ref StatExplainer explanation, ref float __result, MobileParty mobileParty, ref int additionalTroopOnFootCount, ref int additionalTroopOnHorseCount) { var hero = mobileParty.LeaderHero; if (hero != null && hero.GetPerkValue(DefaultPerks.Riding.NomadicTraditions)) { //have to recalculate cavalry and mounted footman bonuses, so repeat the code var party = mobileParty.Party; float availableHorses = mobileParty.ItemRoster.NumberOfMounts; int totalTroops = mobileParty.MemberRoster.TotalManCount + additionalTroopOnFootCount + additionalTroopOnHorseCount; float mountedTroops = party.NumberOfMenWithHorse + additionalTroopOnHorseCount; float troopsOnFoot = party.NumberOfMenWithoutHorse + additionalTroopOnFootCount; if (mobileParty.AttachedParties.Count != 0) { foreach (var mobileParty2 in mobileParty.AttachedParties) { totalTroops += mobileParty2.MemberRoster.TotalManCount; mountedTroops += mobileParty2.Party.NumberOfMenWithHorse; troopsOnFoot += mobileParty2.Party.NumberOfMenWithoutHorse; availableHorses += mobileParty2.ItemRoster.NumberOfMounts; } } float mountedFootman = Math.Min(availableHorses, troopsOnFoot); var mountedFootmanRatio = totalTroops == 0 ? 0 : mountedFootman / totalTroops; var mountedFootmanMagicNumber = (float)MountedFootmenRatioModifierMethodInfo.Invoke(__instance, new object[] { 1, 1 }); var perkMountedFootmanRatio = GetPerkBaseRatio(mountedFootmanMagicNumber) * mountedFootmanRatio; var cavalryRatio = totalTroops == 0 ? 0 : mountedTroops / totalTroops; var cavalryMagicNumber = (float)CavalryRatioModifierMethodInfo.Invoke(__instance, new object[] { 1, 1 }); var perkCavalryRatio = GetPerkBaseRatio(cavalryMagicNumber) * cavalryRatio; var baseSpeed = (float)BaseSpeedMethodInfo.Invoke(__instance, new object[] { totalTroops }); var explainedNumber = new ExplainedNumber(__result, explanation); explainedNumber.Add(baseSpeed * perkCavalryRatio, ActivePatch._perk.Name); explainedNumber.Add(baseSpeed * perkMountedFootmanRatio, ActivePatch._perk.Name); __result = explainedNumber.ResultNumber; } }
private static void Postfix( DefaultPartySpeedCalculatingModel __instance, ref MobileParty mobileParty, ref float baseSpeed, ref StatExplainer explanation, ref float __result) { // Check if on snowy terrain var atmosphereModel = Campaign.Current.Models.MapWeatherModel.GetAtmosphereModel(CampaignTime.Now, mobileParty.GetPosition()); // Observations as of e1.2.0.226271 is that SnowInfo.Density is between 0.0f and 1.0f if (atmosphereModel.SnowInfo.Density > 0f) { var explainedNumber = new ExplainedNumber(baseSpeed, explanation, null); var movingOnSnowEffectField = AccessTools.Field(typeof(DefaultPartySpeedCalculatingModel), "MovingOnSnowEffect"); var movingOnSnowEffect = (float)movingOnSnowEffectField.GetValue(__instance); var snowDescriptionField = AccessTools.Field(typeof(DefaultPartySpeedCalculatingModel), "_snow"); var snowDescription = (TextObject)snowDescriptionField.GetValue(__instance); // if there is snow on the ground, apply the movement debuff as a factor of the density float snowDensityDebuff = movingOnSnowEffect * atmosphereModel.SnowInfo.Density; explainedNumber.AddFactor(snowDensityDebuff, snowDescription); // Apply bonus to Sturgian party leaders if (mobileParty.Leader != null && mobileParty.Leader.GetFeatValue(DefaultFeats.Cultural.SturgianSnowAgility)) { float sturgianBonusFactor = DefaultFeats.Cultural.SturgianSnowAgility.EffectBonus * Math.Abs(snowDensityDebuff); explainedNumber.AddFactor(sturgianBonusFactor, DefaultFeats.Cultural.SturgianSnowAgility.Name); } __result = explainedNumber.ResultNumber; } }
static void Postfix(DefaultPartySpeedCalculatingModel __instance, ref float __result) { __result *= ConfigLoader.Instance.Config.MountedFootmenSpeedMultiplier; }