예제 #1
0
 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);
     }
 }
예제 #3
0
 private static void Postfix(Agent agent, AgentDrivenProperties agentDrivenProperties)
 {
     if (agent.IsHero && agent.IsFemale)
     {
         Equipment spawnEquipment = agent.SpawnEquipment;
         agentDrivenProperties.ArmorHead = spawnEquipment.GetHeadArmorSum() + 99;
     }
 }
예제 #4
0
        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));
     }
 }
예제 #6
0
        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);
                    }
                }
            }
        }
예제 #7
0
            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;
        }
예제 #9
0
 public override void InitializeAgentStats(Agent agent, Equipment spawnEquipment,
                                           AgentDrivenProperties agentDrivenProperties, AgentBuildData agentBuildData)
 {
     previousModel.InitializeAgentStats(agent, spawnEquipment, agentDrivenProperties, agentBuildData);
 }
예제 #10
0
            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;
        }
예제 #13
0
 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);
            }
        }
예제 #15
0
        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);
        }