示例#1
0
        static void CalculateLearningLimitPostfix(ref ExplainedNumber __result)
        {
            float newLearningLimit = __result.ResultNumber * LEARNING_RATE_LIMIT_MULTIPLIER - __result.ResultNumber;

            __result.AddFactor(newLearningLimit);
            __result.LimitMax(500);
        }
示例#2
0
        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;
            }
        }
示例#3
0
 private static void Postfix(MobileParty mobileParty, ref ExplainedNumber __result)
 {
     if (PartyMilitiaMap.ContainsKey(mobileParty))
     {
         __result.AddFactor(SpeedModifier, new TextObject("Bandit Militia"));
     }
 }
示例#4
0
 static void Postfix(ref ExplainedNumber __result)
 {
     if (AdditionalSpottingRange == 0)
     {
         return;
     }
     __result.AddFactor(AdditionalSpottingRange, new TaleWorlds.Localization.TextObject("CustomSpawns HAX"));
 }
示例#5
0
 static void Postfix(ref int __result, MobileParty mobileParty, StatExplainer explanation = null)
 {
     if (Clan.PlayerClan.Parties.Contains(mobileParty))
     {
         ExplainedNumber result = new ExplainedNumber(0f, explanation);
         result.Add(__result, null);
         result.AddFactor(ConfigLoader.Instance.Config.PlayerTroopWageMultiplier - 1f, new TextObject("Player Troop Wage Multiplier (Tyni)"));
         __result = (int)result.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;
            }
        }
 private static void Patched_AddToStat(ref ExplainedNumber stat, SkillEffect.EffectIncrementType effectIncrementType, float number, TextObject text)
 {
     if (effectIncrementType == SkillEffect.EffectIncrementType.Add)
     {
         stat.Add(number, text);
         return;
     }
     if (effectIncrementType == SkillEffect.EffectIncrementType.AddFactor)
     {
         stat.AddFactor(number, text);
     }
 }
示例#8
0
        public override ExplainedNumber CalculateFinalSpeed(MobileParty mobileParty, ExplainedNumber finalSpeed)
        {
            ExplainedNumber result = base.CalculateFinalSpeed(mobileParty, finalSpeed);

            if (mobileParty.Party == PartyBase.MainParty)
            {
                result.AddFactor(SHADOWFAX_MOVEMENT_BONUS);
            }

            result.LimitMin(1f);
            return(result);
        }
 private static void Patched_AddToStat(ref ExplainedNumber stat, FeatObject.AdditionType additionType, float number, TextObject text)
 {
     if (additionType == FeatObject.AdditionType.Add)
     {
         stat.Add(number, text);
         return;
     }
     if (additionType == FeatObject.AdditionType.AddFactor)
     {
         stat.AddFactor(number, text);
     }
 }
        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;
            }
        }
        private static void AddToStat(ref ExplainedNumber stat, SkillEffect.EffectIncrementType effectIncrementType, float number, TextObject text)
        {
            switch (effectIncrementType)
            {
            case SkillEffect.EffectIncrementType.Add:
                stat.Add(number, text);
                break;

            case SkillEffect.EffectIncrementType.AddFactor:                     // For Way of the ..., should always be AddFactor (this is multiply)
                stat.AddFactor(number * 0.01f, text);
                break;
            }
        }
        private static void TryToApplyBuilderPerk(ref int productionPower, Town town, StatExplainer explanation = null)
        {
            if (!HasGovernorWithBuilderPerk(town))
            {
                return;
            }

            var perk = ActivePatch._perk;
            var productionPowerBonus = new ExplainedNumber(productionPower, explanation);

            productionPowerBonus.AddFactor(perk.PrimaryBonus, perk.Name);

            productionPower = (int)productionPowerBonus.ResultNumber;
        }
示例#13
0
        private static void Postfix(ref float __result, MobileParty mobileParty, StatExplainer explanation)
        {
            var perk = ActivePatch._perk;

            if (!(mobileParty.Army?.LeaderParty?.LeaderHero?.GetPerkValue(perk) ?? false))
            {
                return;
            }

            var explainedNumber = new ExplainedNumber(__result, explanation);

            explainedNumber.AddFactor(perk.PrimaryBonus, perk.Name);

            __result = explainedNumber.ResultNumber;
        }
示例#14
0
        // ReSharper disable once InconsistentNaming
        private static void Postfix(ref int __result, Town town, StatExplainer explanation)
        {
            var perk = ActivePatch._perk;

            if (!(town?.Governor?.GetPerkValue(perk) ?? false))
            {
                return;
            }

            var explainedNumber = new ExplainedNumber(__result, explanation);

            if (explainedNumber.BaseNumber > 0)
            {
                explainedNumber.AddFactor(perk.PrimaryBonus, perk.Name);
                __result = (int)explainedNumber.ResultNumber;
            }
        }
        private static void AddToStat(ref ExplainedNumber stat, SkillEffect.EffectIncrementType effectIncrementType, float number, TextObject text, float newBorn)
        {
            bool flag = effectIncrementType == SkillEffect.EffectIncrementType.Add;

            if (flag)
            {
                stat.Add(number * LightSettlementProsperityModel._vanillaToRatio * newBorn * SubModule.Settings.ProsperityGrowthMultiplier, text, null);
            }
            else
            {
                bool flag2 = effectIncrementType != SkillEffect.EffectIncrementType.AddFactor;
                if (!flag2)
                {
                    stat.AddFactor(number * 0.01f, text);
                }
            }
        }
示例#16
0
        // ReSharper disable once t
        public static void Postfix(ref int __result, Village village, int marketIncome)
        {
            var perk = ActivePatch._perk;

            if (!(village.Bound?.OwnerClan?.Leader?.GetPerkValue(perk) ?? false))
            {
                return;
            }

            if (village.VillageType.PrimaryProduction.IsFood)
            {
                return;
            }

            var explainedNumber = new ExplainedNumber(__result, null);

            explainedNumber.AddFactor(perk.PrimaryBonus, perk.Description);
            __result = (int)explainedNumber.ResultNumber;
        }
