private void CreatureFightSimulation(Fight fight, SimulationType type, FightSimulationResult.Info info, CreatureRef attackerRef, CreatureRef defenderRef, TextWriter log) { string val = string.Format("Fight simulation ({2}) between {0} and {1}", attackerRef.Name, defenderRef.Name, System.Enum.GetName(type.GetType(), type)); string dash = new string('-', val.Length); log.WriteLine(dash); log.WriteLine(val); log.WriteLine(dash); AttackType attackType = attackerRef.AttackType[0]; int attackerCount = attackerRef.Count; int attackerDamageLeft = 0; int defenderCount = defenderRef.Count; int defenderDamageLeft = 0; CreatureRef currentAttackerRef = attackerRef; CreatureRef currentDefenderRef = defenderRef; Hero attackerHero = Fight.Attacker; Hero defenderHero = Fight.Defender; int rounds = 0; do { log.WriteLine("ROUND: {0}", rounds + 1); log.WriteLine("*** Strike ***"); FightResult strike = CreatureFight(Fight, attackerHero, defenderHero, currentAttackerRef, currentDefenderRef, attackerCount, defenderCount, log, attackType, defenderDamageLeft); defenderCount = UpdateKillsCount(defenderCount, strike, type); defenderDamageLeft = GetLeftDamage(strike, type); FightResult counterStrike = new FightResult(); int retaliations = strike.Retaliations; if (retaliations > 0 && defenderCount > 0) { log.WriteLine("*** Counterstrike ***"); log.WriteLine("Conterstrike attack, atack type is always melee"); counterStrike = CreatureFight(Fight, defenderHero, attackerHero, currentDefenderRef, currentAttackerRef, defenderCount, attackerCount, log, AttackType.Melee, attackerDamageLeft); --retaliations; attackerCount = UpdateKillsCount(attackerCount, counterStrike, type); attackerDamageLeft = GetLeftDamage(counterStrike, type); } if (strike.DoubleAttack && attackerCount > 0) { log.WriteLine("*** Double Attack ***"); FightResult secondStrike = CreatureFight(Fight, attackerHero, defenderHero, currentAttackerRef, currentDefenderRef, attackerCount, defenderCount, log, attackType, defenderDamageLeft); defenderCount = UpdateKillsCount(defenderCount, secondStrike, type); defenderDamageLeft = GetLeftDamage(secondStrike, type); MergeFightResult(strike, secondStrike); } if (retaliations > 0 && defenderCount > 0) { log.WriteLine("*** Counterstrike ***"); log.WriteLine("Conterstrike attack, atack type is always melee"); FightResult secondCounterStrike = CreatureFight(Fight, defenderHero, attackerHero, currentDefenderRef, currentAttackerRef, defenderCount, attackerCount, log, AttackType.Melee, attackerDamageLeft); --retaliations; attackerCount = UpdateKillsCount(attackerCount, secondCounterStrike, type); attackerDamageLeft = GetLeftDamage(secondCounterStrike, type); MergeFightResult(counterStrike, secondCounterStrike); } if (attackerRef.AttackType[0] == AttackType.Melee || defenderRef.AttackType[0] == AttackType.Melee) { log.WriteLine("One of the fighers did melee attack, rest of the battle is melee."); attackType = AttackType.Melee; } // store info about first attack if (rounds == 0) { info.Strike = strike; switch (type) { case SimulationType.MinimalDamage: info.CounterMin = counterStrike; break; case SimulationType.MaximalDamage: info.CounterMax = counterStrike; break; case SimulationType.AverageDamage: info.CounterAvg = counterStrike; break; default: break; } } CreatureRef tmp = currentDefenderRef; int countTmp = defenderCount; int dmgLeftTmp = defenderDamageLeft; Hero heroTmp = defenderHero; currentDefenderRef = currentAttackerRef; currentAttackerRef = tmp; defenderCount = attackerCount; attackerCount = countTmp; defenderDamageLeft = attackerDamageLeft; attackerDamageLeft = dmgLeftTmp; defenderHero = attackerHero; attackerHero = heroTmp; ++rounds; }while (attackerCount > 0 && defenderCount > 0); FightFinalResult res = new FightFinalResult(); if (rounds % 2 > 0) { res.AttackerLeft = defenderCount; res.DefenderLeft = attackerCount; } else { res.AttackerLeft = attackerCount; res.DefenderLeft = defenderCount; } res.Rounds = rounds; switch (type) { case SimulationType.MinimalDamage: info.FinalMin = res; break; case SimulationType.MaximalDamage: info.FinalMax = res; break; case SimulationType.AverageDamage: info.FinalAvg = res; break; default: break; } }