182 lines
4.0 KiB
JavaScript
182 lines
4.0 KiB
JavaScript
// https://gamefaqs.gamespot.com/snes/563501-the-7th-saga/faqs/54038
|
|
|
|
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(0.1, Math.min(0.8, runRate));
|
|
};
|