示例#17
0
        private static void Postfix1(ref int __result, Town town, StatExplainer explanation)
        {
            var kingdom = town.Owner?.Settlement?.OwnerClan?.Kingdom;

            if (kingdom == null)
            {
                return;
            }

            if (kingdom.ActivePolicies.Contains(DefaultPolicies.LandGrantsForVeterans))
            {
                var explainedNumber = new ExplainedNumber(__result, explanation);
                if (explainedNumber.BaseNumber > 0)
                {
                    explainedNumber.AddFactor(-0.05f, DefaultPolicies.LandGrantsForVeterans.Name);
                    __result = (int)explainedNumber.ResultNumber;
                }
            }
        }
示例#18
0
        public static bool GetDailyHealingHpForHeroes(ref float __result, MobileParty party, StatExplainer explanation, TextObject ____settlementText, TextObject ____starvingText, TextObject ____bushDoctorPerkText)
        {
            ExplainedNumber explainedNumber = new ExplainedNumber(2f, explanation, null);

            SkillHelper.AddSkillBonusForParty(DefaultSkills.Medicine, DefaultSkillEffects.HealingRateBonus, party, ref explainedNumber);
            if (party.CurrentSettlement != null || party.LastVisitedSettlement != null && party.LastVisitedSettlement.IsVillage && party.LastVisitedSettlement.Position2D.DistanceSquared(party.Position2D) < 1f)
            {
                explainedNumber.Add(5f, ____settlementText);
            }
            if (!party.IsGarrison && !party.IsMilitia)
            {
                if (party.PartyMoveMode != MoveModeType.Hold)
                {
                    PerkHelper.AddPerkBonusForParty(DefaultPerks.Medicine.WalkItOff, party, ref explainedNumber);
                }
                else
                {
                    PerkHelper.AddPerkBonusForParty(DefaultPerks.Medicine.TriageTent, party, ref explainedNumber);
                }
            }
            if (party.Morale >= Campaign.Current.Models.PartyMoraleModel.HighMoraleValue)
            {
                PerkHelper.AddPerkBonusForParty(DefaultPerks.Medicine.BestMedicine, party, ref explainedNumber);
            }
            if (party.CurrentSettlement != null)
            {
                explainedNumber.Add(5f, ____settlementText);
                if (party.CurrentSettlement.IsTown && party.SiegeEvent == null && !party.CurrentSettlement.IsUnderSiege)
                {
                    PerkHelper.AddPerkBonusForParty(DefaultPerks.Medicine.GoodLodging, party, ref explainedNumber);
                }
            }
            else if (!party.IsMoving && party.LastVisitedSettlement != null && party.LastVisitedSettlement.IsVillage && party.LastVisitedSettlement.Position2D.DistanceSquared(party.Position2D) < 1f && !party.IsRaiding && !party.LastVisitedSettlement.IsUnderRaid && party.HasPerk(DefaultPerks.Medicine.BushDoctor))
            {
                explainedNumber.AddFactor(DefaultPerks.Medicine.BushDoctor.SecondaryBonus, ____bushDoctorPerkText);
            }
            if (party.Party.IsStarving && party.CurrentSettlement == null)
            {
                explainedNumber.Add(-5f, ____starvingText);
            }
            __result = explainedNumber.ResultNumber;
            return(false);
        }
 private static void AddToStat(
     ref ExplainedNumber stat,
     SkillEffect.EffectIncrementType effectIncrementType,
     float number,
     TextObject text,
     float newBorn)
 {
     if (effectIncrementType == SkillEffect.EffectIncrementType.Add)
     {
         stat.Add(number * _vanillaToRatio * newBorn * SubModule.Settings.prosperityGrowthMultiplier, text);
     }
     else
     {
         if (effectIncrementType != SkillEffect.EffectIncrementType.AddFactor)
         {
             return;
         }
         stat.AddFactor(number * 0.01f, text);
     }
 }
        static bool Prefix(DefaultCharacterDevelopmentModel __instance,
                           int attributeValue, int focusValue, int skillValue, int characterLevel, TextObject attributeName, StatExplainer explainer, ref float __result)
        {
            if (attributeValue == 11)
            {
                skillValue -= (int)(attributeValue * Reworked_SkillsSubModule.__ATTR_VALUE + focusValue * Reworked_SkillsSubModule.__FOCUS_VALUE);
            }
            ExplainedNumber explainedNumber = new ExplainedNumber(0, explainer, (TextObject)null);
            float           BaseByLevel     = (float)(20.0 / (10.0 + (double)characterLevel));
            float           Attribute       = 0.4f * (float)10;
            float           Focus           = (float)5 * 1f;

            if (Reworked_SkillsSubModule.__DEFAULTLEARNING)
            {
                explainedNumber.Add(BaseByLevel, _LevelText);
                explainedNumber.Add(Attribute, attributeName);
                explainedNumber.Add(Focus, _skillFocusText);
            }
            else if (Reworked_SkillsSubModule.__DEFAULTNORMALIZEDLEARNING)
            {
                float penalty = Math.Max(0, Reworked_SkillsSubModule.__SKILLPNLT - skillValue) / Reworked_SkillsSubModule.__SKILLPNLTDV;
                explainedNumber.Add(BaseByLevel, _LevelText);
                explainedNumber.Add(Attribute, attributeName);
                explainedNumber.Add(Focus, _skillFocusText);
                explainedNumber.Add(-penalty, _NormalizedPenaltyText);
            }
            else if (Reworked_SkillsSubModule.__FIXEDRATE)
            {
                explainedNumber.Add(Reworked_SkillsSubModule.__FIXEDLEARNINGRATE, _FixedRateText);
            }
            int learningLimit = Reworked_SkillsSubModule.__LEANRINGLIMIT;// __instance.CalculateLearningLimit(10, 5, (TextObject)null, (StatExplainer)null);

            if (skillValue > learningLimit)
            {
                int num = skillValue - learningLimit;
                explainedNumber.AddFactor((float)(-1.0 - 0.100000001490116 * (double)num), _overLimitText);
            }
            explainedNumber.LimitMin(0.0f);
            __result = explainedNumber.ResultNumber;
            return(false); // make sure you only skip if really necessary
        }
        private static void TryToApplyConstructionExpert(ref int productionPower, Town town, StatExplainer explanation = null)
        {
            var perk = ActivePatch._perk;

            if (town.BuildingsInProgress.IsEmpty())
            {
                return;
            }
            var building = town.BuildingsInProgress.Peek();

            if (!ShouldApplyConstructionExpertPerk(town, building))
            {
                return;
            }

            var productionPowerBonus = new ExplainedNumber(productionPower, explanation);

            productionPowerBonus.AddFactor(perk.PrimaryBonus, perk.Name);

            productionPower = (int)productionPowerBonus.ResultNumber;
        }
        private static void Postfix(ref float __result, Town town, StatExplainer tooltipStringBuilder)
        {
            var perk = ActivePatch._perk;

            if (!town.IsUnderSiege)
            {
                return;
            }

            var leader = town.Settlement?.OwnerClan?.Leader;

            if (leader == null || !leader.GetPerkValue(perk))
            {
                return;
            }

            var explainedNumber = new ExplainedNumber(__result, tooltipStringBuilder);

            explainedNumber.AddFactor(perk.PrimaryBonus, perk.Name);

            __result = explainedNumber.BaseNumber;
        }
