internal BattleSideStep(BattleSideStep step)
 {
     m_counts = new short[step.Counts.Length];
     Array.Copy(step.Counts, m_counts, m_counts.Length);
     m_healts = new int[step.Healts.Length];
     Array.Copy(step.Healts, m_healts, m_healts.Length);
     m_general = step.General;
 }
 public RoundStateArgs(BattleSideStep attackerStep, BattleSideStep enemyStep, int roundIndex)
 {
     m_enemyStep    = enemyStep;
     m_attackerStep = attackerStep;
     m_roundIndex   = roundIndex;
 }
 public RoundStateArgs(BattleStep battleStep, int roundIndex)
 {
     m_attackerStep = battleStep.Sides[(int)BattleSideType.Player];
     m_enemyStep    = battleStep.Sides[(int)BattleSideType.Enemy];
     m_roundIndex   = roundIndex;
 }
        private int AttackUnits2(
            Unit unit,
            int unitIndex,
            int unitCount,
            int targetIndex,
            Battle battle,
            BattleStep newStep,
            BattleSideType attackerSide,
            Random random,
            UnitAttackHandler unitAttackHandler)
        {
            BattleSideType defenderSideType = GetEnemySide(attackerSide);
            BattleSideStep defenderSideStep = newStep.Sides[(int)defenderSideType];

            int[] originalDamages = GetUnitsDamage(attackerSide, unit, unitCount, random);

            int[] reducedDamages = originalDamages;

            double towerBonus = battle.Sides[(int)defenderSideType].TowerBonus;

            if (towerBonus > 0 && unit.IgnoreTowerBonus != 100)
            {
                towerBonus = towerBonus * (1 - unit.IgnoreTowerBonus / 100);

                reducedDamages = new int[originalDamages.Length];
                for (int i = 0; i < originalDamages.Length; i++)
                {
                    reducedDamages[i] = (int)Math.Truncate(originalDamages[i] * towerBonus);
                }
            }

            if (targetIndex < 0)
            {
                targetIndex = GetTargetIndex(unit, defenderSideStep.Counts, defenderSideStep.Healts);
            }

            if (targetIndex < 0)
            {
                // no more targets
                return(-1);
            }

            int[] damages = GetDamageWithTargetUnitReduction(
                battle.Sides[(int)defenderSideType].Units[targetIndex],
                originalDamages,
                reducedDamages);

            int unitId = 0;

            foreach (int temp in damages)
            {
                int damage = temp;
                unitId++;
                if (unitAttackHandler != null)
                {
                    if (unit.AttackOnArea)
                    {
                        unitAttackHandler(null, new UnitAttackArgs(
                                              attackerSide,
                                              unitIndex,
                                              unitId,
                                              targetIndex,
                                              Math.Min(damage, defenderSideStep.Healts[targetIndex]),
                                              defenderSideStep.Healts[targetIndex]));
                    }
                    else
                    {
                        unitAttackHandler(null, new UnitAttackArgs(
                                              attackerSide,
                                              unitIndex,
                                              unitId,
                                              targetIndex,
                                              damage,
                                              defenderSideStep.Healts[targetIndex]));
                    }
                }
                defenderSideStep.Healts[targetIndex] -= damage;

                if (defenderSideStep.Healts[targetIndex] <= 0)
                {
                    defenderSideStep.Counts[targetIndex]--;
                    damage = -defenderSideStep.Healts[targetIndex];
                    int targetUnitHealth = battle.Sides[(int)defenderSideType].Units[targetIndex].Health;
                    defenderSideStep.Healts[targetIndex] = targetUnitHealth;

                    if (unit.AttackOnArea)
                    {
                        while (damage > 0)
                        {
                            targetUnitHealth = battle.Sides[(int)defenderSideType].Units[targetIndex].Health;
                            int remDamage;
                            int killedUnits = Math.DivRem(
                                damage,
                                targetUnitHealth,
                                out remDamage);

                            if (killedUnits < defenderSideStep.Counts[targetIndex])
                            {
                                defenderSideStep.Counts[targetIndex] -= (short)killedUnits;
                                defenderSideStep.Healts[targetIndex] -= (short)remDamage;
                                int prevDamage = 0;
                                if (defenderSideStep.Healts[targetIndex] <= 0)
                                {
                                    prevDamage = remDamage + defenderSideStep.Healts[targetIndex];
                                    remDamage  = remDamage - prevDamage;
                                    defenderSideStep.Counts[targetIndex]--;
                                    defenderSideStep.Healts[targetIndex] = targetUnitHealth;
                                }

                                damage = 0;
                                if (unitAttackHandler != null)
                                {
                                    if (prevDamage > 0)
                                    {
                                        unitAttackHandler(null, new UnitAttackArgs(
                                                              attackerSide,
                                                              unitIndex,
                                                              unitId,
                                                              targetIndex,
                                                              prevDamage,
                                                              battle.Sides[(int)defenderSideType].Units[targetIndex].Health));
                                    }

                                    for (int i = 0; i < killedUnits; i++)
                                    {
                                        unitAttackHandler(null, new UnitAttackArgs(
                                                              attackerSide,
                                                              unitIndex,
                                                              unitId,
                                                              targetIndex,
                                                              targetUnitHealth,
                                                              battle.Sides[(int)defenderSideType].Units[targetIndex].Health));
                                    }

                                    if (remDamage > 0)
                                    {
                                        unitAttackHandler(null, new UnitAttackArgs(
                                                              attackerSide,
                                                              unitIndex,
                                                              unitId,
                                                              targetIndex,
                                                              remDamage,
                                                              battle.Sides[(int)defenderSideType].Units[targetIndex].Health));
                                    }
                                }
                            }
                            else
                            {
                                // squad killed
                                damage -= defenderSideStep.Counts[targetIndex] * targetUnitHealth;
                                if (unitAttackHandler != null)
                                {
                                    for (int i = 0; i < defenderSideStep.Counts[targetIndex]; i++)
                                    {
                                        unitAttackHandler(null, new UnitAttackArgs(
                                                              attackerSide,
                                                              unitIndex,
                                                              unitId,
                                                              targetIndex,
                                                              targetUnitHealth,
                                                              targetUnitHealth));
                                    }
                                }
                                defenderSideStep.Counts[targetIndex] = 0;

                                targetIndex = GetTargetIndex(unit, defenderSideStep.Counts, defenderSideStep.Healts);

                                if (targetIndex < 0)
                                {
                                    // no more targets
                                    return(-1);
                                }
                                damages = GetDamageWithTargetUnitReduction(
                                    battle.Sides[(int)defenderSideType].Units[targetIndex],
                                    originalDamages,
                                    reducedDamages);
                            }
                        }
                    }

                    if (unit.AttackWeaknessTarget || defenderSideStep.Counts[targetIndex] == 0)
                    {
                        targetIndex = GetTargetIndex(unit, defenderSideStep.Counts, defenderSideStep.Healts);

                        if (targetIndex < 0)
                        {
                            return(targetIndex);
                        }

                        damages = GetDamageWithTargetUnitReduction(
                            battle.Sides[(int)defenderSideType].Units[targetIndex],
                            originalDamages,
                            reducedDamages);
                    }
                }
            }

            return(targetIndex);
        }