private void BackupStats() { var player = Mission.Current.MainAgent; foreach (var agent in Mission.Current.AllAgents) { if (agent == null || agent == player) { continue; } var component = agent?.GetComponent <AgentAIStateFlagComponent>(); if (component != null) { component.IsPaused = everyonePassive; } var agentDrivenProperties = (AgentDrivenProperties)agent.GetType() .GetProperty("AgentDrivenProperties", BindingFlags.NonPublic | BindingFlags.Instance) ?.GetValue(agent); if (agentDrivenProperties == null) { continue; } foreach (DrivenProperty drivenProperty in (DrivenProperty[])Enum.GetValues( typeof(DrivenProperty))) { if (drivenProperty >= DrivenProperty.MountManeuver || drivenProperty <= DrivenProperty.None) { continue; } var val = agentDrivenProperties.GetStat(drivenProperty); StatsBackup.SetStat(drivenProperty, val); StatsToSet.SetStat(drivenProperty, val); } } }
//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); } }