示例#23
0
 private void GetBattleXpBonusFromPerks(PartyBase party, ref ExplainedNumber xpToGain, CharacterObject troop)
 {
     if (party.IsMobile && party.MobileParty.LeaderHero != null)
     {
         if (!troop.IsArcher && party.MobileParty.HasPerk(DefaultPerks.OneHanded.Trainer, true))
         {
             xpToGain.AddFactor(DefaultPerks.OneHanded.Trainer.SecondaryBonus * 0.01f, DefaultPerks.OneHanded.Trainer.Name);
         }
         if (troop.IsInfantry)
         {
             if (party.MobileParty.HasPerk(DefaultPerks.OneHanded.CorpsACorps, false))
             {
                 xpToGain.AddFactor(DefaultPerks.OneHanded.CorpsACorps.PrimaryBonus * 0.01f, DefaultPerks.OneHanded.CorpsACorps.Name);
             }
             if (party.MobileParty.HasPerk(DefaultPerks.TwoHanded.BaptisedInBlood, true))
             {
                 xpToGain.AddFactor(DefaultPerks.TwoHanded.BaptisedInBlood.SecondaryBonus * 0.01f, DefaultPerks.TwoHanded.BaptisedInBlood.Name);
             }
         }
         if (party.MobileParty.HasPerk(DefaultPerks.OneHanded.LeadByExample, false))
         {
             xpToGain.AddFactor(DefaultPerks.OneHanded.LeadByExample.PrimaryBonus * 0.01f, DefaultPerks.OneHanded.LeadByExample.Name);
         }
         if (party.MobileParty.HasPerk(DefaultPerks.Leadership.Companions, false))
         {
             xpToGain.AddFactor(DefaultPerks.Leadership.Companions.PrimaryBonus * 0.01f, DefaultPerks.Leadership.Companions.Name);
         }
         if (troop.IsArcher && party.MobileParty.HasPerk(DefaultPerks.Crossbow.MountedCrossbowman, true))
         {
             xpToGain.AddFactor(DefaultPerks.Crossbow.MountedCrossbowman.SecondaryBonus * 0.01f, DefaultPerks.Crossbow.MountedCrossbowman.Name);
         }
     }
     if (party.IsMobile && party.MobileParty.IsGarrison)
     {
         Settlement currentSettlement = party.MobileParty.CurrentSettlement;
         if (((currentSettlement != null) ? currentSettlement.Town.Governor : null) != null)
         {
             PerkHelper.AddPerkBonusForTown(DefaultPerks.TwoHanded.Yadomejutsu, party.MobileParty.CurrentSettlement.Town, ref xpToGain);
             if (troop.IsMounted)
             {
                 PerkHelper.AddPerkBonusForTown(DefaultPerks.Polearm.Guards, party.MobileParty.CurrentSettlement.Town, ref xpToGain);
             }
         }
     }
 }
