Ejemplo n.º 1
0
        public void EndBattle(Battle battle)
        {
            using (var trs = transactionScopeProvider.CreateTransactionScope())
            {
                battle.Active = false;
                var defender = battle.GetDefender();
                var attacker = battle.GetAttacker();

                double defenseSTR = (double)battle.BattleParticipants
                                    .Where(p => p.IsAttacker == false)
                                    .Select(p => p.DamageDealt).Sum();

                double attackerSTR = (double)battle.BattleParticipants
                                     .Where(p => p.IsAttacker == true)
                                     .Select(p => p.DamageDealt).Sum();

                var bestAttacker = battle.BattleParticipants
                                   .Where(p => p.IsAttacker == true)
                                   .GroupBy(p => p.CitizenID)
                                   .Select(group => new
                {
                    CitizenID = group.Key,
                    Damage    = group.Sum(p => p.DamageDealt)
                })
                                   .OrderByDescending(p => p.Damage)
                                   .FirstOrDefault();

                var bestDefender = battle.BattleParticipants
                                   .Where(p => p.IsAttacker == false)
                                   .GroupBy(p => p.CitizenID)
                                   .Select(group => new
                {
                    CitizenID = group.Key,
                    Damage    = group.Sum(p => p.DamageDealt)
                })
                                   .OrderByDescending(p => p.Damage)
                                   .FirstOrDefault();

                if (bestAttacker != null)
                {
                    var bestAttackerCitizen = citizenRepository.GetById(bestAttacker.CitizenID);
                    citizenService.ReceiveBattleHeroMedal(bestAttackerCitizen);
                }
                if (bestDefender != null)
                {
                    var bestDefenderCitizen = citizenRepository.GetById(bestDefender.CitizenID);
                    citizenService.ReceiveBattleHeroMedal(bestDefenderCitizen);
                }

                double destroyedDevelopement;
                if (battle.WallHealth < 0)
                {
                    takeRegionByAttacker(battle);
                    destroyedDevelopement               = calculateDestroyedSupplyValueOnAttackerWin((double)battle.WallHealth, defenseSTR, attackerSTR);
                    battle.Region.SupplyProgramType     = (int)SupplyProgramTypeEnum.None;
                    battle.Region.DefenseSystemQuality -= Math.Max(0, battle.Region.DefenseSystemQuality - 1);
                    battle.WonByAttacker = true;

                    var destroyedDevelopementRatio = ((double)battle.Region.Development * destroyedDevelopement);
                    var countryDevelopementValue   = countryRepository.GetCountryDevelopementValue(defender.ID);

                    double distanceFromCapitalRatio = 0.0; //if no capital then it's 0.0

                    if (defender.CapitalID != null)
                    {
                        var path = regionService.GetPathBetweenRegions(battle.Region, defender.Capital);
                        distanceFromCapitalRatio = 3.0 - 9.0 / (path.Distance / 700 + 3) + Math.Log(path.Distance + 500, 500);
                    }

                    double goldTakenRatio = Math.Sqrt(destroyedDevelopementRatio / (countryDevelopementValue + destroyedDevelopementRatio + distanceFromCapitalRatio) + 1.0) - 1.0;
                    double goldTaken      = goldTakenRatio * (double)defender.Entity.Wallet.GetMoney(CurrencyTypeEnum.Gold, Persistent.Currencies.GetAll()).Amount;

                    transactionService.PayForBattleLoss(attacker, defender, goldTaken);
                    battle.GoldTaken = (decimal)goldTaken;

                    battleEventService.AddEvent(battle, BattleStatusEnum.AttackerWin);
                }
                else
                {
                    destroyedDevelopement = calculateDestroyedSupplyValueOnDefenderWin((double)battle.WallHealth, defenseSTR, attackerSTR);
                    battle.WonByAttacker  = false;
                    battleEventService.AddEvent(battle, BattleStatusEnum.DefenderWin);
                }

                destroyedDevelopement = Math.Max(destroyedDevelopement, 0.0);
                destroyedDevelopement = Math.Min(destroyedDevelopement, 1.0);

                battle.Region.Development  -= (decimal)((double)battle.Region.Development * destroyedDevelopement);
                battle.DestroyedDevelopment = (decimal)destroyedDevelopement;


                ConditionalSaveChanges(battleRepository);
                trs?.Complete();
            }
        }