enemy stats and calculations modal
This commit is contained in:
parent
744cc4bab6
commit
50112210a7
@ -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,
|
||||
{
|
||||
targetGuardUp: true,
|
||||
}
|
||||
);
|
||||
const withPower = window.saga.calc.physicalAttack(
|
||||
powerInnate,
|
||||
powerWeapon,
|
||||
guardInnate,
|
||||
guardArmor,
|
||||
guardAccessory,
|
||||
{
|
||||
attackerPowerUp: true,
|
||||
}
|
||||
);
|
||||
const withPowerGuard = window.saga.calc.physicalAttack(
|
||||
powerInnate,
|
||||
powerWeapon,
|
||||
guardInnate,
|
||||
guardArmor,
|
||||
guardAccessory,
|
||||
{
|
||||
attackerPowerUp: true,
|
||||
targetGuardUp: true,
|
||||
}
|
||||
);
|
||||
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 withDefendGuard = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
|
||||
targetGuardUp: true,
|
||||
attackerDefending: true,
|
||||
});
|
||||
const withPower = calc.physicalAttack(powerInnate, powerWeapon, guardInnate, guardArmor, guardAccessory, {
|
||||
attackerPowerUp: true,
|
||||
});
|
||||
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));
|
||||
|
@ -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
|
||||
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'))
|
||||
div.col-4: div.card.bg-light
|
||||
div.card-header Character magic
|
||||
div.card-body: table.table.table-horizontal.table-sm
|
||||
tr
|
||||
th
|
||||
th Default
|
||||
th Magic up
|
||||
each spell in charSpells.filter(x => !!x.power || x.name === 'HPCatcher' || x.name === 'MPCatcher')
|
||||
tr
|
||||
th= spell.name
|
||||
td: code(class=("magic-dmg-" + spell.name))
|
||||
td: code(class=("magic-dmg-" + spell.name + '-magic-up'))
|
||||
|
Loading…
Reference in New Issue
Block a user