示例#24
0
        public static bool Prefix(Hero hero)
        {
            bool   result        = true;
            bool   proceed       = false;
            bool   playerProceed = false;
            string text          = " has escaped";

            try
            {
                bool isPlayer = hero.IsPrisoner && hero.PartyBelongedToAsPrisoner != null &&
                                (hero.PartyBelongedToAsPrisoner.IsMobile &&
                                 hero.PartyBelongedToAsPrisoner == PartyBase.MainParty ||
                                 hero.PartyBelongedToAsPrisoner.IsSettlement &&
                                 hero.PartyBelongedToAsPrisoner.Settlement.OwnerClan == Clan.PlayerClan);

                bool  enable           = isPlayer || Support.settings.ai_applied;
                float generalChance    = enable ? (float)Support.settings.general_chance : 1;
                float travelChance     = enable ? (float)Support.settings.traveling_chance : 1;
                float settlementChance = enable ? (float)Support.settings.settlement_chance : 1;

                // ***************************************
                // Original method from decompiled source (except for commented lines)
                // ***************************************
                if (!hero.IsPrisoner || hero.PartyBelongedToAsPrisoner == null || hero == Hero.MainHero)
                {
                    return(false);
                }
                float baseNumber = 0.05f /**/ * generalChance /**/;  // general chance modificaiton
                if (hero.PartyBelongedToAsPrisoner.IsMobile && hero.PartyBelongedToAsPrisoner.MobileParty.CurrentSettlement == null)
                {
                    // travel chance modification
                    baseNumber *= (5f - (float)Math.Pow(Math.Min(81, hero.PartyBelongedToAsPrisoner.NumberOfHealthyMembers), 0.25)) /**/ * travelChance /**/;
                    /**/ text   = " slipped away from " + (hero.IsFemale ? "her" : "his") + " guards and escaped"; /**/
                }
                // settlement chance modification begin
                else if (hero.PartyBelongedToAsPrisoner.IsSettlement)
                {
                    baseNumber *= settlementChance;
                    text        = " is missing from " + (hero.IsFemale ? "her" : "his") + " cell";
                }
                // end
                if (hero.PartyBelongedToAsPrisoner == PartyBase.MainParty || hero.PartyBelongedToAsPrisoner.IsSettlement && hero.PartyBelongedToAsPrisoner.Settlement.OwnerClan == Clan.PlayerClan || hero.PartyBelongedToAsPrisoner.IsMobile && hero.PartyBelongedToAsPrisoner.MobileParty.CurrentSettlement != null && hero.PartyBelongedToAsPrisoner.MobileParty.CurrentSettlement.OwnerClan == Clan.PlayerClan)
                {
                    baseNumber *= 0.5f;
                }
                ExplainedNumber explainedNumber = new ExplainedNumber(baseNumber);
                if (hero.PartyBelongedToAsPrisoner.IsSettlement)
                {
                    if (hero.PartyBelongedToAsPrisoner.Settlement.IsTown)
                    {
                        PerkHelper.AddPerkBonusForTown(DefaultPerks.Riding.MountedPatrols, hero.PartyBelongedToAsPrisoner.Settlement.Town, ref explainedNumber);
                        PerkHelper.AddPerkBonusForTown(DefaultPerks.Roguery.SweetTalker, hero.PartyBelongedToAsPrisoner.Settlement.Town, ref explainedNumber);
                    }
                    if (hero.PartyBelongedToAsPrisoner.Settlement.IsTown || hero.PartyBelongedToAsPrisoner.Settlement.IsCastle)
                    {
                        PerkHelper.AddPerkBonusForTown(DefaultPerks.Engineering.PrisonArchitect, hero.PartyBelongedToAsPrisoner.Settlement.Town, ref explainedNumber);
                    }
                }
                if (hero.PartyBelongedToAsPrisoner.IsMobile)
                {
                    if (hero.Clan != null && hero.Clan.Leader != null && hero.Clan.Leader.GetPerkValue(DefaultPerks.Roguery.FleetFooted))
                    {
                        explainedNumber.AddFactor(DefaultPerks.Roguery.FleetFooted.SecondaryBonus);
                    }
                    if (hero.PartyBelongedToAsPrisoner.MobileParty.HasPerk(DefaultPerks.Riding.MountedPatrols))
                    {
                        PerkHelper.AddPerkBonusForParty(DefaultPerks.Riding.MountedPatrols, hero.PartyBelongedToAsPrisoner.MobileParty, true, ref explainedNumber);
                    }
                    if (hero.PartyBelongedToAsPrisoner.MobileParty.HasPerk(DefaultPerks.Roguery.RansomBroker))
                    {
                        PerkHelper.AddPerkBonusForParty(DefaultPerks.Roguery.RansomBroker, hero.PartyBelongedToAsPrisoner.MobileParty, false, ref explainedNumber);
                    }
                }
                if (hero.PartyBelongedToAsPrisoner.IsMobile && hero.PartyBelongedToAsPrisoner.MobileParty.HasPerk(DefaultPerks.Scouting.KeenSight, true))
                {
                    PerkHelper.AddPerkBonusForParty(DefaultPerks.Scouting.KeenSight, hero.PartyBelongedToAsPrisoner.MobileParty, false, ref explainedNumber);
                }
                if (MBRandom.RandomFloat >= explainedNumber.ResultNumber)
                {
                    // Relation modification begin
                    if (isPlayer && Support.settings.daily_penalty != 0)
                    {
                        Support.ChangeRelation(Hero.MainHero, hero, -Support.settings.daily_penalty);
                        Support.ChangeFamilyRelation(Hero.MainHero, hero, 0, -Support.settings.daily_penalty);
                    }
                    // end
                    return(false);
                }
                EndCaptivityAction.ApplyByEscape(hero);
                // Notification modification begin
                if (isPlayer)
                {
                    Support.LogMessage(hero.Name.ToString() + " " + text);
                }
                // end
                return(false);
            }
            catch (Exception exe) { }

            return(result);
        }
        public static bool Prefix(DefaultClanFinanceModel __instance, ref float __result, Clan clan, StatExplainer explanation = null, bool applyWithdrawals = false)
        {
            bool alt = Input.IsKeyDown(InputKey.LeftAlt) || Input.IsKeyDown(InputKey.RightAlt);

            if (clan == Clan.PlayerClan && !alt)
            {
                ExplainedNumber goldChange = new ExplainedNumber(0.0f, explanation);

                // Income
                StatExplainer   incomeExplaination = new StatExplainer();
                ExplainedNumber incomeNumber       = new ExplainedNumber(0.0f, incomeExplaination);
                __instance.CalculateClanIncome(clan, ref incomeNumber, applyWithdrawals);

                List <LineGroup> incomeGroups = new List <LineGroup>();
                if (Settings.IncomeGroups.Count > 0)
                {
                    incomeGroups.AddRange(Settings.IncomeGroups);
                }

                LineGroup[] incomeGroupArray = incomeGroups.ToArray();
                float       otherIncome      = 0f;

                foreach (StatExplainer.ExplanationLine line in incomeExplaination.Lines)
                {
                    string desc    = line.Name.ToLower();
                    bool   matched = false;

                    for (int i = 0; i < incomeGroupArray.Length; i++)
                    {
                        string matchAgainst = (incomeGroupArray[i].CaseSensitive ? line.Name : desc);
                        foreach (string match in incomeGroups[i].Matches)
                        {
                            if (matchAgainst.Contains(match))
                            {
                                incomeGroupArray[i].Gold += line.Number;
                                matched = true;
                                break;
                            }
                        }
                        if (matched)
                        {
                            break;
                        }
                    }
                    if (!matched)
                    {
                        otherIncome += line.Number;
                        if (Settings.DebugModeEnabled)
                        {
                            InformationManager.DisplayMessage(new InformationMessage("Unknown Income: " + line.Name));
                        }
                    }
                }

                foreach (LineGroup incomeGroup in incomeGroupArray)
                {
                    if (incomeGroup.Gold != 0f)
                    {
                        goldChange.Add(incomeGroup.Gold, new TextObject(incomeGroup.Label));
                    }
                }

                if (otherIncome != 0f)
                {
                    goldChange.Add(otherIncome, new TextObject("Miscellaneous Income"));
                }

                // Kingdom Tribute. Directly lifted from DefaultClanFinanceModel.CalculateKingdomTribute()
                if (clan.Kingdom != null)
                {
                    ExplainedNumber tributeNumber = new ExplainedNumber(0.0f);
                    foreach (KingdomTribute kingdomTribute in clan.Kingdom.KingdomTributes)
                    {
                        tributeNumber.AddFactor((float)(-kingdomTribute.Percentage * 0.01), new TextObject("{=AtFv5RMW}Kingdom Tribute"));
                    }
                    goldChange.Add(tributeNumber.ResultNumber, new TextObject("Kingdom Tributes"));
                }

                // Expenses
                StatExplainer   expenseExplanation = new StatExplainer();
                ExplainedNumber expenseNumber      = new ExplainedNumber(0.0f, expenseExplanation);
                __instance.CalculateClanExpenses(clan, ref expenseNumber, applyWithdrawals);

                string playerName          = Hero.MainHero.Name.ToString();
                string playerNamePosessive = playerName + (playerName.EndsWith("s") ? "'" : "'s");

                List <LineGroup> expenseGroups = new List <LineGroup>()
                {
                    new LineGroup(playerNamePosessive + " Party Wages", new List <string> {
                        playerName
                    }, true)
                };

                if (Settings.ExpenseGroups.Count > 0)
                {
                    expenseGroups.AddRange(Settings.ExpenseGroups);
                }

                LineGroup[] expenseGroupArray = expenseGroups.ToArray();
                float       otherExpenses     = 0f;

                foreach (StatExplainer.ExplanationLine line in expenseExplanation.Lines)
                {
                    string desc    = line.Name.ToLower();
                    bool   matched = false;

                    for (int i = 0; i < expenseGroupArray.Length; i++)
                    {
                        string matchAgainst = (expenseGroupArray[i].CaseSensitive ? line.Name : desc);
                        foreach (string match in expenseGroupArray[i].Matches)
                        {
                            if (matchAgainst.Contains(match))
                            {
                                expenseGroupArray[i].Gold += line.Number;
                                matched = true;
                                break;
                            }
                        }
                        if (matched)
                        {
                            break;
                        }
                    }
                    if (!matched)
                    {
                        otherExpenses += line.Number;
                        if (Settings.DebugModeEnabled)
                        {
                            InformationManager.DisplayMessage(new InformationMessage("Unknown Expense: " + line.Name));
                        }
                    }
                }

                foreach (LineGroup expenseGroup in expenseGroupArray)
                {
                    if (expenseGroup.Gold != 0f)
                    {
                        goldChange.Add(expenseGroup.Gold, new TextObject(expenseGroup.Label));
                    }
                }

                if (otherExpenses != 0f)
                {
                    goldChange.Add(otherExpenses, new TextObject("Miscellaneous Expenses"));
                }

                __result = goldChange.ResultNumber;

                return(false);
            }

            return(true);
        }
