static void CalculateLearningLimitPostfix(ref ExplainedNumber __result) { float newLearningLimit = __result.ResultNumber * LEARNING_RATE_LIMIT_MULTIPLIER - __result.ResultNumber; __result.AddFactor(newLearningLimit); __result.LimitMax(500); }
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(MobileParty mobileParty, ref ExplainedNumber __result) { if (PartyMilitiaMap.ContainsKey(mobileParty)) { __result.AddFactor(SpeedModifier, new TextObject("Bandit Militia")); } }
static void Postfix(ref ExplainedNumber __result) { if (AdditionalSpottingRange == 0) { return; } __result.AddFactor(AdditionalSpottingRange, new TaleWorlds.Localization.TextObject("CustomSpawns HAX")); }
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); } }
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; }
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; }
// 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); } } }
// 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; }
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; } } }
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; }
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); } } } }
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); }
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); } }
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); }