private bool ShouldCombatResultInCitySack(IUnit attacker, IUnit defender, CombatInfo combatInfo) { var attackerOwner = UnitPossessionCanon.GetOwnerOfPossession(attacker); return(attackerOwner.Template.IsBarbaric && defender.CurrentHitpoints <= 0 && defender.Type == UnitType.City && combatInfo.CombatType == CombatType.Melee); }
public UnitCombatResults(IUnit attacker, IUnit defender, int damageToAttacker, int damageToDefender, CombatInfo infoOfAttack ) { Attacker = attacker; Defender = defender; DamageToAttacker = damageToAttacker; DamageToDefender = damageToDefender; InfoOfAttack = infoOfAttack; }
public CombatInfo GetAttackInfo(IUnit attacker, IUnit defender, IHexCell location, CombatType combatType) { if (attacker == null) { throw new ArgumentNullException("attacker"); } if (defender == null) { throw new ArgumentNullException("defender"); } if (location == null) { throw new ArgumentNullException("location"); } var combatInfo = new CombatInfo(); combatInfo.CombatType = combatType; ApplyAllModifiersToInfo(attacker, defender, location, combatType, combatInfo); if (combatType == CombatType.Melee && RiverCanon.HasRiver(location) && !attacker.CombatSummary.IgnoresAmphibiousPenalty) { combatInfo.AttackerCombatModifier += UnitConfig.RiverCrossingAttackModifier; } if (!defender.CombatSummary.IgnoresDefensiveTerrainBonus) { combatInfo.DefenderCombatModifier += UnitConfig.GetTerrainDefensiveness(location.Terrain); combatInfo.DefenderCombatModifier += UnitConfig.GetVegetationDefensiveness(location.Vegetation); combatInfo.DefenderCombatModifier += UnitConfig.GetShapeDefensiveness(location.Shape); var improvementAtLocation = ImprovementLocationCanon.GetPossessionsOfOwner(location).FirstOrDefault(); if (improvementAtLocation != null) { combatInfo.DefenderCombatModifier += improvementAtLocation.Template.DefensiveBonus; } combatInfo.DefenderCombatModifier += FortificationLogic.GetFortificationModifierForUnit(defender); } CombatAuraLogic.ApplyAurasToCombat(attacker, defender, combatInfo); CityCombatModifierLogic.ApplyCityModifiersToCombat(attacker, defender, combatInfo); combatInfo.AttackerCombatModifier -= GetUnhappinessPenalty(attacker); combatInfo.DefenderCombatModifier -= GetUnhappinessPenalty(defender); return(combatInfo); }
public void PerformCommonCombatTasks(IUnit attacker, IUnit defender, CombatInfo combatInfo) { Tuple <int, int> results = CombatCalculator.CalculateCombat(attacker, defender, combatInfo); attacker.CurrentHitpoints -= results.Item1; defender.CurrentHitpoints -= results.Item2; foreach (var responder in PostCombatResponders) { responder.RespondToCombat(attacker, defender, combatInfo); } attacker.CanAttack = attacker.CombatSummary.CanAttackAfterAttacking; }
public void ApplyCityModifiersToCombat(IUnit attacker, IUnit defender, CombatInfo combatInfo) { if (attacker.Type == UnitType.City) { var attackerLocation = UnitPositionCanon.GetOwnerOfPossession(attacker); var cityAt = CityLocationCanon.GetPossessionsOfOwner(attackerLocation).FirstOrDefault(); if (cityAt != null && combatInfo.CombatType == CombatType.Ranged) { combatInfo.AttackerCombatModifier += CityModifiers.GarrisionedRangedCombatStrength.GetValueForCity(cityAt); } } }
public void RespondToCombat(IUnit attacker, IUnit defender, CombatInfo combatInfo) { if (!ShouldCombatResultInCitySack(attacker, defender, combatInfo)) { return; } var citySacked = CityFactory.AllCities.Where(city => city.CombatFacade == defender).FirstOrDefault(); var cityOwner = CityPossessionCanon.GetOwnerOfPossession(citySacked); float totalPopOfCityOwner = CityPossessionCanon.GetPossessionsOfOwner(cityOwner).Sum(city => city.Population); float sackProportion = citySacked.Population / totalPopOfCityOwner; int goldStolen = Math.Max(0, Mathf.RoundToInt(cityOwner.GoldStockpile * sackProportion)); cityOwner.GoldStockpile -= goldStolen; }
public void RespondToCombat(IUnit attacker, IUnit defender, CombatInfo combatInfo) { if (attacker.CurrentHitpoints <= 0 && attacker.Type != UnitType.City) { DestroyUnit(attacker); } if (defender.CurrentHitpoints <= 0) { if (defender.Type == UnitType.City) { defender.CurrentHitpoints = 1; } else { var defenderLocation = UnitPositionCanon.GetOwnerOfPossession(defender); var attackerOwner = UnitPossessionCanon.GetOwnerOfPossession(attacker); if (combatInfo.CombatType == CombatType.Melee && UnitConfig.CapturableTemplates.Contains(defender.Template) && UnitPossessionCanon.CanChangeOwnerOfPossession(defender, attackerOwner) ) { UnitPossessionCanon.ChangeOwnerOfPossession(defender, attackerOwner); } else { DestroyUnit(defender); } if (attacker.CurrentHitpoints > 0 && combatInfo.CombatType == CombatType.Melee) { attacker.CurrentPath = new List <IHexCell>() { defenderLocation }; attacker.PerformMovement(false); } } } }
public void RespondToCombat(IUnit attacker, IUnit defender, CombatInfo combatInfo) { if (!attacker.CombatSummary.CanMoveAfterAttacking) { attacker.CurrentMovement = 0; } else if (combatInfo.CombatType == CombatType.Melee) { var attackerLocation = UnitPositionCanon.GetOwnerOfPossession(attacker); var defenderLocation = UnitPositionCanon.GetOwnerOfPossession(defender); var costToMove = UnitPositionCanon.GetTraversalCostForUnit( attacker, attackerLocation, defenderLocation, true ); attacker.CurrentMovement = Math.Max(0, attacker.CurrentMovement - costToMove); } else if (combatInfo.CombatType == CombatType.Ranged) { attacker.CurrentMovement--; } }
public void ApplyAurasToCombat( IUnit attacker, IUnit defender, CombatInfo combatInfo ) { var attackerLocation = UnitPositionCanon.GetOwnerOfPossession(attacker); var defenderLocation = UnitPositionCanon.GetOwnerOfPossession(defender); float attackerAuraStrength = 0f, defenderAuraStrength = 0f; var attackerAllyAuraModifiers = GetNearbyAllies(attacker, UnitConfig.AuraRange).SelectMany( ally => ally.CombatSummary.AuraModifiersWhenAttacking ); foreach (var auraModifier in attackerAllyAuraModifiers) { if (auraModifier.DoesModifierApply(attacker, defender, attackerLocation, combatInfo.CombatType)) { attackerAuraStrength += auraModifier.Modifier; } } var defenderAllyAuraModifiers = GetNearbyAllies(defender, UnitConfig.AuraRange).SelectMany( ally => ally.CombatSummary.AuraModifiersWhenDefending ); foreach (var auraModifier in defenderAllyAuraModifiers) { if (auraModifier.DoesModifierApply(defender, attacker, defenderLocation, combatInfo.CombatType)) { defenderAuraStrength += auraModifier.Modifier; } } combatInfo.AttackerCombatModifier += attackerAuraStrength; combatInfo.DefenderCombatModifier += defenderAuraStrength; }
public Tuple <int, int> CalculateCombat(IUnit attacker, IUnit defender, CombatInfo combatInfo) { float attackerBaseStrength = combatInfo.CombatType == CombatType.Melee ? attacker.CombatStrength : attacker.RangedAttackStrength; float attackerStrength = attackerBaseStrength * (1f + combatInfo.AttackerCombatModifier); float defenderStrength = defender.CombatStrength * (1f + combatInfo.DefenderCombatModifier); int attackerDamage = 0, defenderDamage = 0; if (attackerStrength == 0) { defenderDamage = attacker.CurrentHitpoints; } else if (defenderStrength == 0) { attackerDamage = defender.CurrentHitpoints; } else { float attackerDefenderRatio = attackerStrength / defenderStrength; float defenderAttackerRatio = defenderStrength / attackerStrength; attackerDamage = Mathf.RoundToInt( attackerDefenderRatio * UnitConfig.CombatBaseDamage ); defenderDamage = Mathf.RoundToInt( defenderAttackerRatio * UnitConfig.CombatBaseDamage ); } return(new Tuple <int, int>( combatInfo.CombatType == CombatType.Melee ? Math.Min(defenderDamage, attacker.CurrentHitpoints) : 0, Math.Min(attackerDamage, defender.CurrentHitpoints) )); }
private void ApplyAllModifiersToInfo( IUnit attacker, IUnit defender, IHexCell location, CombatType combatType, CombatInfo info ) { foreach (var attackerModifier in attacker.CombatSummary.ModifiersWhenAttacking) { if (attackerModifier.DoesModifierApply(attacker, defender, location, combatType)) { info.AttackerCombatModifier += attackerModifier.Modifier; } } foreach (var defenderModifiers in defender.CombatSummary.ModifiersWhenDefending) { if (defenderModifiers.DoesModifierApply(defender, attacker, location, combatType)) { info.DefenderCombatModifier += defenderModifiers.Modifier; } } }