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);
        }
示例#2
0
 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;
        }
示例#7
0
        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;
                }
            }
        }