示例#26
0
 public static void CalculateClanExpenses(Clan clan, ref ExplainedNumber goldChange, bool applyWithdrawals = false) =>
 goldChange.AddFactor(
     Math.Max(
         clan.GetPartyBonus(bonuses => bonuses.ExpensesMultiplier, null) - 1,
         -Config.Instance.max_bonus_decreas),
     new TextObject("Decreasing expenses for Leaders' INT"));
        public override float CalculateFinalSpeed(MobileParty mobileParty, float baseSpeed, StatExplainer explanation)
        {
            try
            {
                PartyBase       party           = mobileParty.Party;
                ExplainedNumber explainedNumber = new ExplainedNumber(baseSpeed, explanation, null);
                explainedNumber.LimitMin(1f);
                string key = CampaignUtils.IsolateMobilePartyStringID(mobileParty); //TODO if this is non-trivial make it more efficient
                if (partyIDToBaseSpeed.ContainsKey(key) && partyIDToBaseSpeed[key] != float.MinValue)
                {
                    float bs = partyIDToBaseSpeed[key];
                    explainedNumber.Add(bs - explainedNumber.ResultNumber, explanationText);
                }
                else if (partyIDToExtraSpeed.ContainsKey(key))
                {
                    float extra = partyIDToExtraSpeed[key];
                    explainedNumber.Add(extra, explanationText);
                }
                TerrainType faceTerrainType = Campaign.Current.MapSceneWrapper.GetFaceTerrainType(mobileParty.CurrentNavigationFace);
                float       num             = explainedNumber.ResultNumber;
                if (partyIDToMinimumSpeed.ContainsKey(key))//minimum adjustment
                {
                    num = Math.Max(num, partyIDToMinimumSpeed[key]);
                }
                else
                {
                    explainedNumber.LimitMin(1f);
                }

                if (partyIDToMaximumSpeed.ContainsKey(key))//maximum adjustment
                {
                    num = Math.Min(num, partyIDToMaximumSpeed[key]);
                }

                explainedNumber.Add(num - explainedNumber.ResultNumber, new TextObject("Custom Spawns final modification"));
                if (faceTerrainType == TerrainType.Forest)
                {
                    explainedNumber.AddFactor(-0.3f, _movingInForest);
                    PerkHelper.AddFeatBonusForPerson(DefaultFeats.Cultural.BattanianForestAgility, mobileParty.Leader, ref explainedNumber);
                }
                else if (faceTerrainType == TerrainType.Water || faceTerrainType == TerrainType.River || faceTerrainType == TerrainType.Bridge || faceTerrainType == TerrainType.ShallowRiver)
                {
                    explainedNumber.AddFactor(-0.3f, _fordEffect);
                }
                if (Campaign.Current.IsNight)
                {
                    explainedNumber.AddFactor(-0.25f, _night);
                }
                if (faceTerrainType == TerrainType.Snow)
                {
                    explainedNumber.AddFactor(-0.1f, _snow);
                    if (party.Leader != null)
                    {
                        PerkHelper.AddFeatBonusForPerson(DefaultFeats.Cultural.SturgianSnowAgility, party.Leader, ref explainedNumber);
                    }
                }
                return(explainedNumber.ResultNumber);
            }
            catch (Exception e)
            {
                ErrorHandler.HandleException(e, " MOBILE PARTY FINAL SPEED CALCULATION ");
                return(1f);
            }
        }
