public static void GetPerkEffectsOnAgent(ref Agent agent, ref AgentDrivenProperties agentDrivenProperties, ref WeaponComponentData rightHandEquippedItem) { if (agent != null && agent.IsMainAgent && BannerlordCheatsSettings.Instance.InstantCrossbowReload) { agentDrivenProperties.ReloadSpeed = 10f; } }
public override void UpdateAgentStats(Agent agent, AgentDrivenProperties agentDrivenProperties) { _previousModel?.UpdateAgentStats(agent, agentDrivenProperties); if (agent.IsHuman) { EnhancedSetAiRelatedProperties(agent, agentDrivenProperties); } }
private static void Postfix(Agent agent, AgentDrivenProperties agentDrivenProperties) { if (agent.IsHero && agent.IsFemale) { Equipment spawnEquipment = agent.SpawnEquipment; agentDrivenProperties.ArmorHead = spawnEquipment.GetHeadArmorSum() + 99; } }
private static void UpdateHorseStats(Agent agent, AgentDrivenProperties agentDrivenProperties) { if (agent.RiderAgent != null && agent.RiderAgent.IsHero) { var riding = (agent.RiderAgent.Character as CharacterObject).GetSkillValue(DefaultSkills.Riding); agentDrivenProperties.ArmorTorso *= 1f + (float)Math.Sqrt(riding / 100f); } }
public static void GetPerkEffectsOnAgent(ref Agent agent, ref AgentDrivenProperties agentDrivenProperties, ref WeaponComponentData rightHandEquippedItem) { try { if (agent.IsPlayer() && BannerlordCheatsSettings.Instance?.InstantCrossbowReload == true) { agentDrivenProperties.ReloadSpeed = 10f; } } catch (Exception e) { SubModule.LogError(e, typeof(InstantCrossbowReload)); } }
public static void Postfix(Agent agent, AgentDrivenProperties agentDrivenProperties) { if (agent != null && agentDrivenProperties != null) { if (!agent.IsHero && agent.IsHuman) { try { Agent leader = agent.Team.Leader; Equipment leader_equipment = leader.SpawnEquipment; float total_armor = leader_equipment.GetHeadArmorSum() + leader_equipment.GetHumanBodyArmorSum() + leader_equipment.GetLegArmorSum() + leader_equipment.GetArmArmorSum(); EquipmentIndex wieldedItemIndex3 = agent.GetWieldedItemIndex(Agent.HandIndex.MainHand); MissionEquipment equipment = agent.Equipment; WeaponComponentData weaponComponentData = (wieldedItemIndex3 != EquipmentIndex.None) ? equipment[wieldedItemIndex3].CurrentUsageItem : null; if (total_armor > 9000) { agentDrivenProperties.ArmorHead += leader_equipment.GetHeadArmorSum() / 10; agentDrivenProperties.ArmorTorso += leader_equipment.GetHumanBodyArmorSum() / 10; agentDrivenProperties.ArmorLegs += leader_equipment.GetLegArmorSum() / 10; agentDrivenProperties.ArmorArms += leader_equipment.GetArmArmorSum() / 10; agent.HealthLimit = Math.Min(agent.HealthLimit + (total_armor / 100) * (total_armor > 9000 ? 3f : 0.5f), 50000f); agent.Health = agent.HealthLimit; agentDrivenProperties.SwingSpeedMultiplier += (total_armor > 9000 ? 1f : 0f); agentDrivenProperties.ThrustOrRangedReadySpeedMultiplier += (total_armor > 9000 ? 1f : 0f); agentDrivenProperties.WeaponInaccuracy *= (total_armor > 9000 ? 0.01f : 1f); agentDrivenProperties.MaxSpeedMultiplier *= (total_armor > 9000 ? 2f : 1f); agentDrivenProperties.WeaponUnsteadyBeginTime = (total_armor > 9000 ? 0.01f : 1f); agentDrivenProperties.WeaponUnsteadyEndTime = (total_armor > 9000 ? 0.05f : 1f); agentDrivenProperties.ReloadSpeed = (total_armor > 9000 ? 0.01f : 0.93f); } //ModDebug.ShowMessage($"Test: ArmorHead {agentDrivenProperties.ArmorHead} | ArmorTorso {agentDrivenProperties.ArmorTorso} | ArmorLegs {agentDrivenProperties.ArmorLegs} | ArmorArms {agentDrivenProperties.ArmorArms}" + // $"Test: HealthLimit {agent.HealthLimit}" // , "Test"); } catch (Exception ex) { ModDebug.ShowError($"An exception occurred whilst trying to apply the god mode", "", ex); } } } }
static void Postfix(Agent agent, ref AgentDrivenProperties agentDrivenProperties, WeaponComponentData equippedItem, WeaponComponentData secondaryItem) { int meleeSkill = GetMeleeSkill(agent, equippedItem, secondaryItem); SkillObject skill = (equippedItem == null) ? DefaultSkills.Athletics : equippedItem.RelevantSkill; int effectiveSkill = GetEffectiveSkill(agent.Character, agent.Origin, agent.Formation, skill); float meleeLevel = CalculateAILevel(agent, meleeSkill); //num float effectiveSkillLevel = CalculateAILevel(agent, effectiveSkill); //num2 float meleeDefensivness = meleeLevel + agent.Defensiveness; //num3 agentDrivenProperties.AiChargeHorsebackTargetDistFactor = 4f; agentDrivenProperties.AIBlockOnDecideAbility = MBMath.ClampFloat(meleeLevel * 0.5f, 0.15f, 0.45f); agentDrivenProperties.AIParryOnDecideAbility = MBMath.ClampFloat((meleeLevel * 0.25f) + 0.15f, 0.1f, 0.45f); agentDrivenProperties.AIRealizeBlockingFromIncorrectSideAbility = MBMath.ClampFloat(meleeLevel + 0.1f, 0f, 0.95f); agentDrivenProperties.AIDecideOnAttackChance = MBMath.ClampFloat(meleeLevel + 0.1f, 0f, 0.95f); agentDrivenProperties.AIDecideOnRealizeEnemyBlockingAttackAbility = MBMath.ClampFloat(meleeLevel + 0.1f, 0f, 0.95f); agentDrivenProperties.AiRangedHorsebackMissileRange = 0.7f; agentDrivenProperties.AiUseShieldAgainstEnemyMissileProbability = 0.95f; agentDrivenProperties.AiFlyingMissileCheckRadius = 250f; }
public static void UpdateAgentStats(Agent agent, AgentDrivenProperties agentDrivenProperties) { if (!agent.IsHuman) { return; } var characterObject = CharacterObject.Find(agent.Character.StringId); var characterBonuses = new CharacterAttributeBonuses(characterObject); var weapon = agent.GetWieldedWeaponInfo(Agent.HandIndex.MainHand); var isMelee = weapon != null && !weapon.IsRangedWeapon; float speedMultiplier = isMelee ? characterBonuses.MeleeSpeedMultiplier : characterBonuses.RangeSpeedMultiplier; Logger.Log("Bonus " + speedMultiplier.ToString("P") + " Attack Speed from " + (isMelee ? "VIG" : "CON"), characterObject); speedMultiplier++; agentDrivenProperties.ThrustOrRangedReadySpeedMultiplier *= speedMultiplier; agentDrivenProperties.ReloadSpeed *= speedMultiplier; agentDrivenProperties.SwingSpeedMultiplier *= speedMultiplier; }
public override void InitializeAgentStats(Agent agent, Equipment spawnEquipment, AgentDrivenProperties agentDrivenProperties, AgentBuildData agentBuildData) { previousModel.InitializeAgentStats(agent, spawnEquipment, agentDrivenProperties, agentBuildData); }
static void Postfix(Agent agent, ref AgentDrivenProperties agentDrivenProperties, WeaponComponentData equippedItem, WeaponComponentData secondaryItem, AgentStatCalculateModel __instance) { MethodInfo method = typeof(AgentStatCalculateModel).GetMethod("GetMeleeSkill", BindingFlags.NonPublic | BindingFlags.Instance); method.DeclaringType.GetMethod("GetMeleeSkill"); //int meleeSkill = Utilities.GetMeleeSkill(agent, equippedItem, secondaryItem); //int effectiveSkill = Utilities.GetEffectiveSkill(agent.Character, agent.Origin, agent.Formation, skill); SkillObject skill = (equippedItem == null) ? DefaultSkills.Athletics : equippedItem.RelevantSkill; int meleeSkill = (int)method.Invoke(__instance, new object[] { agent, equippedItem, secondaryItem }); int effectiveSkill = __instance.GetEffectiveSkill(agent.Character, agent.Origin, agent.Formation, skill); float meleeLevel = Utilities.CalculateAILevel(agent, meleeSkill); //num float effectiveSkillLevel = Utilities.CalculateAILevel(agent, effectiveSkill); //num2 float meleeDefensivness = meleeLevel + agent.Defensiveness; //num3 agentDrivenProperties.AiChargeHorsebackTargetDistFactor = 8f; agentDrivenProperties.AIBlockOnDecideAbility = MBMath.ClampFloat(0.1f + meleeLevel * 0.6f, 0.2f, 0.45f); // chance for directed blocking agentDrivenProperties.AIParryOnDecideAbility = MBMath.ClampFloat((meleeLevel * 0.30f) + 0.15f, 0.1f, 0.45f); agentDrivenProperties.AIRealizeBlockingFromIncorrectSideAbility = MBMath.ClampFloat((meleeLevel * 0.3f) - 0.05f, 0.01f, 0.25f); agentDrivenProperties.AIDecideOnAttackChance = MBMath.ClampFloat(meleeLevel + 0.1f, 0f, 0.95f); agentDrivenProperties.AIDecideOnRealizeEnemyBlockingAttackAbility = MBMath.ClampFloat(meleeLevel + 0.1f, 0f, 0.95f); agentDrivenProperties.AiRangedHorsebackMissileRange = 0.5f; agentDrivenProperties.AiUseShieldAgainstEnemyMissileProbability = 0.95f; agentDrivenProperties.AiFlyingMissileCheckRadius = 250f; agentDrivenProperties.AiShooterError = 0.0001f; //agentDrivenProperties.AiRangerLeadErrorMin = 0f; //agentDrivenProperties.AiRangerLeadErrorMax = 0f; if (equippedItem != null && equippedItem.RelevantSkill == DefaultSkills.Bow) { agentDrivenProperties.AiRangerVerticalErrorMultiplier = MBMath.ClampFloat(0.025f - effectiveSkill * 0.0001f, 0.01f, 0.025f); //bow agentDrivenProperties.AiRangerHorizontalErrorMultiplier = MBMath.ClampFloat(0.025f - effectiveSkill * 0.0001f, 0.01f, 0.025f); //bow } else if (equippedItem != null && equippedItem.RelevantSkill == DefaultSkills.Crossbow) { agentDrivenProperties.AiRangerVerticalErrorMultiplier = MBMath.ClampFloat(0.015f - effectiveSkill * 0.0001f, 0.005f, 0.015f); //crossbow agentDrivenProperties.AiRangerHorizontalErrorMultiplier = MBMath.ClampFloat(0.015f - effectiveSkill * 0.0001f, 0.005f, 0.015f); //crossbow } else { agentDrivenProperties.AiRangerVerticalErrorMultiplier = MBMath.ClampFloat(0.030f - effectiveSkill * 0.0001f, 0.01f, 0.030f); // javelins and axes etc agentDrivenProperties.AiRangerHorizontalErrorMultiplier = MBMath.ClampFloat(0.030f - effectiveSkill * 0.0001f, 0.01f, 0.030f); // javelins and axes etc } agentDrivenProperties.AIAttackOnParryChance = MBMath.ClampFloat(meleeLevel * 0.4f, 0.1f, 0.30f); //0.3f - 0.1f * agent.Defensiveness; //0.2-0.3f // chance to break own parry guard - 0 constant parry in reaction to enemy, 1 constant breaking of parry agentDrivenProperties.AIDecideOnAttackChance = MBMath.ClampFloat(meleeLevel * 0.3f, 0.15f, 0.5f); //0.15f * agent.Defensiveness; //0-0.15f - how often is direction changed (or swtich to parry) when preparing for attack agentDrivenProperties.AIAttackOnDecideChance = 0.5f; //MBMath.ClampFloat(0.23f * CalculateAIAttackOnDecideMaxValue() * (3f - agent.Defensiveness), 0.05f, 1f); //0.05-1f, 0.66-line, 0.44 - shield wall - aggressiveness / chance of attack instead of anything else / when set to 0 AI never attacks on its own agentDrivenProperties.AiDefendWithShieldDecisionChanceValue = MBMath.ClampFloat(1f - (meleeLevel * 1f), 0.1f, 1.0f); //MBMath.ClampMin(1f, 0.2f + 0.5f * num + 0.2f * num3); 0.599-0.799 = 200 skill line/wall - chance for passive constant block //agentDrivenProperties.AiRaiseShieldDelayTimeBase = -0.4f; //MBMath.ClampFloat(-0.5f + (meleeLevel * 1.25f), -0.5f, 0f); //-0.75f + 0.5f * meleeLevel; delay between block decision and actual block for AI agentDrivenProperties.AiAttackCalculationMaxTimeFactor = meleeLevel; agentDrivenProperties.AiAttackingShieldDefenseChance = MBMath.ClampFloat(meleeLevel * 2f, 0.1f, 1.0f);; //0.2f + 0.3f * meleeLevel; agentDrivenProperties.AiAttackingShieldDefenseTimer = MBMath.ClampFloat(-0.3f + (meleeLevel * 0.6f), -0.3f, 0f); //-0.3f + 0.3f * meleeLevel; agentDrivenProperties.AiShootFreq = MBMath.ClampFloat(effectiveSkill * 1.5f, 0.1f, 0.9f); // when set to 0 AI never shoots //agentDrivenProperties.AiWaitBeforeShootFactor = 0f; //agentDrivenProperties.AiMinimumDistanceToContinueFactor = 5f; //2f + 0.3f * (3f - meleeSkill); //agentDrivenProperties.AIHoldingReadyMaxDuration = 0.1f; //MBMath.Lerp(0.25f, 0f, MBMath.Min(1f, num * 1.2f)); //agentDrivenProperties.AIHoldingReadyVariationPercentage = //num; //agentDrivenProperties.ReloadSpeed = 0.19f; //0.12 for heavy crossbows, 0.19f for light crossbows, composite bows and longbows. if (agent.IsRangedCached) { //agent.SetScriptedCombatFlags(Agent.AISpecialCombatModeFlags.IgnoreAmmoLimitForRangeCalculation); agent.SetScriptedCombatFlags(agent.GetScriptedCombatFlags() | Agent.AISpecialCombatModeFlags.IgnoreAmmoLimitForRangeCalculation); //agent.ResetAiWaitBeforeShootFactor(); } }
private static void GetPerkEffectsOnAgent(Agent agent, AgentDrivenProperties agentDrivenProperties, WeaponComponentData rightHandEquippedItem) { CharacterObject characterObject = agent.Character as CharacterObject; if (characterObject == null) { return; } ItemObject offHandItemObject = null; EquipmentIndex wieldedItemIndex = agent.GetWieldedItemIndex(Agent.HandIndex.OffHand); if (wieldedItemIndex != EquipmentIndex.None) { offHandItemObject = agent.Equipment[wieldedItemIndex].CurrentUsageItem.Item; } if (offHandItemObject != null && offHandItemObject.PrimaryWeapon.IsShield) { } if (rightHandEquippedItem == null) { return; } if (rightHandEquippedItem.RelevantSkill == DefaultSkills.OneHanded) { } else if (rightHandEquippedItem.RelevantSkill == DefaultSkills.TwoHanded) { //PerkObject perkObject = rightHandEquippedItem.ThrustSpeed < 85 ? DefaultPerks.TwoHanded.PowerBasher : (rightHandEquippedItem.ThrustSpeed > 100 ? DefaultPerks.TwoHanded.SpeedBasher : null); //if (perkObject != null) //{ // agentDrivenProperties.ThrustOrRangedReadySpeedMultiplier *= 1 + perkObject.SecondaryBonus / 100f; //} //PerkObject swingPerk = rightHandEquippedItem.SwingSpeed < 85 ? DefaultPerks.TwoHanded.PowerBasher : (rightHandEquippedItem.SwingSpeed > 100 ? DefaultPerks.TwoHanded.SpeedBasher : null); //if (swingPerk != null) //{ // agentDrivenProperties.SwingSpeedMultiplier *= 1 + swingPerk.SecondaryBonus / 100f; //} //双手大于100效果。 var bonus = (characterObject.GetSkillValue(DefaultSkills.TwoHanded) - 200) * 0.2f; if (bonus > 0) { agentDrivenProperties.SwingSpeedMultiplier *= 1 + bonus / 100; agentDrivenProperties.ThrustOrRangedReadySpeedMultiplier *= 1 + bonus / 100; } } else if (rightHandEquippedItem.RelevantSkill == DefaultSkills.Polearm) { } else if (rightHandEquippedItem.RelevantSkill == DefaultSkills.Bow) { if (characterObject.GetPerkValue(DefaultPerks.Bow.Marksman)) { agentDrivenProperties.WeaponInaccuracy *= 1.1f; } if (characterObject.GetPerkValue(DefaultPerks.Bow.FasterAim)) { agentDrivenProperties.ThrustOrRangedReadySpeedMultiplier *= 1.1f; } if (characterObject.GetPerkValue(DefaultPerks.Bow.Ranger)) { agentDrivenProperties.WeaponMaxMovementAccuracyPenalty *= 0.6f; } } else if (rightHandEquippedItem.RelevantSkill == DefaultSkills.Crossbow) { if (characterObject.GetPerkValue(DefaultPerks.Crossbow.FastReload)) { agentDrivenProperties.ReloadSpeed *= 1.1f; } if (characterObject.GetPerkValue(DefaultPerks.Crossbow.HastyReload)) { agentDrivenProperties.ReloadSpeed *= 1.15f; } if (characterObject.GetPerkValue(DefaultPerks.Crossbow.VolleyCommander)) { agentDrivenProperties.ReloadSpeed *= 1.2f; } if (characterObject.GetPerkValue(DefaultPerks.Crossbow.ImprovedAim)) { agentDrivenProperties.WeaponInaccuracy *= 1.2f; } } else if (rightHandEquippedItem.RelevantSkill == DefaultSkills.Throwing) { if (characterObject.GetPerkValue(DefaultPerks.Throwing.SteadyHand)) { agentDrivenProperties.WeaponInaccuracy *= 1.15f; } if (characterObject.GetPerkValue(DefaultPerks.Throwing.PerfectAccuracy)) { agentDrivenProperties.WeaponInaccuracy *= 1.3f; } if (characterObject.GetPerkValue(DefaultPerks.Throwing.Extra2)) { agentDrivenProperties.WeaponMaxMovementAccuracyPenalty = 0f; } } if (agent.HasMount) { if (characterObject.GetPerkValue(DefaultPerks.Riding.Sharpshooter)) { agentDrivenProperties.WeaponInaccuracy *= 1.15f; } if (characterObject.GetPerkValue(DefaultPerks.Riding.MountedArcher) && (rightHandEquippedItem.RelevantSkill == DefaultSkills.Bow || rightHandEquippedItem.RelevantSkill == DefaultSkills.Crossbow || rightHandEquippedItem.RelevantSkill == DefaultSkills.Throwing)) { agentDrivenProperties.WeaponMaxUnsteadyAccuracyPenalty *= 0.9f; agentDrivenProperties.WeaponMaxMovementAccuracyPenalty *= 0.9f; agentDrivenProperties.WeaponRotationalAccuracyPenaltyInRadians *= 0.9f; } else if (characterObject.GetPerkValue(DefaultPerks.Riding.Cavalry) && (rightHandEquippedItem.RelevantSkill == DefaultSkills.OneHanded || rightHandEquippedItem.RelevantSkill == DefaultSkills.TwoHanded || rightHandEquippedItem.RelevantSkill == DefaultSkills.Polearm)) { agentDrivenProperties.WeaponMaxUnsteadyAccuracyPenalty *= 0.9f; agentDrivenProperties.WeaponMaxMovementAccuracyPenalty *= 0.9f; agentDrivenProperties.WeaponRotationalAccuracyPenaltyInRadians *= 0.9f; } } }
public static void InitializeAgentStats(Agent agent, Equipment spawnEquipment, AgentDrivenProperties agentDrivenProperties, AgentBuildData agentBuildData) { if (!agent.IsHuman) { return; } var characterObject = CharacterObject.Find(agent.Character.StringId); var speedMultiplier = new CharacterAttributeBonuses(characterObject).MoveSpeedMultiplier; Logger.Log("Bonus " + speedMultiplier.ToString("P") + " Movement Speed from END", characterObject); agentDrivenProperties.CombatMaxSpeedMultiplier *= 1 + speedMultiplier; }
internal static void UpdateHumanStats(this SandboxAgentStatCalculateModel model, Agent agent, AgentDrivenProperties agentDrivenProperties) { throw new NotImplementedException("Need to patch first"); }
//private int GetWeaponSkill(BasicCharacterObject character, WeaponComponentData equippedItem) //{ // SkillObject skill = DefaultSkills.Athletics; // if (equippedItem != null) // skill = equippedItem.RelevantSkill; // return character.GetSkillValue(skill); //} //private int GetMeleeSkill( // BasicCharacterObject character, // WeaponComponentData equippedItem, // WeaponComponentData secondaryItem) //{ // SkillObject skill = DefaultSkills.Athletics; // if (equippedItem != null) // { // SkillObject relevantSkill = equippedItem.RelevantSkill; // skill = relevantSkill == DefaultSkills.OneHanded || relevantSkill == DefaultSkills.Polearm ? relevantSkill : (relevantSkill != DefaultSkills.TwoHanded ? DefaultSkills.OneHanded : (secondaryItem == null ? DefaultSkills.TwoHanded : DefaultSkills.OneHanded)); // } // return character.GetSkillValue(skill); //} private void EnhancedSetAiRelatedProperties( Agent agent, AgentDrivenProperties agentDrivenProperties) { MissionEquipment equipment = agent.Equipment; EquipmentIndex mainHandItemIndex = agent.GetWieldedItemIndex(Agent.HandIndex.MainHand); MissionWeapon missionWeapon; WeaponComponentData mainHandWeapon; if (mainHandItemIndex == EquipmentIndex.None) { mainHandWeapon = null; } else { missionWeapon = equipment[mainHandItemIndex]; mainHandWeapon = missionWeapon.CurrentUsageItem; } EquipmentIndex offHandItemIndex = agent.GetWieldedItemIndex(Agent.HandIndex.OffHand); WeaponComponentData offHandWeapon; if (offHandItemIndex == EquipmentIndex.None) { offHandWeapon = null; } else { missionWeapon = equipment[offHandItemIndex]; offHandWeapon = missionWeapon.CurrentUsageItem; } var config = ImprovedCombatAIConfig.Get(); float meleeAILevel; if (config.DirectlySetMeleeAI) { meleeAILevel = MathF.Clamp(config.MeleeAIDifficulty / 100.0f, 0, 1); } else { int meleeSkill = GetMeleeSkill(agent, mainHandWeapon, offHandWeapon); meleeAILevel = CalculateAILevel(agent, meleeSkill); meleeAILevel = MathF.Clamp(meleeAILevel / Math.Max(1 - config.MeleeAIDifficulty / 100f, 0.001f), 0, 1); } float rangedAILevel; if (config.DirectlySetRangedAI) { rangedAILevel = MathF.Clamp(config.RangedAIDifficulty / 100.0f, 0, 1); } else { SkillObject skill = mainHandWeapon == null ? DefaultSkills.Athletics : mainHandWeapon.RelevantSkill; int weaponSkill = GetEffectiveSkill(agent.Character, agent.Origin, agent.Formation, skill); rangedAILevel = CalculateAILevel(agent, weaponSkill); rangedAILevel = MathF.Clamp(rangedAILevel / Math.Max(1 - config.RangedAIDifficulty / 100f, 0.001f), 0, 1); } float num1 = meleeAILevel + agent.Defensiveness; agentDrivenProperties.AiRangedHorsebackMissileRange = (float)(0.300000011920929 + 0.400000005960464 * rangedAILevel); agentDrivenProperties.AiFacingMissileWatch = (float)(meleeAILevel * 0.0599999986588955 - 0.959999978542328); agentDrivenProperties.AiFlyingMissileCheckRadius = (float)(8.0 - 6.0 * meleeAILevel); agentDrivenProperties.AiShootFreq = (float)(0.300000011920929 + 0.699999988079071 * rangedAILevel); agentDrivenProperties.AiWaitBeforeShootFactor = agent._propertyModifiers.resetAiWaitBeforeShootFactor ? 0.0f : (float)(1.0 - 0.5 * rangedAILevel); int num2 = offHandWeapon != null ? 1 : 0; agentDrivenProperties.AIBlockOnDecideAbility = MBMath.Lerp(0.25f, 0.99f, MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 1.0), 0.0f, 1f)); agentDrivenProperties.AIParryOnDecideAbility = MBMath.Lerp(0.01f, 0.95f, MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 1.5), 0.0f, 1f)); agentDrivenProperties.AiTryChamberAttackOnDecide = (float)((meleeAILevel - 0.150000005960464) * 0.100000001490116); agentDrivenProperties.AIAttackOnParryChance = (float)(0.300000011920929 - 0.100000001490116 * agent.Defensiveness); agentDrivenProperties.AiAttackOnParryTiming = (float)(0.300000011920929 * meleeAILevel - 0.200000002980232); agentDrivenProperties.AIDecideOnAttackChance = 0.15f * agent.Defensiveness; agentDrivenProperties.AIParryOnAttackAbility = MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 3.0), 0.0f, 1f); agentDrivenProperties.AiKick = (float)(meleeAILevel - 0.100000001490116); agentDrivenProperties.AiAttackCalculationMaxTimeFactor = meleeAILevel; agentDrivenProperties.AiDecideOnAttackWhenReceiveHitTiming = (float)(-0.25 * (1.0 - meleeAILevel)); agentDrivenProperties.AiDecideOnAttackContinueAction = (float)(-0.5 * (1.0 - meleeAILevel)); agentDrivenProperties.AiDecideOnAttackingContinue = 0.1f * meleeAILevel; agentDrivenProperties.AIParryOnAttackingContinueAbility = MBMath.Lerp(0.05f, 0.95f, MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 3.0), 0.0f, 1f)); agentDrivenProperties.AIDecideOnRealizeEnemyBlockingAttackAbility = 0.5f * MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 2.5) - 0.1f, 0.0f, 1f); agentDrivenProperties.AIRealizeBlockingFromIncorrectSideAbility = 0.5f * MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 2.5) - 0.1f, 0.0f, 1f); agentDrivenProperties.AiAttackingShieldDefenseChance = (float)(0.200000002980232 + 0.300000011920929 * meleeAILevel); agentDrivenProperties.AiAttackingShieldDefenseTimer = (float)(0.300000011920929 * meleeAILevel - 0.300000011920929); agentDrivenProperties.AiRandomizedDefendDirectionChance = (float)(1.0 - Math.Log(meleeAILevel * 7.0 + 1.0, 2.0) * 0.333330005407333); agentDrivenProperties.AISetNoAttackTimerAfterBeingHitAbility = MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 2.0), 0.05f, 0.95f); agentDrivenProperties.AISetNoAttackTimerAfterBeingParriedAbility = MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 2.0), 0.05f, 0.95f); agentDrivenProperties.AISetNoDefendTimerAfterHittingAbility = MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 2.0), 0.05f, 0.95f); agentDrivenProperties.AISetNoDefendTimerAfterParryingAbility = MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 2.0), 0.05f, 0.95f); agentDrivenProperties.AIEstimateStunDurationPrecision = 1f - MBMath.ClampFloat((float)Math.Pow(meleeAILevel, 2.0), 0.05f, 0.95f); agentDrivenProperties.AIHoldingReadyMaxDuration = MBMath.Lerp(0.25f, 0.0f, Math.Min(1f, meleeAILevel * 1.2f)); agentDrivenProperties.AIHoldingReadyVariationPercentage = meleeAILevel; agentDrivenProperties.AiRaiseShieldDelayTimeBase = (float)(0.5 * meleeAILevel - 0.75); agentDrivenProperties.AiUseShieldAgainstEnemyMissileProbability = (float)(0.100000001490116 + meleeAILevel * 0.600000023841858 + num1 * 0.200000002980232); agentDrivenProperties.AiCheckMovementIntervalFactor = (float)(0.00499999988824129 * (1.10000002384186 - meleeAILevel)); agentDrivenProperties.AiMovemetDelayFactor = (float)(4.0 / (3.0 + rangedAILevel)); agentDrivenProperties.AiParryDecisionChangeValue = (float)(0.0500000007450581 + 0.699999988079071 * meleeAILevel); agentDrivenProperties.AiDefendWithShieldDecisionChanceValue = Math.Min(1f, (float)(0.200000002980232 + 0.5 * meleeAILevel + 0.200000002980232 * num1)); agentDrivenProperties.AiMoveEnemySideTimeValue = (float)(0.5 * meleeAILevel - 2.5); agentDrivenProperties.AiMinimumDistanceToContinueFactor = (float)(2.0 + 0.300000011920929 * (3.0 - meleeAILevel)); agentDrivenProperties.AiStandGroundTimerValue = (float)(0.5 * (meleeAILevel - 1.0)); agentDrivenProperties.AiStandGroundTimerMoveAlongValue = (float)(0.5 * meleeAILevel - 1.0); agentDrivenProperties.AiHearingDistanceFactor = 1f + meleeAILevel; agentDrivenProperties.AiChargeHorsebackTargetDistFactor = (float)(1.5 * (3.0 - meleeAILevel)); agentDrivenProperties.AiWaitBeforeShootFactor = agent._propertyModifiers.resetAiWaitBeforeShootFactor ? 0.0f : (float)(1.0 - 0.5 * rangedAILevel); float num3 = 1f - rangedAILevel; agentDrivenProperties.AiRangerLeadErrorMin = (float)(-(double)num3 * 0.349999994039536) + config.RangedError; agentDrivenProperties.AiRangerLeadErrorMax = num3 * 0.2f + config.RangedError; agentDrivenProperties.AiRangerVerticalErrorMultiplier = num3 * 0.1f; agentDrivenProperties.AiRangerHorizontalErrorMultiplier = num3 * ((float)Math.PI / 90f); agentDrivenProperties.AIAttackOnDecideChance = MathF.Clamp((float)(0.230000004172325 * CalculateAIAttackOnDecideMaxValue() * (3.0 - agent.Defensiveness)), 0.05f, 1f); //agentDrivenProperties.SetStat(DrivenProperty.UseRealisticBlocking, agent.Controller != Agent.ControllerType.Player ? 1f : 0.0f); if (config.UseRealisticBlocking) { agentDrivenProperties.SetStat(DrivenProperty.UseRealisticBlocking, 1f); } }
private static bool UpdateHorseStatsPrefix(ref SandboxAgentStatCalculateModel __instance, Agent agent, AgentDrivenProperties agentDrivenProperties) { Equipment spawnEquipment = agent.SpawnEquipment; agentDrivenProperties.AiSpeciesIndex = (int)spawnEquipment[EquipmentIndex.ArmorItemEndSlot].Item.Id.InternalValue; agentDrivenProperties.AttributeRiding = 0.8f + ((spawnEquipment[EquipmentIndex.HorseHarness].Item != null) ? 0.2f : 0f); float num = 0f; for (int i = 1; i < 12; i++) { if (spawnEquipment[i].Item != null) { num += (float)spawnEquipment[i].GetBodyArmorHorse(); } } agentDrivenProperties.ArmorTorso = num; ItemObject item = spawnEquipment[EquipmentIndex.ArmorItemEndSlot].Item; if (item != null) { float num2 = 1f; if (!agent.Mission.Scene.IsAtmosphereIndoor) { if (agent.Mission.Scene.GetRainDensity() > 0f) { num2 *= 0.9f; } if (CampaignTime.Now.IsNightTime) { num2 *= 0.9f; } } HorseComponent horseComponent = item.HorseComponent; EquipmentElement equipmentElement = spawnEquipment[EquipmentIndex.ArmorItemEndSlot]; EquipmentElement harness = spawnEquipment[EquipmentIndex.HorseHarness]; int baseHorseManeuver = equipmentElement.GetBaseHorseManeuver(harness); int num3 = equipmentElement.GetBaseHorseSpeed(harness) + 1; agentDrivenProperties.MountChargeDamage = (float)equipmentElement.GetBaseHorseCharge(harness) * 0.004f; agentDrivenProperties.MountDifficulty = (float)equipmentElement.Item.Difficulty; RidingModel ridingModel = Game.Current.BasicModels.RidingModel; ItemObject item2 = equipmentElement.Item; Agent riderAgent = agent.RiderAgent; agentDrivenProperties.TopSpeedReachDuration = ridingModel.CalculateAcceleration(item2, (riderAgent != null) ? riderAgent.Character : null); if (agent.RiderAgent != null) { ExplainedNumber explainedNumber = new ExplainedNumber((float)baseHorseManeuver, null); ExplainedNumber explainedNumber2 = new ExplainedNumber((float)num3, null); SkillHelper.AddSkillBonusForCharacter(DefaultSkills.Riding, DefaultSkillEffects.HorseManeuver, agent.RiderAgent.Character as CharacterObject, ref explainedNumber, true); SkillHelper.AddSkillBonusForCharacter(DefaultSkills.Riding, DefaultSkillEffects.HorseSpeed, agent.RiderAgent.Character as CharacterObject, ref explainedNumber2, true); if (harness.Item == null) { explainedNumber.AddFactor(-0.1f, null); explainedNumber2.AddFactor(-0.1f, null); } agentDrivenProperties.MountManeuver = explainedNumber.ResultNumber; if (HorseCrippleLogic.CheckHorseCrippled(agent)) { agentDrivenProperties.MountSpeed = 1; } else { agentDrivenProperties.MountSpeed = num2 * 0.22f * (1f + explainedNumber2.ResultNumber); } return(false); } agentDrivenProperties.MountManeuver = (float)baseHorseManeuver; if (HorseCrippleLogic.CheckHorseCrippled(agent)) { agentDrivenProperties.MountSpeed = 1; } else { agentDrivenProperties.MountSpeed = num2 * 0.22f * (float)(1 + num3); } } return(false); }