public async Task <int> InitiateFight(int opponentId) { Fight fight = new Fight(); Hero attacker = await this.heroService.GetHero(); this.CheckIfHeroIsWorking(attacker); this.CheckIfHeroCanAttackPlayer(attacker); this.CheckIfHeroAttackThemselves(attacker, opponentId); Hero defender = await this.heroService.GetHero(opponentId); this.CheckIfOpponentsAreSameFraction(attacker, defender); this.CheckIfInLevelBoundary(attacker, defender); this.CheckIfHeroCanBeAttacked(defender); await this.amuletBagService.EquipAmulet("PlayerAttack"); EquippedSet attackerSet = await this.equipmentService.GetEquippedSet(); EquippedSet defenderSet = await this.equipmentService.GetEquippedSet(defender.EquippedSetId); 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; int defenderAttack = FightFormulas.CalculateAttack(defender); int defenderDefense = FightFormulas.CalculateDefense(defender); int defenderMastery = FightFormulas.CalculateMastery(defender); int defenderDexterity = FightFormulas.CalculateDexterity(defender); int defenderMass = defender.Characteristics.Mass; HitType[] attackerHitTypes = new HitType[Rounds]; HitType[] defenderHitTypes = new HitType[Rounds]; int?[] attackerHits = new int?[Rounds]; int?[] defenderHits = new int?[Rounds]; string winnerName = string.Empty; int goldStolen = 0; for (int i = 0; i < Rounds; i++) { bool isCrit = FightFormulas.IsCrit( attackerMastery, defenderDexterity, attackerSet.Amulet?.Name == AmuletNames.Criticum ? attackerSet.Amulet.Bonus : 0); bool isDodged = FightFormulas.IsDodged(attackerAttack, defenderDexterity, 0); int attackerDamage = FightFormulas.CalculateHitDamage( attackerAttack, defenderDefense, isCrit, isDodged, attackerSet.Amulet?.Name == AmuletNames.Fatty ? attackerSet.Amulet.Bonus : 0); await this.healthService.ReduceHealth(attackerDamage, defender.HealthId); attackerHitTypes[i] = isDodged ? HitType.Dodged : isCrit ? HitType.Critical : HitType.Normal; attackerHits[i] = attackerDamage; if (await this.healthService.CheckIfDead(defender.HealthId)) { winnerName = attacker.Name; break; } isCrit = FightFormulas.IsCrit( defenderMastery, attackerDexterity, defenderSet.Amulet?.Name == AmuletNames.Criticum ? defenderSet.Amulet.Bonus : 0); isDodged = FightFormulas.IsDodged(defenderAttack, attackerDexterity, 0); int defenderDamage = FightFormulas.CalculateHitDamage( defenderAttack, attackerDefense, isCrit, isDodged, defenderSet.Amulet?.Name == AmuletNames.Fatty ? defenderSet.Amulet.Bonus : 0); await this.healthService.ReduceHealth(defenderDamage, attacker.HealthId); defenderHitTypes[i] = isDodged ? HitType.Dodged : isCrit ? HitType.Critical : HitType.Normal; defenderHits[i] = defenderDamage; if (await this.healthService.CheckIfDead(attacker.HealthId)) { winnerName = defender.Name; break; } } if (string.IsNullOrEmpty(winnerName)) { winnerName = attackerHits.Sum() > defenderHits.Sum() ? attacker.Name : defender.Name; } if (winnerName == attacker.Name) { goldStolen = ResourceFormulas.CalculateStolenGold( defender.ResourcePouch.Gold, this.GetGoldSafeBonus(defender)); await this.resourcePouchService.IncreaseResource(ResourceNames.Gold, goldStolen, attacker.ResourcePouchId); await this.resourcePouchService.DecreaseResource(ResourceNames.Gold, goldStolen, defender.ResourcePouchId); await this.levelService.GiveHeroExperience(ExperiencePerWin, attacker.LevelId); attacker.Statistics.TotalGoldStolen += goldStolen; attacker.Statistics.Wins++; defender.Statistics.Losses++; if (attacker.Statistics.MaximalGoldSteal < goldStolen) { attacker.Statistics.MaximalGoldSteal = goldStolen; } } else if (winnerName == defender.Name) { goldStolen = ResourceFormulas.CalculateStolenGold( attacker.ResourcePouch.Gold, this.GetGoldSafeBonus(attacker)); await this.resourcePouchService.IncreaseResource(ResourceNames.Gold, goldStolen, defender.ResourcePouchId); await this.resourcePouchService.DecreaseResource(ResourceNames.Gold, goldStolen, attacker.ResourcePouchId); await this.levelService.GiveHeroExperience(ExperiencePerWin, defender.LevelId); defender.Statistics.TotalGoldStolen += goldStolen; defender.Statistics.Wins++; attacker.Statistics.Losses++; if (defender.Statistics.MaximalGoldSteal < goldStolen) { defender.Statistics.MaximalGoldSteal = goldStolen; } } attacker.Statistics.TotalFights++; defender.Statistics.TotalFights++; await this.statisticsService.UpdateStatistics(attacker.Statistics); await this.statisticsService.UpdateStatistics(defender.Statistics); await this.chronometerService.SetCannotAttackHeroUntil(SecondsUntilNextHeroAttack, attacker.ChronometerId); await this.chronometerService.SetCannotBeAttackedUntil(SecondsDefenseGranted, defender.ChronometerId); #region Map Fight model fight.WinnerName = winnerName; fight.GoldStolen = goldStolen; fight.ExperienceGained = ExperiencePerWin; fight.AttackerDamageDealt = (int)attackerHits.Sum(); fight.DefenderDamageDealt = (int)defenderHits.Sum(); fight.AttackerHealthLeft = attacker.Health.Current; fight.DefenderHealthLeft = defender.Health.Current; fight.AttackerId = attacker.Id; fight.AttackerName = attacker.Name; fight.DefenderId = defender.Id; fight.DefenderName = defender.Name; fight.AttackerLevel = attacker.Level.CurrentLevel; fight.DefenderLevel = defender.Level.CurrentLevel; fight.AttackerAvatarUrl = attacker.AvatarUrl; fight.DefenderAvatarUrl = defender.AvatarUrl; fight.AttackerAttack = attackerAttack; fight.AttackerDefense = attackerDefense; fight.AttackerMastery = attackerMastery; fight.AttackerMass = attackerMass; fight.AttackerDexterity = attackerDexterity; fight.DefenderAttack = defenderAttack; fight.DefenderDefense = defenderDefense; fight.DefenderMastery = defenderMastery; fight.DefenderMass = defenderMass; fight.DefenderDexterity = defenderDexterity; 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 }); defender.HeroFights.Add(new HeroFight { Fight = fightEntity, Hero = defender }); await this.context.SaveChangesAsync(); Notification attackerNotification = new Notification() { ImageUrl = HeroFightNotificationImageUrl, Title = FightNotificationTitle, Link = string.Format(FightNotificationLink, fightEntity.Id), Content = string.Format(FightNotificationAttacker, defender.Name), Gold = winnerName == attacker.Name ? goldStolen : goldStolen * -1, Experience = winnerName == attacker.Name ? ExperiencePerWin : default(int?), Type = NotificationType.HeroFight, Hero = attacker, }; Notification defenderNotification = new Notification() { ImageUrl = HeroFightNotificationImageUrl, Title = FightNotificationTitle, Link = string.Format(FightNotificationLink, fightEntity.Id), Content = string.Format(FightNotificationDefender, attacker.Name), Gold = winnerName == defender.Name ? goldStolen : goldStolen * -1, Experience = winnerName == defender.Name ? ExperiencePerWin : default(int?), Type = NotificationType.HeroFight, Hero = defender, }; await this.notificationService.AddNotification(attackerNotification); await this.notificationService.AddNotification(defenderNotification); await this.amuletBagService.EquipAmulet("Idle"); return(fightEntity.Id); }
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); }