Action(AttackingTroops attackingTroops, DefendingTroops defendingTroops, int wallStage) { //Attack and defense values for the archery phase ArcheryDefensePhase archeryDefensePhase = new ArcheryDefensePhase(); int defenseValue = archeryDefensePhase.CalculateDefenseValue(defendingTroops.ArcheryPhaseDefendingUnits); int attackValue = attackingTroops.CalculateAttackValue(attackingTroops.ArcheryPhaseTroops); //Apply the effects of the wall double wallDefenseMultiplier = wallStage * 0.05 + 1; defenseValue = (int)Math.Ceiling(defenseValue * wallDefenseMultiplier); defenseValue += wallStage * 10; if (attackingTroops.ArcheryPhaseTroops.Count == 0 || defendingTroops.ArcheryPhaseDefendingUnits.Count == 0) { return(attackingTroops.ArcheryPhaseTroops, defendingTroops.ArcheryPhaseDefendingUnits); } return(attackingTroops.Fight(attackingTroops.ArcheryPhaseTroops, defendingTroops.ArcheryPhaseDefendingUnits, attackValue, defenseValue)); }
public async Task <MediatR.Unit> Handle(Command request, CancellationToken cancellationToken) { //Initialize the variables for the attack process var initValues = await InitAttackProcess(request.Request); AttackingTroops attackingTroops = initValues.attackingTroops; DefendingTroops defendingTroops = initValues.defendingTroops; IEnumerable <UnitsInCity> unitsOfAttacker = initValues.unitsOfAttacker; IEnumerable <UnitsInCity> defendingUnits = initValues.defendingUnits; int wallStage = initValues.wallStage; var infantryPhaseResult = new InfantryAttackPhaseBehaviour().Action(attackingTroops, defendingTroops, wallStage); //Add the survivors of the previous phase to the next one defendingTroops.AddSurvivorsOfPreviousPhase(infantryPhaseResult.defendingTroops, defendingTroops.CavalryPhaseDefendingUnits); attackingTroops.AddSurvivorsOfPreviousPhase(infantryPhaseResult.attackerTroops, attackingTroops.CavalryPhaseTroops); var cavalryPhaseResult = new CavalryAttackPhaseBehaviour().Action(attackingTroops, defendingTroops, wallStage); //Add the survivors of the previous phase to the next one defendingTroops.AddSurvivorsOfPreviousPhase(cavalryPhaseResult.defendingTroops, defendingTroops.ArcheryPhaseDefendingUnits); attackingTroops.AddSurvivorsOfPreviousPhase(cavalryPhaseResult.attackerTroops, attackingTroops.ArcheryPhaseTroops); var archeryPhaseResult = new ArcheryAttackPhaseBehaviour().Action(attackingTroops, defendingTroops, wallStage); //Update the attacking side foreach (var item in archeryPhaseResult.attackerTroops) { foreach (var unitsInCity in unitsOfAttacker) { if (unitsInCity.Unit.Name.Equals(item.Key.Name)) { var fallenSoldierAmount = (request.Request.AttackingForces.First(x => x.Key.Equals(item.Key.Name)).Value - item.Value); unitsInCity.Amount -= fallenSoldierAmount; initValues.attackerCity.Resources.Population += fallenSoldierAmount * item.Key.UnitCost.Population; } } } int initialWoodAmount = initValues.attackerCity.Resources.Wood; int initialStoneAmount = initValues.attackerCity.Resources.Stone; int initialSilverAmount = initValues.attackerCity.Resources.Silver; //Steal resources int totalCarryingCapacity = CalculateCarryingCapacity(archeryPhaseResult.attackerTroops); if (totalCarryingCapacity > 0) { ResourceStealingProcess(initValues.attackerCity, initValues.defenderCity, totalCarryingCapacity); CheckWarehouseCapacity(initValues.attackerCity); } int stolenWoodAmount = initValues.attackerCity.Resources.Wood - initialWoodAmount; int stolenStoneAmount = initValues.attackerCity.Resources.Stone - initialStoneAmount; int stolenSilverAmount = initValues.attackerCity.Resources.Silver - initialSilverAmount; await _reportSender.CreateReport(initValues.attackerName, initValues.attackerCity.CityName, initValues.defenderName, initValues.defenderCity.CityName, archeryPhaseResult.attackerTroops, archeryPhaseResult.defendingTroops, request.Request.AttackingForces, initValues.defendingUnits, stolenWoodAmount, stolenStoneAmount, stolenSilverAmount); //Update the defending side foreach (var item in archeryPhaseResult.defendingTroops) { var fallenSoldierAmount = defendingUnits.First(d => d.Unit.Name.Equals(item.Key.Name)).Amount - item.Value; initValues.defenderCity.Resources.Population += fallenSoldierAmount * item.Key.UnitCost.Population; defendingUnits.First(d => d.Unit.Name.Equals(item.Key.Name)).Amount = item.Value; } await _unitOfWork.CommitChangesAsync(); return(new MediatR.Unit()); }
string attackerName, City attackerCity, string defenderName, City defenderCity)> InitAttackProcess(AttackRequest request) { var attackingUser = await _unitOfWork.Users.GetUserWithCities(_identityContext.UserId); var defendingUser = await _unitOfWork.Users.GetUserWithCities(request.AttackedUserId); if (defendingUser == null || attackingUser == null) { throw new NotFoundException(); } var attackingCity = attackingUser.Cities.ElementAt(request.AttackerCityIndex); if (attackingCity == null) { throw new NotFoundException(); } var defendingCity = defendingUser.Cities.ElementAt(request.AttackedCityIndex); if (defendingCity == null) { throw new NotFoundException(); } var unitsOfAttacker = await _unitOfWork.Units.GetUnitsInCityByBarrackId(attackingCity.BarrackId); IEnumerable <BackEnd.Models.Models.Unit> allUnitTypes = await _unitOfWork.Units.GetAllUnitsAsync(); //Convert the dto into a model in order to use it for the attack calculations Dictionary <BackEnd.Models.Models.Unit, int> attackingForces = new Dictionary <BackEnd.Models.Models.Unit, int>(); try { foreach (var type in allUnitTypes) { bool found = false; foreach (var troop in request.AttackingForces) { if (troop.Key.Equals(type.Name)) { attackingForces.Add(type, troop.Value); found = true; } } if (!found) { attackingForces.Add(type, 0); } } /* foreach (var item in request.AttackingForces) * attackingForces.Add(allUnitTypes.First(unit => unit.Name.Equals(item.Key)), item.Value);*/ } catch (InvalidOperationException) { throw new BadRequestException("Invalid unit type name"); } AttackingTroops attackingTroops = new AttackingTroops(attackingForces); //Get the defending units var defendingUnits = await _unitOfWork.Units.GetUnitsInCityByBarrackId(defendingUser.Cities.ElementAt(request.AttackedCityIndex).BarrackId); var tmp = defendingUnits.ToList(); foreach (var type in allUnitTypes) { bool found = false; foreach (var troop in tmp) { if (troop.Unit.Name.Equals(type.Name)) { found = true; } } if (!found) { tmp.Add(new UnitsInCity { Amount = 0, Barrack = defendingCity.Barrack, BarrackId = defendingCity.BarrackId, Unit = type, UnitId = type.Id }); } } defendingUnits = tmp; DefendingTroops defendingTroops = new DefendingTroops(defendingUnits, attackingTroops.InfantryProvisionPercentage, attackingTroops.CavalryProvisionPercentage, attackingTroops.ArcheryProvisionPercentage); int wallStage = defendingUser.Cities.ElementAt(request.AttackedCityIndex).CityWall.Stage; return(attackingTroops, defendingTroops, unitsOfAttacker, defendingUnits, wallStage, attackingUser.UserName, attackingCity, defendingUser.UserName, defendingCity); }