private PartyAttackComposition MakeSingleAttack(float consumption) { if (!SubModule.Settings.Battle_SendAllTroops_DetailedCombatModel) { PartyAttackComposition attack = new PartyAttackComposition(); attack.Infantry.Melee = Strength; return(attack); } var preparedAttack = PrepareWeapon(); if (!ChosenWeapon.IsTwohanded && Shield != null) { IsUsingShield = true; } else { IsUsingShield = false; } IsUsingRanged = ChosenWeapon.IsRanged; if (ChosenWeapon.HasLimitedAmmo && !partyState.mapEventState.IsSiege) { ChosenWeapon.RemainingAmmo -= consumption; } return(preparedAttack); }
public bool ApplyDamageToTroop(PartyAttackComposition attack, CharacterObject troop, out float damage) { TroopState troopState = GetTroopState(troop); bool isFinishingBlow = troopState.TakeHit(attack, out damage); return(isFinishingBlow); }
public PartyAttackComposition MakePartyAttack(float consumption) { PartyAttackComposition attack = new PartyAttackComposition(); foreach (var troopState in TroopStates.Values) { attack += troopState.MakeTotalAttack(consumption); } return(attack); }
// MapEventSide.ApplySimulationDamageToSelectedTroop public static bool ApplySimulationDamageToSelectedTroop(MapEventSide side, CharacterObject strikedTroop, PartyBase strikedTroopParty, UniqueTroopDescriptor strikedTroopDescriptor, int selectedSimulationTroopIndex, List <UniqueTroopDescriptor> strikedTroopList, PartyAttackComposition attack, DamageTypes damageType, PartyBase strikerParty, MapEventState mapEventState, IBattleObserver battleObserver, out float damage) { bool IsFinishingStrike = mapEventState.ApplyDamageToPartyTroop(attack, strikedTroopParty, strikedTroop, out damage); if (IsFinishingStrike) { if (strikedTroop.IsHero) { battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 0, 1, 0, 0, 0); } else { float survivalChance = Campaign.Current.Models.PartyHealingModel.GetSurvivalChance(strikedTroopParty, strikedTroop, damageType, strikerParty); if (MBRandom.RandomFloat < survivalChance) { side.OnTroopWounded(strikedTroopDescriptor); battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 0, 1, 0, 0, 0); if (strikedTroopParty.MobileParty != null) { SkillLevelingManager.OnSurgeryApplied(strikedTroopParty.MobileParty, 1f); } } else { side.OnTroopKilled(strikedTroopDescriptor); battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 1, 0, 0, 0, 0); if (strikedTroopParty.MobileParty != null) { SkillLevelingManager.OnSurgeryApplied(strikedTroopParty.MobileParty, 0.5f); } } } // side.RemoveSelectedTroopFromSimulationList(); RemoveSelectedTroopFromSimulationList(side, selectedSimulationTroopIndex, strikedTroopList); } return(IsFinishingStrike); }
public bool TakeHit(PartyAttackComposition attack, out float totalDamage) { if (IsHero) { // Uses the vanilla hero health system totalDamage = Math.Min(CalculateRecievedDamage(attack), MaxHitPoints); AccumulatedDamage += totalDamage; int actualDamage = (int)Math.Floor(AccumulatedDamage); AccumulatedDamage -= actualDamage; troop.HeroObject.HitPoints -= actualDamage; return(troop.HeroObject.IsWounded); } else { if (Alive <= 0) { totalDamage = 0; return(true); } if (_expectedHits > 0) { totalDamage = 0; _expectedHits -= 1; if (ExpectedDeathCount > CurrentDeathCount) { CurrentDeathCount += 1; return(true); } else { return(false); } } float singleDamage = CalculateRecievedDamage(attack); // Apply the damage to all alive members at once, and ignore the next Alive - 1 attacks totalDamage = Math.Min(singleDamage, MaxHitPoints) * Alive; if (SubModule.Settings.Battle_SendAllTroops_RandomDeath) { for (int i = 0; i < Alive; i++) { if (MBRandom.RandomFloat * MaxHitPoints < singleDamage) { ExpectedDeathCount += 1; } } } else { AccumulatedDamage += totalDamage; ExpectedDeathCount = (int)Math.Round(AccumulatedDamage / MaxHitPoints); if (ExpectedDeathCount > TotalCount) { ExpectedDeathCount = TotalCount; } } _expectedHits = Alive - 1; if (ExpectedDeathCount > CurrentDeathCount) { CurrentDeathCount += 1; return(true); } return(false); } }
private float CalculateRecievedDamage(PartyAttackComposition attack) { float damage; if (SubModule.Settings.Battle_SendAllTroops_DetailedCombatModel) { float infantryMeleeDefense = ArmorPoints; float infantryMissileDefense = ArmorPoints; float infantryPolearmDefense = ArmorPoints; float mountedMeleeDefense = ArmorPoints; float mountedMissileDefense = ArmorPoints; float mountedPolearmDefense = ArmorPoints; if (IsUsingShield && Shield != null) { infantryMeleeDefense += Shield.Strength; infantryMissileDefense += 6 * Shield.Strength; infantryPolearmDefense += Shield.Strength; mountedMeleeDefense += Shield.Strength; mountedMissileDefense += 6 * Shield.Strength; mountedPolearmDefense += Shield.Strength; } if (IsMounted) { if (IsUsingRanged) { infantryMeleeDefense *= (1 + 3 * Horse.Strength); infantryMissileDefense *= (1 + Horse.Strength); infantryPolearmDefense *= (1 + 3 * Horse.Strength); } else { infantryMeleeDefense *= (1 + Horse.Strength); infantryMissileDefense *= (1 + Horse.Strength); } mountedMeleeDefense *= (1 + Horse.Strength); mountedMissileDefense *= (1 + Horse.Strength); mountedPolearmDefense *= (1 + Horse.Strength); } else { if (IsUsingRanged) { infantryMeleeDefense *= (1 + 6 * Atheletics); infantryPolearmDefense *= (1 + 6 * Atheletics); } else { infantryMeleeDefense *= (1 + Atheletics); infantryPolearmDefense *= (1 + Atheletics); } mountedMeleeDefense *= (1 + Atheletics); mountedPolearmDefense *= (1 + Atheletics); } damage = attack.Infantry.Melee / infantryMeleeDefense + attack.Infantry.Missile / infantryMissileDefense + attack.Infantry.Polearm / infantryPolearmDefense + attack.Mounted.Melee / mountedMeleeDefense + attack.Mounted.Missile / mountedMissileDefense + attack.Mounted.Polearm / mountedPolearmDefense; } else { damage = attack.Infantry.Melee / Strength; } if (SubModule.Settings.Battle_SendAllTroops_RandomDamage) { damage *= MBRandom.RandomFloat * MBRandom.RandomFloat * 4f; } return(damage); }
public bool ApplyDamageToPartyTroop(PartyAttackComposition attack, PartyBase party, CharacterObject troop, out float damage) { PartyState partyState = GetPartyState(party); return(partyState.ApplyDamageToTroop(attack, troop, out damage)); }