private Characteristics GenerateFightMonsterCharacteristics(int monsterLevel, int monsterBattlePowerPercent, Characteristics heroCharacteristics)
        {
            Characteristics monsterCharacteristics = new Characteristics();

            int heroBattlePower = CharacteristicsFormulas.CalculateBattlePower(heroCharacteristics);

            Random random = new Random();

            int maxPercent              = MaxPercent;
            int monsterAttackPercent    = random.Next(MinimumPercentAttack, MaximumPercentAttack);
            int monsterDefensePercent   = random.Next(MinimumPercentDefense, MaximumPercentDefense);
            int monsterMasteryPercent   = random.Next(MinimumPercentMastery, MaximumPercentMastery);
            int monsterDexterityPercent = maxPercent - monsterAttackPercent - monsterDefensePercent - monsterMasteryPercent;
            int monsterBattlePower      = MonsterFormulas.CalculateBattlePower(heroBattlePower, monsterBattlePowerPercent);

            monsterCharacteristics.Attack    = MonsterFormulas.CalculateAttack(monsterLevel, monsterBattlePower, monsterAttackPercent);
            monsterCharacteristics.Defense   = MonsterFormulas.CalculateDefense(monsterLevel, monsterBattlePower, monsterAttackPercent);
            monsterCharacteristics.Mastery   = MonsterFormulas.CalculateMastery(monsterLevel, monsterBattlePower, monsterMasteryPercent);
            monsterCharacteristics.Dexterity = MonsterFormulas.CalculateDexterity(monsterLevel, monsterBattlePower, monsterDexterityPercent);
            monsterCharacteristics.Mass      = heroCharacteristics.Mass;

            return(monsterCharacteristics);
        }
