public int CalcAttackPower(IRole attacker, IRole attacked, ref InteractionEffect pSpecial)
        {
            if (attacked is Character)
            {
                Character pUser = attacked as Character;
                if (pUser.QueryTransformation != null && pUser.QueryTransformation.Lookface == 223)
                {
                    return(1);
                }
            }

            if (m_pOwner.Map.IsLineSkillMap())
            {
                return(1);
            }

            if (attacked.QueryStatus(FlagInt.VORTEX) != null)
            {
                return(1);
            }

            int nAttack = 0;

            if (Calculations.ChanceCalc(50))
            {
                nAttack = attacker.MaxAttack - ThreadSafeRandom.RandGet(1, Math.Max(1, attacker.MaxAttack - attacker.MinAttack) / 2 + 1);
            }
            else
            {
                nAttack = attacker.MinAttack + ThreadSafeRandom.RandGet(1, Math.Max(1, attacker.MaxAttack - attacker.MinAttack) / 2 + 1);
            }

            if (attacker is Character && attacked is Character && (attacker as Character).IsBowman())
            {
                nAttack = (int)(nAttack / 1.5f);
            }

            // handle physical status
            if (attacker.QueryStatus(FlagInt.STIG) != null)
            {
                float tPower = attacker.QueryStatus(FlagInt.STIG).Power;
                if (tPower > 30000)
                {
                    tPower  = (tPower - 30000) / 100f;
                    nAttack = (int)(nAttack * tPower);
                }
                else
                {
                    nAttack += (short)tPower;
                }
            }

            int nRawDefense = attacked.Defense;
            int nDef        = attacked.AdjustDefense(nRawDefense);

            if (attacker.QueryStatus(FlagInt.OBLIVION) != null &&
                !(attacked is Character) &&
                ((attacked is Monster) && !(attacked as Monster).IsBoss))
            {
                nAttack *= 2;
            }

            if (attacker.QueryStatus(FlagInt.FATAL_STRIKE) != null &&
                ((!attacked.IsDynaNpc() && !(attacked is Character))))
            {
                float tPower = attacker.QueryStatus(FlagInt.FATAL_STRIKE).Power;
                if (tPower > 30000)
                {
                    tPower  = (tPower - 30000) / 100f;
                    nAttack = (int)(nAttack * tPower);
                }
                else
                {
                    nAttack += (short)tPower;
                }

                if (attacked is Monster)
                {
                    Monster pMob = attacked as Monster;
                    if (pMob.IsGuard())
                    {
                        nAttack /= 10;
                    }
                }
            }

            if (attacker.QueryStatus(FlagInt.VORTEX) != null && !attacked.IsDynaNpc() && !(attacked is Character))
            {
                float tPower = attacker.QueryStatus(FlagInt.VORTEX).Power;
                if (tPower > 30000)
                {
                    tPower  = (tPower - 30000) / 100f;
                    nAttack = (int)(nAttack * tPower);
                }
                else
                {
                    nAttack += (short)tPower;
                }
            }

            if (attacker.QueryStatus(FlagInt.SUPERMAN) != null &&
                (!attacked.IsDynaNpc() && !(attacked is Character)))
            {
                float tPower = attacker.QueryStatus(FlagInt.SUPERMAN).Power;
                if (tPower > 30000)
                {
                    tPower  = (tPower - 30000) / 100f;
                    nAttack = (int)(nAttack * tPower);
                }
                else
                {
                    nAttack += (short)tPower;
                }
            }

            if (attacked.QueryStatus(FlagInt.SHIELD) != null)
            {
                float tPower = attacked.QueryStatus(FlagInt.SHIELD).Power;
                if (tPower > 30000)
                {
                    tPower = (tPower - 30000) / 100f;
                    nDef   = (int)(nDef * tPower);
                }
                else
                {
                    nDef += (short)tPower;
                }
            }

            if (attacker.Magics.QueryMagic() != null)
            {
                float tPower = attacker.Magics.QueryMagic().QueryPower();
                if (tPower > 30000)
                {
                    tPower  = (tPower - 30000) / 100f;
                    nAttack = (int)(nAttack * tPower);
                }
                else
                {
                    nAttack += (short)tPower;
                }
            }

            //float reduction = attacked.GetReduceDamage();
            int   nDamage = (int)((nAttack - nDef) * (1f - (attacked.GetReduceDamage() / 100f)));
            float tort    = (attacked.GetTortoiseGemEffect() / 100f);

            nDamage = (int)(nDamage * (1f - tort));

            if (nDamage <= 0)
            {
                nDamage = 7;
            }

            if (attacker is Character && attacked.IsMonster())
            {
                nDamage = CalcDamageUser2Monster(nAttack, nDef, attacker.Level, attacked.Level);
                nDamage = attacked.AdjustWeaponDamage(nDamage);
                nDamage = AdjustMinDamageUser2Monster(nDamage, attacker, attacked);
            }
            else if (attacker.IsMonster() && attacked is Character)
            {
                nDamage = CalcDamageMonster2User(nAttack, nDef, attacker.Level, attacked.Level);
                nDamage = attacked.AdjustWeaponDamage(nDamage);
                nDamage = AdjustMinDamageMonster2User(nDamage, attacker, attacked);
            }
            else
            {
                nDamage = attacked.AdjustWeaponDamage(nDamage);
            }

            //if (attacker is Character && attacked is Character && attacker.BattlePower < attacked.BattlePower)
            //{
            //    nDamage /= 2;
            //}

            #region Block, Critical, Break
            if (attacker.BattlePower < attacked.BattlePower)
            {
                if (attacked is Character)
                {
                    // Break (Pene is on the magic code)
                    // Break through the battle power cap...
                    // If the break fails, the damage is reduced by half.
                    if (attacked.Counteraction < attacker.Breakthrough)
                    {
                        if (!Calculations.ChanceCalc((float)(attacker.Breakthrough - attacked.Counteraction) / 10))
                        {
                            nDamage /= 2;
                        }
                        else
                        {
                            pSpecial |= InteractionEffect.BREAKTHROUGH;
                        }
                        //Owner.SendMessage(string.Format("Break: {0} Counter: {1} Difference: {2}%", GetBreakthrough(), pTarget.GetCounteraction(), (float)(GetBreakthrough() - pTarget.GetCounteraction()) / 10));
                    }
                    else
                    {
                        nDamage /= 2;
                    }
                }
            }

            // Critical is enabled on every monster. :)
            // Multiply the damage by 1.5
            if (attacker.CriticalStrike > attacked.Immunity)
            {
                if (Calculations.ChanceCalc((float)(attacker.CriticalStrike - attacked.Immunity) / 100))
                {
                    nDamage   = (int)(nDamage * 1.5f);
                    pSpecial |= InteractionEffect.CRITICAL_STRIKE;
                }
            }

            if (attacked.Block > 0 && Calculations.ChanceCalc((float)attacked.Block / 100))
            {
                nDamage  /= 10;
                pSpecial |= InteractionEffect.BLOCK;
            }

            if (QueryMagic() != null && QueryMagic().GetElement() > ElementType.NONE)
            {
                switch (QueryMagic().GetElement())
                {
                case ElementType.WATER:
                    pSpecial |= InteractionEffect.WATER_RESIST;
                    break;

                case ElementType.FIRE:
                    pSpecial |= InteractionEffect.FIRE_RESIST;
                    break;

                case ElementType.WOOD:
                    pSpecial |= InteractionEffect.WOOD_RESIST;
                    break;

                case ElementType.METAL:
                    pSpecial |= InteractionEffect.METAL_RESIST;
                    break;

                case ElementType.EARTH:
                    pSpecial |= InteractionEffect.EARTH_RESIST;
                    break;
                }
            }
            #endregion

            if (attacker is Monster && QueryMagic() != null && QueryMagic().GetElement() > ElementType.NONE)
            {
                switch (QueryMagic().GetElement())
                {
                case ElementType.WATER:
                {
                    nDamage = (int)(nDamage * (1 - (attacked.WaterResistance / 100f)));
                    break;
                }

                case ElementType.FIRE:
                {
                    nDamage = (int)(nDamage * (1 - (attacked.FireResistance / 100f)));
                    break;
                }

                case ElementType.EARTH:
                {
                    nDamage = (int)(nDamage * (1 - (attacked.EarthResistance / 100f)));
                    break;
                }

                case ElementType.WOOD:
                {
                    nDamage = (int)(nDamage * (1 - (attacked.WoodResistance / 100f)));
                    break;
                }

                case ElementType.METAL:
                {
                    nDamage = (int)(nDamage * (1 - (attacked.MetalResistance / 100f)));
                    break;
                }
                }
            }

            if (attacker is Character)
            {
                nDamage += attacker.AddFinalAttack;
            }

            if (attacked is Character)
            {
                nDamage -= attacked.AddFinalDefense;
            }

            if (attacked is Monster)
            {
                nDamage = (int)Math.Min(nDamage, attacked.MaxLife * 700);
            }

            if (nDamage <= 0)
            {
                nDamage = 1;
            }

            return(nDamage);
        }