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); } } } }
public static IEnumerable <(MissionWeapon element, EquipmentIndex index)> YieldSlots(this MissionEquipment equipment) { for (int i = (int)EquipmentIndex.WeaponItemBeginSlot; i < (int)EquipmentIndex.ExtraWeaponSlot; i++) { yield return(equipment[i], (EquipmentIndex)i); } }
public static void Equipment(Agent __instance, MissionEquipment value) { if (!__instance.IsHero) { return; } var charObj = __instance.Character as CharacterObject; if (charObj == null) { return; } for (var i = 0; i < 5; i++) { MissionWeapon missionWeapon = value[i]; if (missionWeapon.Weapons.IsEmpty()) { continue; } var weaponComponentData = missionWeapon.Weapons[0]; if (weaponComponentData == null) { continue; } short add = 0; if (weaponComponentData.WeaponClass == WeaponClass.Arrow) { if (charObj.GetPerkValue(DefaultPerks.Bow.LargeQuiver)) { add += 3; } if (__instance.HasMount && charObj.GetPerkValue(DefaultPerks.Riding.SpareArrows)) { add += 3; } if (__instance.HasMount && charObj.GetPerkValue(DefaultPerks.Bow.BattleEquipped)) { add += 6; } if (!__instance.HasMount && charObj.GetPerkValue(DefaultPerks.Athletics.ExtraArrows)) { add += 2; } missionWeapon.Amount += add; short newMaxValue = (short)(missionWeapon.MaxAmount + add); MaxAmmoField.SetValue(missionWeapon, newMaxValue); value[i] = missionWeapon; } else if (weaponComponentData.WeaponClass == WeaponClass.Crossbow) { if (__instance.HasMount && charObj.GetPerkValue(DefaultPerks.Riding.SpareArrows)) { add += 3; } if (!__instance.HasMount && charObj.GetPerkValue(DefaultPerks.Athletics.ExtraArrows)) { add += 2; } missionWeapon.Amount += add; short newMaxValue = (short)(missionWeapon.MaxAmount + add); MaxAmmoField.SetValue(missionWeapon, newMaxValue); value[i] = missionWeapon; } } }
public static IEnumerable <(MissionWeapon element, EquipmentIndex index)> YieldFilledSlots(this MissionEquipment equipment) => equipment.YieldSlots().Where(s => !s.element.IsEmpty);
//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); } }