示例#28
0
        private static void Postfix(ref float __result, MobileParty mobileParty, float baseSpeed, StatExplainer explanation)
        {
            if (mobileParty.LeaderHero == null)
            {
                return;
            }

            var             leader          = mobileParty.LeaderHero;
            PartyBase       party           = mobileParty.Party;
            ExplainedNumber bonuses         = new ExplainedNumber(__result, explanation);
            TerrainType     faceTerrainType = Campaign.Current.MapSceneWrapper.GetFaceTerrainType(mobileParty.CurrentNavigationFace);

            switch (faceTerrainType)
            {
            case TerrainType.Forest:
                if (leader.GetPerkValue(DefaultPerks.Scouting.ForestLore))
                {
                    bonuses.AddFactor(0.05f, DefaultPerks.Scouting.ForestLore.Name);
                }
                break;

            case TerrainType.Desert:
                if (leader.GetPerkValue(DefaultPerks.Scouting.DesertLore))
                {
                    bonuses.AddFactor(0.05f, DefaultPerks.Scouting.DesertLore.Name);
                }
                break;

            case TerrainType.Mountain:
                if (leader.GetPerkValue(DefaultPerks.Scouting.HillsLore))
                {
                    bonuses.AddFactor(0.05f, DefaultPerks.Scouting.HillsLore.Name);
                }

                break;

            case TerrainType.Swamp:
                if (leader.GetPerkValue(DefaultPerks.Scouting.MarshesLore))
                {
                    bonuses.AddFactor(0.05f, DefaultPerks.Scouting.MarshesLore.Name);
                }

                break;

            case TerrainType.Steppe:
                var scoutingGrasslandNavigator = PerkObject.FindFirst(a => a.Name.GetID() == "Ekqj9IFR");
                if (scoutingGrasslandNavigator != null && leader.GetPerkValue(scoutingGrasslandNavigator))
                {
                    bonuses.AddFactor(0.05f, scoutingGrasslandNavigator.Name);
                }
                break;

            case TerrainType.Water:
            case TerrainType.Bridge:
            case TerrainType.River:
            case TerrainType.ShallowRiver:


                break;
            }
            //第一层
            if (!Campaign.Current.IsNight)
            {
                if (leader.GetPerkValue(DefaultPerks.Scouting.Pathfinder) || (mobileParty.Scout != null && mobileParty.Scout.GetPerkValue(DefaultPerks.Scouting.Pathfinder)))
                {
                    bonuses.AddFactor(0.01f, DefaultPerks.Scouting.Pathfinder.Name);
                }
            }
            else
            {
                if (leader.GetPerkValue(DefaultPerks.Scouting.TorchCarriers) || (mobileParty.Scout != null && mobileParty.Scout.GetPerkValue(DefaultPerks.Scouting.TorchCarriers)))
                {
                    bonuses.AddFactor(0.02f, DefaultPerks.Scouting.TorchCarriers.Name);
                }
            }
            //2
            if (leader.GetPerkValue(DefaultPerks.Scouting.Navigator) || (mobileParty.Scout != null && mobileParty.Scout.GetPerkValue(DefaultPerks.Scouting.Navigator)))
            {
                bonuses.AddFactor(0.01f, DefaultPerks.Scouting.Navigator.Name);
            }

            var ScoutingExtra2 = PerkObject.FindFirst(a => a.Name.GetID() == "P68GX3zY");//{=P68GX3zY}Lay of the land", "{=RchM1puc} Extra 3% movement speed on map.

            if (ScoutingExtra2 != null && leader.GetPerkValue(ScoutingExtra2))
            {
                bonuses.AddFactor(0.03f, ScoutingExtra2.Name);
            }
            bonuses.LimitMin(1f);
            __result = bonuses.ResultNumber;
        }
        public override float CalculateFinalSpeed(MobileParty mobileParty, float baseSpeed, StatExplainer explanation)
        {
            PartyBase       party           = mobileParty.Party;
            ExplainedNumber explainedNumber = new ExplainedNumber(baseSpeed, explanation, null);
            TerrainType     faceTerrainType = Campaign.Current.MapSceneWrapper.GetFaceTerrainType(mobileParty.CurrentNavigationFace);

            if (faceTerrainType == TerrainType.Forest)
            {
                explainedNumber.AddFactor(MovingAtForestEffect, _movingInForest);
                // @CFF - Reduce the effect of forest instead of calculating off of base speed
                // PerkHelper.AddFeatBonusForPerson(DefaultFeats.Cultural.BattanianForestAgility, mobileParty.Leader, ref explainedNumber);

                // @CFF - Replace call to PerkHelper.AddFeatBonusForPerson and subsequent private calls
                if (mobileParty.Leader != null && mobileParty.Leader.GetFeatValue(DefaultFeats.Cultural.BattanianForestAgility))
                {
                    float battanianBonusFactor = Math.Abs(MovingAtForestEffect) * DefaultFeats.Cultural.BattanianForestAgility.EffectBonus;

                    if (DefaultFeats.Cultural.BattanianForestAgility.IncrementType == FeatObject.AdditionType.AddFactor)
                    {
                        explainedNumber.AddFactor(battanianBonusFactor, DefaultFeats.Cultural.BattanianForestAgility.Name);
                    }
                    else if (DefaultFeats.Cultural.BattanianForestAgility.IncrementType == FeatObject.AdditionType.Add)
                    {
                        // Backwards compatibility in case the modifier is set to Add in the future
                        explainedNumber.Add(battanianBonusFactor, DefaultFeats.Cultural.BattanianForestAgility.Name);
                    }
                    else
                    {
                        // This should not occur, explicitly do nothing
                    }
                }
            }

            else if (faceTerrainType == TerrainType.Water || faceTerrainType == TerrainType.River || faceTerrainType == TerrainType.Bridge || faceTerrainType == TerrainType.ShallowRiver)
            {
                explainedNumber.AddFactor(MovingAtWaterEffect, _fordEffect);
            }
            if (Campaign.Current.IsNight)
            {
                explainedNumber.AddFactor(MovingAtNightEffect, _night);
            }

            // @CFF - BUG: faceTerrainType is never TerrainType.Snow

            /*
             * if (faceTerrainType == TerrainType.Snow) {
             *  explainedNumber.AddFactor(MovingOnSnowEffect, _snow);
             *  if (party.Leader != null) {
             *      PerkHelper.AddFeatBonusForPerson(DefaultFeats.Cultural.SturgianSnowAgility, party.Leader, ref explainedNumber);
             *  }
             * }
             */

            // @CFF - Replace snow detection
            // Get the current weather for the party position
            var atmosphereModel = Campaign.Current.Models.MapWeatherModel.GetAtmosphereModel(CampaignTime.Now, mobileParty.GetPosition());

            if (atmosphereModel.SnowInfo.Density > 0f)
            {
                // 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, _snow);

                // @CFF - Replace call to PerkHelper.AddFeatBonusForPerson and subsequent private calls
                if (mobileParty.Leader != null && mobileParty.Leader.GetFeatValue(DefaultFeats.Cultural.SturgianSnowAgility))
                {
                    float sturgianBonusFactor = Math.Abs(snowDensityDebuff) * DefaultFeats.Cultural.SturgianSnowAgility.EffectBonus;

                    if (DefaultFeats.Cultural.SturgianSnowAgility.IncrementType == FeatObject.AdditionType.AddFactor)
                    {
                        explainedNumber.AddFactor(sturgianBonusFactor, DefaultFeats.Cultural.SturgianSnowAgility.Name);
                    }
                    else if (DefaultFeats.Cultural.SturgianSnowAgility.IncrementType == FeatObject.AdditionType.Add)
                    {
                        explainedNumber.Add(sturgianBonusFactor, DefaultFeats.Cultural.SturgianSnowAgility.Name);
                    }
                    else
                    {
                        // This should not occur, explicitly do nothing
                    }
                }
            }

            explainedNumber.LimitMin(1f);
            return(explainedNumber.ResultNumber);
        }
        public override float CalculatePureSpeed(MobileParty mobileParty, StatExplainer explanation, int additionalTroopOnFootCount = 0, int additionalTroopOnHorseCount = 0)
        {
            if (mobileParty.Army != null && mobileParty.Army.LeaderParty.AttachedParties.Contains(mobileParty))
            {
                return(this.CalculatePureSpeed(mobileParty.Army.LeaderParty, explanation, 0, 0));
            }

            PartyBase party = mobileParty.Party;
            int       numberOfAvailableMounts = 0;
            float     totalWeightCarried      = 0f;
            int       herdSize = 0;
            int       menCount = mobileParty.MemberRoster.TotalManCount + additionalTroopOnFootCount + additionalTroopOnHorseCount;

            AddCargoStats(mobileParty, ref numberOfAvailableMounts, ref totalWeightCarried, ref herdSize);

            float totalWeightOfItems = GetTotalWeightOfItems(mobileParty);
            int   inventryCapacity   = Campaign.Current.Models.InventoryCapacityModel.CalculateInventoryCapacity(mobileParty, null, additionalTroopOnFootCount, additionalTroopOnHorseCount, 0, false);
            int   horsemenCount      = party.NumberOfMenWithHorse + additionalTroopOnHorseCount;
            int   footmenCount       = party.NumberOfMenWithoutHorse + additionalTroopOnFootCount;
            int   woundedCount       = party.MemberRoster.TotalWounded;
            int   prisonerCount      = party.PrisonRoster.TotalManCount;
            float morale             = mobileParty.Morale;

            if (mobileParty.AttachedParties.Count != 0)
            {
                foreach (MobileParty attachedParty in mobileParty.AttachedParties)
                {
                    AddCargoStats(attachedParty, ref numberOfAvailableMounts, ref totalWeightCarried, ref herdSize);
                    menCount           += attachedParty.MemberRoster.TotalManCount;
                    totalWeightOfItems += GetTotalWeightOfItems(attachedParty);
                    inventryCapacity   += Campaign.Current.Models.InventoryCapacityModel.CalculateInventoryCapacity(attachedParty, null, 0, 0, 0, false);
                    horsemenCount      += attachedParty.Party.NumberOfMenWithHorse;
                    footmenCount       += attachedParty.Party.NumberOfMenWithoutHorse;
                    woundedCount       += attachedParty.MemberRoster.TotalWounded;
                    prisonerCount      += attachedParty.PrisonRoster.TotalManCount;
                }
            }
            float           baseNumber           = CalculateBaseSpeedForParty(menCount);
            ExplainedNumber explainedNumber      = new ExplainedNumber(baseNumber, explanation, null);
            float           cavalryRatioModifier = this.GetCavalryRatioModifier(menCount, horsemenCount);

            explainedNumber.AddFactor(cavalryRatioModifier, _textCavalry);

            int   min_footmenCount_numberOfAvailableMounts = Math.Min(footmenCount, numberOfAvailableMounts);
            float mountedFootmenRatioModifier = this.GetMountedFootmenRatioModifier(menCount, min_footmenCount_numberOfAvailableMounts);

            explainedNumber.AddFactor(mountedFootmenRatioModifier, _textMountedFootmen);

            if (mobileParty.Leader != null)
            {
                // @CFF - Calculates off of base value instead of (cavalry + footmen on horses) * bonus
                // PerkHelper.AddFeatBonusForPerson(DefaultFeats.Cultural.KhuzaitCavalryAgility, mobileParty.Leader, ref explainedNumber);

                // @CFF - Replace call to PerkHelper.AddFeatBonusForPerson and subsequent private calls
                if (mobileParty.Leader != null && mobileParty.Leader.GetFeatValue(DefaultFeats.Cultural.KhuzaitCavalryAgility))
                {
                    // Add khuzait bonus based on cavalry horsemen bonus already applied instead of base
                    float khuzaitBonusFactor = (cavalryRatioModifier + mountedFootmenRatioModifier) * DefaultFeats.Cultural.KhuzaitCavalryAgility.EffectBonus;
                    if (DefaultFeats.Cultural.KhuzaitCavalryAgility.IncrementType == FeatObject.AdditionType.AddFactor)
                    {
                        explainedNumber.AddFactor(khuzaitBonusFactor, DefaultFeats.Cultural.KhuzaitCavalryAgility.Name);
                    }
                    else if (DefaultFeats.Cultural.KhuzaitCavalryAgility.IncrementType == FeatObject.AdditionType.Add)
                    {
                        // Backwards compatibility in case the modifier is set to Add in the future
                        explainedNumber.Add(khuzaitBonusFactor, DefaultFeats.Cultural.KhuzaitCavalryAgility.Name);
                    }
                    else
                    {
                        // This should not occur, explicitly do nothing
                    }
                }
            }

            float num12 = Math.Min(totalWeightOfItems, (float)inventryCapacity);

            if (num12 > 0f)
            {
                float cargoEffect = this.GetCargoEffect(num12, inventryCapacity);
                explainedNumber.AddFactor(cargoEffect, _textCargo);
            }
            if (totalWeightCarried > (float)inventryCapacity)
            {
                float overBurdenedEffect = this.GetOverBurdenedEffect(totalWeightCarried - (float)inventryCapacity, inventryCapacity);
                explainedNumber.AddFactor(overBurdenedEffect, _textOverburdened);
            }
            if (mobileParty.Party.NumberOfAllMembers > mobileParty.Party.PartySizeLimit)
            {
                float overPartySizeEffect = this.GetOverPartySizeEffect(mobileParty);
                explainedNumber.AddFactor(overPartySizeEffect, _textOverPartySize);
            }
            if (mobileParty.Party.NumberOfPrisoners > mobileParty.Party.PrisonerSizeLimit)
            {
                float overPrisonerSizeEffect = this.GetOverPrisonerSizeEffect(mobileParty);
                explainedNumber.AddFactor(overPrisonerSizeEffect, _textOverPrisonerSize);
            }
            herdSize += Math.Max(0, numberOfAvailableMounts - min_footmenCount_numberOfAvailableMounts);
            float herdingModifier = this.GetHerdingModifier(menCount, herdSize);

            explainedNumber.AddFactor(herdingModifier, _textHerd);
            float woundedModifier = this.GetWoundedModifier(menCount, woundedCount, mobileParty);

            explainedNumber.AddFactor(woundedModifier, _textWounded);
            float sizeModifierPrisoner = GetSizeModifierPrisoner(menCount, prisonerCount);

            explainedNumber.AddFactor(1f / sizeModifierPrisoner - 1f, _textPrisoners);
            if (morale > 70f)
            {
                explainedNumber.AddFactor(0.05f * ((morale - 70f) / 30f), _textHighMorale);
            }
            if (morale < 30f)
            {
                explainedNumber.AddFactor(-0.1f * (1f - mobileParty.Morale / 30f), _textLowMorale);
            }
            if (mobileParty == MobileParty.MainParty)
            {
                float playerMapMovementSpeedBonusMultiplier = Campaign.Current.Models.DifficultyModel.GetPlayerMapMovementSpeedBonusMultiplier();
                if (playerMapMovementSpeedBonusMultiplier != 0f)
                {
                    explainedNumber.AddFactor(playerMapMovementSpeedBonusMultiplier, _difficulty);
                }
            }
            if (mobileParty.IsDisorganized)
            {
                explainedNumber.AddFactor(-0.3f, _textDisorganized);
            }
            explainedNumber.LimitMin(1f);
            return(explainedNumber.ResultNumber);
        }