Exemple #2
0
        public async Task <int> InitiateMonsterFight(int monsterLevel = 0)
        {
            Random random = new Random();
            Fight  fight  = new Fight();

            Hero attacker = await this.heroService.GetHero();

            this.CheckIfHeroIsWorking(attacker);
            this.CheckIfHeroCanAttackMonster(attacker);

            await this.amuletBagService.EquipAmulet("MonsterAttack");

            if (monsterLevel == 0)
            {
                monsterLevel = random.Next(RandomMonsterMinimumLevel, RandomMonsterMaximumLevel);

                await this.resourcePouchService.DecreaseResource(ResourceNames.Gold, RandomMonsterGoldCost);
            }
            else
            {
                await this.resourcePouchService.DecreaseResource(ResourceNames.Crystals, MonsterCrystalCost);
            }

            Monster databaseMonster = await this.monsterService.GetMonsterByLevel(monsterLevel);

            FightMonster monster = await this.monsterService.GenerateFightMonster(databaseMonster);

            EquippedSet attackerSet = await this.equipmentService.GetEquippedSet();

            int attackerAttack    = FightFormulas.CalculateAttack(attacker);
            int attackerDefense   = FightFormulas.CalculateDefense(attacker);
            int attackerMastery   = FightFormulas.CalculateMastery(attacker);
            int attackerDexterity = FightFormulas.CalculateDexterity(attacker);
            int attackerMass      = attacker.Characteristics.Mass;

            HeroAmulet heroAmulet = attacker.EquippedSet.Amulet;

            if (heroAmulet?.Name == AmuletNames.Undergrounder)
            {
                attackerAttack    = (int)(attackerAttack * (1 + (heroAmulet.Bonus / 100)));
                attackerDefense   = (int)(attackerDefense * (1 + (heroAmulet.Bonus / 100)));
                attackerMastery   = (int)(attackerMastery * (1 + (heroAmulet.Bonus / 100)));
                attackerDexterity = (int)(attackerDexterity * (1 + (heroAmulet.Bonus / 100)));
            }

            int?[]    attackerHits     = new int?[Rounds];
            int?[]    defenderHits     = new int?[Rounds];
            HitType[] attackerHitTypes = new HitType[Rounds];
            HitType[] defenderHitTypes = new HitType[Rounds];
            string    winnerName       = string.Empty;
            int       goldStolen       = 0;

            for (int i = 0; i < Rounds; i++)
            {
                bool isCrit = FightFormulas.IsCrit(
                    attackerMastery,
                    monster.Characteristics.Dexterity,
                    attackerSet.Amulet?.Name == AmuletNames.Criticum ? attackerSet.Amulet.Bonus : 0);

                bool isDodged = FightFormulas.IsDodged(attackerAttack, monster.Characteristics.Dexterity, 0);

                int attackerDamage = FightFormulas.CalculateHitDamage(
                    attackerAttack,
                    monster.Characteristics.Defense,
                    isCrit,
                    isDodged,
                    attackerSet.Amulet?.Name == AmuletNames.Fatty ? attackerSet.Amulet.Bonus : 0);

                monster.Health -= attackerDamage;
                if (monster.Health < 1)
                {
                    monster.Health = 1;
                }

                attackerHits[i]     = attackerDamage;
                attackerHitTypes[i] = isDodged ? HitType.Dodged : isCrit ? HitType.Critical : HitType.Normal;

                if (monster.Health == 1)
                {
                    winnerName = attacker.Name;
                    break;
                }

                isCrit   = FightFormulas.IsCrit(monster.Characteristics.Attack, attackerDexterity, 0);
                isDodged = FightFormulas.IsDodged(monster.Characteristics.Attack, attackerDexterity, 0);

                int defenderDamage = FightFormulas.CalculateHitDamage(
                    monster.Characteristics.Attack,
                    attackerDefense,
                    isCrit,
                    isDodged,
                    0);

                await this.healthService.ReduceHealth(defenderDamage, attacker.HealthId);

                defenderHits[i]     = defenderDamage;
                defenderHitTypes[i] = isDodged ? HitType.Dodged : isCrit ? HitType.Critical : HitType.Normal;

                if (await this.healthService.CheckIfDead(attacker.HealthId))
                {
                    winnerName = monster.Name;
                    break;
                }
            }

            if (string.IsNullOrEmpty(winnerName))
            {
                winnerName = attackerHits.Sum() > defenderHits.Sum() ? attacker.Name : monster.Name;
            }

            if (winnerName == attacker.Name)
            {
                goldStolen = MonsterFormulas.CalculateReward(databaseMonster, attacker.Level.CurrentLevel);

                await this.resourcePouchService.IncreaseResource(ResourceNames.Gold, goldStolen, attacker.ResourcePouchId);

                await this.levelService.GiveHeroExperience(monster.Level, attacker.LevelId);

                attacker.Statistics.EarnedFromMonsters += goldStolen;
                attacker.Statistics.MonstersDefeated++;
            }
            else if (winnerName == monster.Name)
            {
                goldStolen = ResourceFormulas.CalculateStolenGold(
                    attacker.ResourcePouch.Gold,
                    this.GetGoldSafeBonus(attacker));

                await this.resourcePouchService.DecreaseResource(ResourceNames.Gold, goldStolen, attacker.ResourcePouchId);
            }

            await this.statisticsService.UpdateStatistics(attacker.Statistics);

            await this.chronometerService.SetCannotAttackMonsterUntil(SecondsUntilNextMonsterAttack, attacker.ChronometerId);

            #region Map Fight entity
            fight.WinnerName          = winnerName;
            fight.GoldStolen          = goldStolen;
            fight.ExperienceGained    = monster.Level;
            fight.AttackerDamageDealt = (int)attackerHits.Sum();
            fight.DefenderDamageDealt = (int)defenderHits.Sum();
            fight.AttackerHealthLeft  = attacker.Health.Current;
            fight.DefenderHealthLeft  = monster.Health;

            fight.AttackerId        = attacker.Id;
            fight.AttackerName      = attacker.Name;
            fight.DefenderName      = monster.Name;
            fight.AttackerLevel     = attacker.Level.CurrentLevel;
            fight.DefenderLevel     = monster.Level;
            fight.AttackerAvatarUrl = attacker.AvatarUrl;
            fight.DefenderAvatarUrl = monster.AvatarUrl;

            fight.AttackerAttack    = attackerAttack;
            fight.AttackerDefense   = attackerDefense;
            fight.AttackerMastery   = attackerMastery;
            fight.AttackerMass      = attackerMass;
            fight.AttackerDexterity = attackerDexterity;
            fight.DefenderAttack    = monster.Characteristics.Attack;
            fight.DefenderDefense   = monster.Characteristics.Defense;
            fight.DefenderMastery   = monster.Characteristics.Mastery;
            fight.DefenderMass      = monster.Characteristics.Mass;
            fight.DefenderDexterity = monster.Characteristics.Dexterity;

            fight.AttackerHitOne   = attackerHits[0];
            fight.AttackerHitTwo   = attackerHits[1];
            fight.AttackerHitThree = attackerHits[2];
            fight.AttackerHitFour  = attackerHits[3];
            fight.AttackerHitFive  = attackerHits[4];
            fight.DefenderHitOne   = defenderHits[0];
            fight.DefenderHitTwo   = defenderHits[1];
            fight.DefenderHitThree = defenderHits[2];
            fight.DefenderHitFour  = defenderHits[3];
            fight.DefenderHitFive  = defenderHits[4];

            fight.AttackerHitOneType   = attackerHitTypes[0];
            fight.AttackerHitTwoType   = attackerHitTypes[1];
            fight.AttackerHitThreeType = attackerHitTypes[2];
            fight.AttackerHitFourType  = attackerHitTypes[3];
            fight.AttackerHitFiveType  = attackerHitTypes[4];
            fight.DefenderHitOneType   = defenderHitTypes[0];
            fight.DefenderHitTwoType   = defenderHitTypes[1];
            fight.DefenderHitThreeType = defenderHitTypes[2];
            fight.DefenderHitFourType  = defenderHitTypes[3];
            fight.DefenderHitFiveType  = defenderHitTypes[4];
            #endregion

            Fight fightEntity = this.context.Fights.AddAsync(fight).Result.Entity;
            attacker.HeroFights.Add(new HeroFight {
                Fight = fightEntity, Hero = attacker
            });
            await this.context.SaveChangesAsync();

            Notification notification = new Notification()
            {
                ImageUrl   = MonsterFightNotificationImageUrl,
                Title      = FightNotificationTitle,
                Link       = string.Format(FightNotificationLink, fightEntity.Id),
                Content    = string.Format(FightNotificationAttacker, monster.Name),
                Gold       = winnerName == attacker.Name ? goldStolen : goldStolen * -1,
                Experience = winnerName == attacker.Name ? monster.Level : default(int?),
                Type       = NotificationType.MonsterFight,
                Hero       = attacker,
            };
            await this.notificationService.AddNotification(notification);

            await this.amuletBagService.EquipAmulet("Idle");

            return(fightEntity.Id);
        }