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); }