enemy stats and calculations modal

This commit is contained in:
tmont 2021-02-22 20:13:48 -08:00
parent 744cc4bab6
commit 50112210a7
2 changed files with 257 additions and 92 deletions

View File

@ -317,15 +317,40 @@
const $enemyInfoModal = $('#enemy-info-modal');
if ($enemyInfoModal.length) {
$table.find('tbody.data td').on('click', (e) => {
const rowData = $(e.target).closest('tr').data();
let rowData;
let shouldApplyRunes = false;
$enemyInfoModal.find('.apply-runes-form input[type="checkbox"]').on('change', (e) => {
shouldApplyRunes = e.target.checked;
if (rowData) {
if (shouldApplyRunes) {
rowData.guard /= 2;
rowData.power /= 2;
rowData.speed /= 2;
rowData.hp /= 2;
rowData.magic /= 2;
} else {
rowData.guard *= 2;
rowData.power *= 2;
rowData.speed *= 2;
rowData.hp *= 2;
rowData.magic *= 2;
}
refreshModal();
}
});
const refreshModal = () => {
rowData.spells = Array.isArray(rowData.spells) ? rowData.spells : rowData.spells.split(',');
const calc = window.saga.calc;
Object.keys(rowData).forEach((key) => {
const cls = key.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase());
$enemyInfoModal.find('.' + cls).text(rowData[key]);
});
if (charStats.power === null && charStats.weapon === null) {
if (charStats.power === null && charStats.weapon === null && charStats.guard === null && !charStats.armor && !charStats.accessory) {
$enemyInfoModal.find('[class^="physical-"]').text('n/a');
} else {
const powerInnate = charStats.power || 0;
@ -333,51 +358,66 @@
const guardInnate = rowData.guard;
const guardArmor = 0;
const guardAccessory = 0;
const def = window.saga.calc.physicalAttack(
powerInnate,
powerWeapon,
guardInnate,
guardArmor,
guardAccessory,
);
const withGuard = window.saga.calc.physicalAttack(
powerInnate,
powerWeapon,
guardInnate,
guardArmor,
guardAccessory,
{
const def = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory);
const withDefend = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
attackerDefending: true,
});
const withGuard = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
targetGuardUp: true,
}
);
const withPower = window.saga.calc.physicalAttack(
powerInnate,
powerWeapon,
guardInnate,
guardArmor,
guardAccessory,
{
});
const withDefendGuard = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
targetGuardUp: true,
attackerDefending: true,
});
const withPower = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
attackerPowerUp: true,
}
);
const withPowerGuard = window.saga.calc.physicalAttack(
powerInnate,
powerWeapon,
guardInnate,
guardArmor,
guardAccessory,
{
});
const withPowerDefend = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
attackerDefending: true,
attackerPowerUp: true,
});
const withPowerGuard = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
attackerPowerUp: true,
targetGuardUp: true,
}
);
});
const withPowerGuardDefend = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
attackerDefending: true,
attackerPowerUp: true,
targetGuardUp: true,
});
const dmgRange = (dmg) => `${Math.floor(dmg.normal.min)}-${Math.ceil(dmg.normal.max)}`;
$enemyInfoModal.find('.physical-dmg').text(dmgRange(def));
$enemyInfoModal.find('.physical-dmg-guard-up').text(dmgRange(withGuard));
$enemyInfoModal.find('.physical-dmg-defend').text(dmgRange(withDefend));
$enemyInfoModal.find('.physical-dmg-defend-guard-up').text(dmgRange(withDefendGuard));
$enemyInfoModal.find('.physical-dmg-power-up').text(dmgRange(withPower));
$enemyInfoModal.find('.physical-dmg-power-up-guard-up').text(dmgRange(withPowerGuard));
$enemyInfoModal.find('.physical-dmg-defend-power-up').text(dmgRange(withPowerDefend));
$enemyInfoModal.find('.physical-dmg-defend-power-up-guard-up').text(dmgRange(withPowerGuardDefend));
// enemy attack
const enemyPower = rowData.power;
const charGuard = charStats.guard || 0;
const charArmor = charStats.armor ? charStats.armor.defense : 0;
const charAccessory = charStats.accessory ? charStats.accessory.defense : 0;
const enemyDef = calc.physicalAttack(enemyPower, 0, charGuard, charArmor, charAccessory,);
const enemyDefDefend = calc.physicalAttack(enemyPower, 0, charGuard, charArmor, charAccessory, {
targetDefending: true,
});
const enemyDefDefendGuardUp = calc.physicalAttack(enemyPower, 0, charGuard, charArmor, charAccessory, {
targetDefending: true,
targetGuardUp: true,
});
const enemyDefGuardUp = calc.physicalAttack(enemyPower, 0, charGuard, charArmor, charAccessory, {
targetGuardUp: true,
});
$enemyInfoModal.find('.physical-enemy-dmg').text(dmgRange(enemyDef));
$enemyInfoModal.find('.physical-enemy-dmg-guard-up').text(dmgRange(enemyDefGuardUp));
$enemyInfoModal.find('.physical-enemy-dmg-defend').text(dmgRange(enemyDefDefend));
$enemyInfoModal.find('.physical-enemy-dmg-defend-guard-up').text(dmgRange(enemyDefDefendGuardUp));
}
const magicDmg = (dmg) => `${Math.floor(dmg.min)}-${Math.ceil(dmg.max)}`;
@ -386,9 +426,9 @@
if (charStats.magic === null) {
$enemyInfoModal.find('[class^="magic-"]').text('n/a');
} else {
const attackerMagic = charStats.magic;
const targetMagic = rowData.magic;
const res = {
const charMagic = charStats.magic;
const enemyMagic = rowData.magic;
const enemyRes = {
ice: rowData.resIce,
fire: rowData.resFire,
thunder: rowData.resThunder,
@ -399,10 +439,10 @@
const resAccessory = 0;
window.saga.spells.filter(x => !!x.power).forEach((spell) => {
const elementalRes = res[spell.element.toLowerCase()];
const elementalRes = enemyRes[spell.element.toLowerCase()];
const def = window.saga.calc.magicalAttack(attackerMagic, targetMagic, elementalRes, resArmor, resAccessory, spell.power);
const magicUp = window.saga.calc.magicalAttack(attackerMagic, targetMagic, elementalRes, resArmor, resAccessory, spell.power, {
const def = calc.magicalAttack(charMagic, enemyMagic, elementalRes, resArmor, resAccessory, spell.power);
const magicUp = calc.magicalAttack(charMagic, enemyMagic, elementalRes, resArmor, resAccessory, spell.power, {
attackerMagicUp: true,
});
@ -412,8 +452,8 @@
});
// hpcatcher
let def = window.saga.calc.hpCatcherAttack(charStats.magic, 999, 0, rowData.hp);
let magicUp = window.saga.calc.hpCatcherAttack(charStats.magic, 999, 0, rowData.hp, {
let def = calc.hpCatcherAttack(charStats.magic, 999, 0, rowData.hp);
let magicUp = calc.hpCatcherAttack(charStats.magic, 999, 0, rowData.hp, {
attackerMagicUp: true,
});
@ -422,23 +462,63 @@
$enemyInfoModal.find(prefix + '-magic-up').text(magicDmg(magicUp));
// mpcatcher
def = window.saga.calc.mpCatcherAttack(charStats.magic, 999, 0, rowData.mp);
magicUp = window.saga.calc.mpCatcherAttack(charStats.magic, 999, 0, rowData.mp, {
def = calc.mpCatcherAttack(charStats.magic, 999, 0, rowData.mp);
magicUp = calc.mpCatcherAttack(charStats.magic, 999, 0, rowData.mp, {
attackerMagicUp: true,
});
prefix = '.magic-dmg-MPCatcher';
$enemyInfoModal.find(prefix).text(magicDmg(def));
$enemyInfoModal.find(prefix + '-magic-up').text(magicDmg(magicUp));
$enemyInfoModal.find('.enemy-spells tbody tr')
.hide()
.filter((i, row) => {
return rowData.spells.includes(row.getAttribute('data-name'));
})
.show();
window.saga.spells.filter(x => !!x.power && rowData.spells.includes(x.name)).forEach((spell) => {
const elementalRes = '';
const resArmor = 0;
const resAccessory = charStats.accessor ? charStats.accessor.resistance[spell.element.toLowerCase()] : 0;
let def = calc.magicalAttack(enemyMagic, charMagic, elementalRes, resArmor, resAccessory, spell.power);
let magicUp = calc.magicalAttack(enemyMagic, charMagic, elementalRes, resArmor, resAccessory, spell.power, {
targetMagicUp: true,
});
$enemyInfoModal.find(`.enemy-spells .magic-enemy-dmg-${spell.name}`).text(magicDmg(def));
$enemyInfoModal.find(`.enemy-spells .magic-enemy-dmg-${spell.name}-magic-up`).text(magicDmg(magicUp));
// hpcatcher
def = calc.hpCatcherAttack(rowData.magic, 999, 0, rowData.hp);
magicUp = calc.hpCatcherAttack(rowData.magic, 999, 0, rowData.hp, {
targetMagicUp: true,
});
let prefix = '.magic-enemy-dmg-HPCatcher';
$enemyInfoModal.find(prefix).text(magicDmg(def));
$enemyInfoModal.find(prefix + '-magic-up').text(magicDmg(magicUp));
// mpcatcher
def = calc.mpCatcherAttack(rowData.magic, 999, 0, rowData.mp);
magicUp = calc.mpCatcherAttack(rowData.magic, 999, 0, rowData.mp, {
attackerMagicUp: true,
});
prefix = '.magic-enemy-dmg-MPCatcher';
$enemyInfoModal.find(prefix).text(magicDmg(def));
$enemyInfoModal.find(prefix + '-magic-up').text(magicDmg(magicUp));
});
}
if (charStats.speed !== null) {
const hitRate = window.saga.calc.hitRate(charStats.speed, rowData.speed);
const hitRateSpeed = window.saga.calc.hitRate(charStats.speed, rowData.speed, {
const hitRate = calc.hitRate(charStats.speed, rowData.speed);
const hitRateSpeed = calc.hitRate(charStats.speed, rowData.speed, {
attackerSpeedUp: true,
});
const runRate = window.saga.calc.runRate(charStats.speed, rowData.speed);
const runRateSpeed = window.saga.calc.runRate(charStats.speed, rowData.speed, {
const runRate = rowData.cls === 1 ? 0 : calc.runRate(charStats.speed, rowData.speed);
const runRateSpeed = rowData.cls === 1 ? 0 : calc.runRate(charStats.speed, rowData.speed, {
attackerSpeedUp: true,
});
@ -446,18 +526,45 @@
$enemyInfoModal.find('.run-rate-speed-up').text(toPer(runRateSpeed));
$enemyInfoModal.find('.hit-rate').text(toPer(hitRate));
$enemyInfoModal.find('.hit-rate-speed-up').text(toPer(hitRateSpeed));
const enemyHitRate = calc.hitRate(rowData.speed, charStats.speed);
const enemyHitRateSpeed = calc.hitRate(rowData.speed, charStats.speed, {
attackerSpeedUp: true,
});
const enemyHitRateCharSpeed = calc.hitRate(rowData.speed, charStats.speed, {
targetSpeedUp: true,
});
const enemyHitRateCharSpeedSpeed = calc.hitRate(rowData.speed, charStats.speed, {
attackerSpeedUp: true,
targetSpeedUp: true,
});
$enemyInfoModal.find('.hit-rate-enemy').text(toPer(enemyHitRate));
$enemyInfoModal.find('.hit-rate-enemy-speed-up').text(toPer(enemyHitRateSpeed));
$enemyInfoModal.find('.hit-rate-enemy-char-speed-up').text(toPer(enemyHitRateCharSpeed));
$enemyInfoModal.find('.hit-rate-enemy-char-speed-up-speed-up').text(toPer(enemyHitRateCharSpeedSpeed));
}
const debuffRate = window.saga.calc.effectSpellHitRate(rowData.resDebuff === 100 ? null : rowData.resDebuff, 0, 0);
const vacuumRate = window.saga.calc.effectSpellHitRate(rowData.resVacuum === 100 ? null : rowData.resVacuum, 0, 0);
const debuffRate = calc.effectSpellHitRate(rowData.resDebuff === 100 ? null : rowData.resDebuff, 0, 0);
const vacuumRate = calc.effectSpellHitRate(rowData.resVacuum === 100 ? null : rowData.resVacuum, 0, 0);
$enemyInfoModal.find('.debuff-rate').text(toPer(debuffRate));
$enemyInfoModal.find('.vacuum-rate').text(toPer(vacuumRate));
};
$table.find('tbody.data td').on('click', (e) => {
rowData = rowData = { ...$(e.target).closest('tr').data() };
if (rowData.name === 'Gorsia') {
$enemyInfoModal.find('.apply-runes-form').show().prop('checked', false);
} else {
$enemyInfoModal.find('.apply-runes-form').hide().find('input').prop('checked', false);
}
refreshModal();
$enemyInfoModal.modal({
show: true,
});
});
} else {
}
}(window));

View File

@ -42,6 +42,8 @@ block tab-content
data-res-thunder=enemy.resistance.thunder
data-res-vacuum=(enemy.resistance.vacuum === null ? 100 : enemy.resistance.vacuum)
data-res-debuff=(enemy.resistance.debuff === null ? 100 : enemy.resistance.debuff)
data-spells=((enemy.spells || []).join(','))
data-cls=enemy.cls
)
td
td: strong= enemy.name
@ -69,17 +71,20 @@ block tab-content
= item + ' (' + (rate * 100).toFixed(2) + '%)'
div#enemy-info-modal.modal(tabindex="-1")
div.modal-dialog.modal-lg
div.modal-dialog.modal-xl
div.modal-content
div.modal-header
h5.modal-title
span.name
div.form-check-inline.ml-4.apply-runes-form(style="font-size: 75%")
input.form-check-input#apply-runes(type="checkbox" autocomplete="off")
label.form-check-label(for="apply-runes") Apply runes
div
| #[span.gold]/#[span.exp]
div.modal-body
div.modal-body(style="font-size: 85%")
div.row
div.col-6
table.table.table-horizontal
div.col-4
table.table.table-horizontal.table-sm
tr
th(colspan="2") Stats
th(colspan="2") Resistances
@ -113,6 +118,76 @@ block tab-content
td.res-debuff
div.card.bg-light
div.card-header Enemy attack
div.card-body
table.table.table-horizontal.table-sm
tr
th Default
th Guard up
th Defend
th Defend+Guard
tr
td: code.physical-enemy-dmg
td: code.physical-enemy-dmg-defend
td: code.physical-enemy-dmg-guard-up
td: code.physical-enemy-dmg-defend-guard-up
h6 Hit rate
table.table.table-horizontal.table-sm.mt-2
thead: tr
th
th Normal
th Speed up
tr
th Default
td: code.hit-rate-enemy
td: code.hit-rate-enemy-speed-up
tr
th Char. speed up
td: code.hit-rate-enemy-char-speed-up
td: code.hit-rate-enemy-char-speed-up-speed-up
div.card.bg-light.mt-2
div.card-header Enemy magic
div.card-body: table.table.table-horizontal.table-sm.enemy-spells
thead: tr
th
th Default
th Magic up
tbody
each spell in charSpells.filter(x => (!!x.power || x.name === 'HPCatcher' || x.name === 'MPCatcher'))
tr(data-name=spell.name class=("enemy-spell-" + spell.name))
th= spell.name
td: code(class=("magic-enemy-dmg-" + spell.name))
td: code(class=("magic-enemy-dmg-" + spell.name + '-magic-up'))
div.col-4
div.card.bg-light
div.card-header Character attack
div.card-body: table.table.table-horizontal.table-sm
tr
th
th Default
th Guard up
tr
th Normal
td: code.physical-dmg
td: code.physical-dmg-guard-up
tr
th Defend
td: code.physical-dmg-defend
td: code.physical-dmg-defend-guard-up
tr
th Power up
td: code.physical-dmg-power-up
td: code.physical-dmg-power-up-guard-up
tr
th Defend+Power
td: code.physical-dmg-defend-power-up
td: code.physical-dmg-defend-power-up-guard-up
div.card.bg-light.mt-2
div.card-header Character rates
div.card-body
table.table.table-sm.table-horizontal
tr
@ -136,32 +211,15 @@ block tab-content
th
td
div.col-6
div.card.bg-light
div.card-body
table.table.table-horizontal.table-sm
div.col-4: div.card.bg-light
div.card-header Character magic
div.card-body: table.table.table-horizontal.table-sm
tr
th
th
th Default
th Guard up
tr
th(rowspan="2").align-middle Physical
th Normal
td: code.physical-dmg
td: code.physical-dmg-guard-up
tr
th Power up
td: code.physical-dmg-power-up
td: code.physical-dmg-power-up-guard-up
tr
th
th
th Default
th Magic up
each spell in charSpells.filter(x => !!x.power || x.name === 'HPCatcher' || x.name === 'MPCatcher')
tr
th= spell.name
th
td: code(class=("magic-dmg-" + spell.name))
td: code(class=("magic-dmg-" + spell.name + '-magic-up'))