public void ExecuteTurn_WhenDoesNotHaveObjectsInCurrentRoundAndGroupRandomReturns0AndObjectRandomReturns1_ShouldReturnSecondObjectFromFirstGroup( [Frozen] IBattleRandom battleRandom, BattleOrder battleOrder) { // 999 controls order to be defense // 0 is the first group idx // 1 is the second combat obj idx // 1 is the random obj after we've found no objects are in the current round // 0 is going to be when looking into the attacker list (for group and obj) after it didnt find a defense battleRandom.Next(Arg.Any <int>()).Returns(999, 0, 1, 1, 0); ICombatObject outCombatObject; ICombatGroup outCombatGroup; BattleManager.BattleSide foundInGroup; var attackerObject = CreateCombatObject(round: 1); var attackerGroup = CreateGroup(attackerObject); var attackerList = CreateList(upkeepNotParticipated: 1, combatGroups: attackerGroup); var defenderObject1 = CreateCombatObject(round: 1); var defenderObject2 = CreateCombatObject(round: 1); var defenderGroup = CreateGroup(defenderObject1, defenderObject2); var defenderList = CreateList(upkeepNotParticipated: 999, combatGroups: defenderGroup); var result = battleOrder.NextObject(0, attackerList, defenderList, out outCombatObject, out outCombatGroup, out foundInGroup); result.Should().Be(false); outCombatObject.Should().Be(defenderObject2); ((object)outCombatGroup).Should().Be(defenderGroup); foundInGroup.Should().Be(BattleManager.BattleSide.Defense); }
public void ExecuteTurn_WhenDoesNotHaveObjectsInCurrentRoundAndGroupRandomReturns0AndFirstGroupIsEmpty_ShouldReturnObjectFromSecondGroup( [Frozen] IBattleRandom battleRandom, BattleOrder battleOrder) { // 999 controls order to be defense // 0 is the to always return first obj and first group battleRandom.Next(Arg.Any <int>()).Returns(999, 0); ICombatObject outCombatObject; ICombatGroup outCombatGroup; BattleManager.BattleSide foundInGroup; var attackerObject = CreateCombatObject(round: 1); var attackerGroup = CreateGroup(attackerObject); var attackerList = CreateList(upkeepNotParticipated: 1, combatGroups: attackerGroup); var defenderGroup1 = CreateGroup(); var defenderObject2 = CreateCombatObject(round: 1); var defenderGroup2 = CreateGroup(defenderObject2); var defenderList = CreateList(upkeepNotParticipated: 999, combatGroups: new [] { defenderGroup1, defenderGroup2 }); var result = battleOrder.NextObject(0, attackerList, defenderList, out outCombatObject, out outCombatGroup, out foundInGroup); result.Should().Be(false); outCombatObject.Should().Be(defenderObject2); ((object)outCombatGroup).Should().Be(defenderGroup2); foundInGroup.Should().Be(BattleManager.BattleSide.Defense); }
public override void CalcActualDmgToBeTaken(ICombatList attackers, ICombatList defenders, IBattleRandom random, decimal baseDmg, int attackIndex, out decimal actualDmg) { // Miss chance actualDmg = BattleFormulas.GetDmgWithMissChance(attackers.UpkeepExcludingWaitingToJoinBattle, defenders.UpkeepExcludingWaitingToJoinBattle, baseDmg, random); // Splash dmg reduction actualDmg = BattleFormulas.SplashReduction(this, actualDmg, attackIndex); // if hp is less than 20% of the original total HP(entire group), lastStand kicks in. if (Hp < (Hp + DmgRecv) / 5m) { var lastStandEffects = TroopStub.City.Technologies.GetEffects(EffectCode.LastStand); var percent = lastStandEffects.Where( tech => BattleFormulas.UnitStatModCheck(Stats.Base, TroopBattleGroup.Attack, (string)tech.Value[1])) .DefaultIfEmpty() .Max(x => x == null ? 0 : (int)x.Value[0]); actualDmg = actualDmg * (100 - percent) / 100m; } }
public void ExecuteTurn_WhenGroupRandomReturns1AndGroupHasNoObjectsLeft_ShouldReturnFirstObjectFromFirstGroup( [Frozen] IBattleRandom battleRandom, BattleOrder battleOrder) { // 999 controls order to be defense // 1 is the second group idx // 0 is the first combat obj idx battleRandom.Next(Arg.Any <int>()).Returns(999, 1, 0); ICombatObject outCombatObject; ICombatGroup outCombatGroup; BattleManager.BattleSide foundInGroup; var attackerObject = CreateCombatObject(round: 0); var attackerGroup = CreateGroup(attackerObject); var attackerList = CreateList(upkeepNotParticipated: 1, combatGroups: attackerGroup); var defenderObject1 = CreateCombatObject(round: 0); var defenderGroup1 = CreateGroup(defenderObject1); var defenderObject2 = CreateCombatObject(round: 1); var defenderGroup2 = CreateGroup(defenderObject2); var defenderList = CreateList(upkeepNotParticipated: 999, combatGroups: new [] { defenderGroup1, defenderGroup2 }); var result = battleOrder.NextObject(0, attackerList, defenderList, out outCombatObject, out outCombatGroup, out foundInGroup); result.Should().Be(true); outCombatObject.Should().Be(defenderObject1); ((object)outCombatGroup).Should().Be(defenderGroup1); foundInGroup.Should().Be(BattleManager.BattleSide.Defense); }
public BattleManager(uint battleId, BattleLocation location, BattleOwner owner, IRewardStrategy rewardStrategy, IDbManager dbManager, IBattleReport battleReport, ICombatListFactory combatListFactory, IBattleFormulas battleFormulas, IBattleOrder battleOrder, IBattleRandom battleRandom) { groupIdGen = new LargeIdGenerator(uint.MaxValue); idGen = new LargeIdGenerator(uint.MaxValue); // Group id 1 is always reserved for local troop groupIdGen.Set(1); BattleId = battleId; Location = location; Owner = owner; BattleReport = battleReport; Attackers = combatListFactory.GetAttackerCombatList(); Defenders = combatListFactory.GetDefenderCombatList(); this.rewardStrategy = rewardStrategy; this.dbManager = dbManager; this.battleOrder = battleOrder; this.battleFormulas = battleFormulas; this.battleRandom = battleRandom; }
public override void CalcActualDmgToBeTaken(ICombatList attackers, ICombatList defenders, IBattleRandom random, decimal baseDmg, int attackIndex, out decimal actualDmg) { actualDmg = baseDmg / 10; }
public override void CalcActualDmgToBeTaken(ICombatList attackers, ICombatList defenders, IBattleRandom random, decimal baseDmg, int attackIndex, out decimal actualDmg) { // Miss chance actualDmg = BattleFormulas.GetDmgWithMissChance(attackers.UpkeepExcludingWaitingToJoinBattle, defenders.UpkeepExcludingWaitingToJoinBattle, baseDmg, random); }
public PublicBattleManager(uint battleId, BattleLocation location, BattleOwner owner, IRewardStrategy rewardStrategy, IDbManager dbManager, IBattleReport battleReport, ICombatListFactory combatListFactory, IBattleFormulas battleFormulas, IBattleOrder battleOrder, IBattleRandom battleRandom) : base(battleId, location, owner, rewardStrategy, dbManager, battleReport, combatListFactory, battleFormulas, battleOrder, battleRandom) { }
public StrongholdMainBattleManager(uint battleId, BattleLocation location, BattleOwner owner, IRewardStrategy rewardStrategy, IDbManager dbManager, IBattleReport battleReport, ICombatListFactory combatListFactory, IGameObjectLocator gameObjectLocator, IBattleOrder battleOrder, IBattleFormulas battleFormulas, IBattleRandom random) : base(battleId, location, owner, rewardStrategy, dbManager, battleReport, combatListFactory, battleFormulas, battleOrder, random) { this.gameObjectLocator = gameObjectLocator; }
public BattleManagerGate(uint battleId, IStronghold stronghold, BattleLocation location, BattleOwner owner, IRewardStrategy rewardStrategy, IDbManager dbManager, IBattleReport battleReport, ICombatListFactory combatListFactory, IBattleFormulas battleFormulas, IBattleOrder battleOrder, IBattleRandom battleRandom) : base(battleId, location, owner, rewardStrategy, dbManager, battleReport, combatListFactory, battleFormulas, battleOrder, battleRandom) { this.stronghold = stronghold; precision = 1m + (new Random((int)(owner.Id + battleId + location.Id)).Next(-20, 20) / 100m); }
public override void CalcActualDmgToBeTaken(ICombatList attackers, ICombatList defenders, IBattleRandom random, decimal baseDmg, int attackIndex, out decimal actualDmg) { // Miss chance actualDmg = BattleFormulas.GetDmgWithMissChance(attackers.UpkeepExcludingWaitingToJoinBattle, defenders.UpkeepExcludingWaitingToJoinBattle, baseDmg, random); // Splash dmg reduction actualDmg = BattleFormulas.SplashReduction(this, actualDmg, attackIndex); // AP Bonuses if (City.AlignmentPoint >= 90m) { actualDmg *= .1m; } }
public virtual decimal GetDmgWithMissChance(int attackersUpkeep, int defendersUpkeep, decimal dmg, IBattleRandom random) { double delta = Math.Max(0, (double)attackersUpkeep / defendersUpkeep); double effectiveness = attackersUpkeep > 200 ? 1 : (double)attackersUpkeep / 200; int missChance; if (delta < 1) { missChance = (int)(0 * effectiveness); } else if (delta < 1.25) { missChance = (int)(10 * effectiveness); } else if (delta < 1.5) { missChance = (int)(17 * effectiveness); } else if (delta < 2) { missChance = (int)(22 * effectiveness); } else if (delta < 3.5) { missChance = (int)(30 * effectiveness); } else if (delta < 5) { missChance = (int)(40 * effectiveness); } else if (delta < 7) { missChance = (int)(48 * effectiveness); } else if (delta < 10) { missChance = (int)(55 * effectiveness); } else { missChance = (int)(60 * effectiveness); } var rand = (int)(random.NextDouble() * 100); if (missChance <= 0 || rand > missChance) { return(dmg); } return(dmg / 2m); }
public override void CalcActualDmgToBeTaken(ICombatList attackers, ICombatList defenders, IBattleRandom random, decimal baseDmg, int attackIndex, out decimal actualDmg) { throw new NotImplementedException(); }
public abstract void CalcActualDmgToBeTaken(ICombatList attackers, ICombatList defenders, IBattleRandom random, decimal baseDmg, int attackIndex, out decimal actualDmg);
public BattleOrder(IBattleRandom random) { this.random = random; }