// https://gamefaqs.gamespot.com/snes/563501-the-7th-saga/faqs/54038 (function(exports) { exports.physicalAttack = ( attackerPowerInnate, attackerPowerWeapon, targetGuardInnate, targetGuardArmor, targetGuardAccessory, options = {}, ) => { let attackPower = attackerPowerInnate; if (options.attackerDefending) { attackPower *= 1.5; } if (options.attackerPowerUp) { attackPower *= 2; } let weaponPower = attackerPowerWeapon; if (options.attackerDefending) { weaponPower *= 1.5; } let guardPower = targetGuardInnate; if (options.targetGuardDown) { guardPower /= 2; } const totalAttackPower = attackPower + weaponPower; const totalGuardPower = guardPower + targetGuardArmor + targetGuardAccessory; let averageDamage = totalAttackPower - (totalGuardPower / 2); if (options.targetGuardUp) { averageDamage /= 2; } if (options.targetDefending) { averageDamage /= 2; } let minDamage = averageDamage * 0.75; let maxDamage = averageDamage * 1.25; const absoluteMin = 1; return { normal: { avg: Math.max(absoluteMin, averageDamage), min: Math.max(absoluteMin, minDamage), max: Math.max(absoluteMin, maxDamage), }, critical: { avg: Math.max(absoluteMin, averageDamage * 2), min: Math.max(absoluteMin, minDamage * 2), max: Math.max(absoluteMin, maxDamage * 2), }, }; }; exports.magicalAttack = ( attackerMagicInnate, targetMagicInnate, targetResistanceInnate, targetResistanceArmor, targetResistanceAccessory, spellPower, options = {}, ) => { let attackerPower = attackerMagicInnate; let targetPower = targetMagicInnate; if (options.targetMagicUp) { targetPower += 40; } const targetResistance = 100 - targetResistanceInnate - targetResistanceArmor - targetResistanceAccessory; const spellBonusAttackPower = attackerPower + (options.attackerMagicUp ? 40 : 0); const spellBonus = ((spellBonusAttackPower / 2) + spellPower) * (targetResistance / 100); const averageDamage = attackerPower - targetPower + spellBonus; return { avg: Math.max(1, averageDamage), min: Math.max(1, averageDamage * 0.75), max: Math.max(1, averageDamage * 1.25), }; }; exports.hpCatcherAttack = ( attackerMagicInnate, attackerMaxHP, attackerCurrentHP, targetCurrentHP, options = {}, ) => { let attackerPower = attackerMagicInnate; if (options.attackerMagicUp) { attackerPower += 40; } const adjust = dmg => Math.min(attackerMaxHP - attackerCurrentHP, Math.min(Math.min(dmg, 50), targetCurrentHP)); const minDamage = attackerPower / 2; return { min: adjust(minDamage), max: adjust(minDamage + 15), }; }; exports.mpCatcherAttack = ( attackerMagicInnate, attackerMaxMP, attackerCurrentMP, targetCurrentMP, options = {}, ) => { let attackerPower = attackerMagicInnate; if (options.attackerMagicUp) { attackerPower += 40; } const adjust = dmg => Math.min(attackerMaxMP - attackerCurrentMP, Math.min(Math.min(dmg, 40), targetCurrentMP)); const minDamage = attackerPower / 2; return { min: adjust(minDamage), max: adjust(minDamage + 15), }; }; exports.effectSpellHitRate = ( targetResistanceInnate, targetResistanceArmor, targetResistanceAccessory, ) => { if (targetResistanceInnate === null) { // e.g. "Class 1" enemies return 0; } return Math.max(5, 100 - targetResistanceInnate - targetResistanceArmor - targetResistanceAccessory); }; exports.hitRate = ( attackerSpeedInnate, targetSpeedInnate, options = {}, ) => { let attackerSpeed = attackerSpeedInnate; if (options.attackerSpeedUp) { attackerSpeed += 30; } let targetSpeed = targetSpeedInnate; if (options.targetSpeedUp) { targetSpeed += 30; } const hitRate = 85 + (0.8 * (attackerSpeed - targetSpeed)); return Math.max(10, Math.min(98, hitRate)); }; exports.runRate = ( attackerSpeedInnate, targetSpeedInnate, options = {}, ) => { let attackerSpeed = attackerSpeedInnate; if (options.attackerSpeedUp) { attackerSpeed += 30; } let targetSpeed = targetSpeedInnate; if (options.targetSpeedUp) { targetSpeed += 30; } const runRate = 0.25 + (1.6 * (attackerSpeed - targetSpeed)); return Math.max(10, Math.min(80, runRate)); }; }(typeof(module) !== 'undefined' ? module.exports : window.saga.calc));