diff --git a/app/app.html b/app/app.html index 2b8f8cd3..345ddaf3 100644 --- a/app/app.html +++ b/app/app.html @@ -43,11 +43,11 @@ -
+ -
+
@@ -75,6 +75,18 @@ + + + + + + + + + + + +
@@ -1489,19 +1533,6 @@
- -
Click on the magnifying glass on an item to analyze it.
@@ -1528,10 +1559,16 @@
+ +
+
+
+
+
@@ -1723,25 +1760,6 @@

Options

-
@@ -1780,7 +1798,7 @@

Options

- +

NOTE: The screenshot tool has some issues importing data accurately since the item backgrounds were changed. The automatic importer is recommended. @@ -1839,7 +1857,7 @@

Options

- +

Select the Zarroc optimizer file here. @@ -1857,6 +1875,7 @@

Options

+
@@ -2027,6 +2046,8 @@

Languages

日本語
|
한국어
+ | +
Русский язык


diff --git a/app/assets/link.png b/app/assets/link.png new file mode 100644 index 00000000..ed15a3f9 Binary files /dev/null and b/app/assets/link.png differ diff --git a/app/css/darktheme.css b/app/css/darktheme.css index 5ab9f68e..e4618c8b 100644 --- a/app/css/darktheme.css +++ b/app/css/darktheme.css @@ -271,4 +271,58 @@ input[type=checkbox]:checked:after { } .active, .collapsible:hover { background-color: var(--inactive-color); +} + + +/* Tabs */ + + +.tabsWrapperBody { + text-align: center; +/* font-family: 'Jost', sans-serif;*/ +/* background-color: var(--bg-color);*/ +} + +.tabsWrapper { +/* width: 700px;*/ + margin: auto; +/* background-color: var(--inactive-color);*/ + border-radius: 10px; +/* box-shadow: 0px 5px 15px rgba(0, 0, 0, .1);*/ +} + +.tabsButtonWrapper { + display: grid; + grid-template-columns: 1fr 1fr 1fr; +} + +.tab-button { + letter-spacing: 3px; + border: none; + padding: 10px; + background-color: var(--bg-color); + color: var(--font-color); + font-size: 18px; + cursor: pointer; + transition: 0.5s; +} + +.tab-button:hover { + background-color: var(--inactive-color); +} + +.tab-button.active { + background-color: var(--inactive-color); +} + +.tabsContent { + display: none; + padding: 10px 20px; + margin-top: 0px; + +} + +.tabsContent.active { + display: block; + background-color: var(--inactive-color); } \ No newline at end of file diff --git a/app/css/style.css b/app/css/style.css index 84814a6e..f0238923 100644 --- a/app/css/style.css +++ b/app/css/style.css @@ -69,6 +69,9 @@ .tabLabel { user-select: none; } +.tabLabelLink { + user-select: none; +} .tabset > input:first-child:checked ~ .tab-panels > .tab-panel:first-child, .tabset > input:nth-child(3):checked ~ .tab-panels > .tab-panel:nth-child(2), @@ -99,7 +102,7 @@ input[type=submit] { .tabset > label { position: relative; display: inline-block; - padding: 5px 15px 10px; + padding: 5px 7px 10px; border: 1px solid transparent; border-bottom: 0; cursor: pointer; @@ -109,9 +112,10 @@ input[type=submit] { .tabset > label::after { content: ""; position: absolute; - left: 15px; + left: 7px; bottom: 6px; - width: 22px; + width: -webkit-fill-available; + margin-right: 14px; height: 3px; background: #8d8d8d; } @@ -128,13 +132,12 @@ input[type=submit] { .tabset > input:checked + label { border-color: #ccc; - border-bottom: 1px solid #fff; - margin-bottom: -1px; } .tab-panel { padding: 4px 0; border-top: 1px solid #ccc; + white-space: normal; } .optimizer-panel { @@ -161,6 +164,9 @@ input[type=submit] { margin-left: 1px; margin-right: 10px; } +.controlsPanel { + width: 149px; +} .importerButton { width: 200px; @@ -172,6 +178,12 @@ input[type=submit] { .importer-section { padding-top: 10px; + white-space: nowrap; +} + +.importerWrapper { + display: flex; + flex-direction: column; } .optimization-results-panel { @@ -184,9 +196,21 @@ input[type=submit] { #myGrid { height: 100%; flex-grow: 2; - min-width: 1075px; + min-width: 1150px; +} + +.optionsShortSelector > .ms-choice { + height: 23px; + font-size: 13px; } +.gearActionButtonSmaller { + width: 100%; + cursor: pointer; + margin-right: 5px; + height: 19px; + margin-bottom: 3px; +} .optimizer-equipped-section { display: flex; flex-direction: row; @@ -220,7 +244,7 @@ input { } .constraints-panel-col { - padding: 5px 8px 5px 8px; + padding: 5px 5px 5px 5px; width: 200px; flex-grow: 1; line-height: 14px; @@ -676,6 +700,10 @@ input[type=number]::-webkit-outer-spin-button { height: 29px; vertical-align: middle; } +.shrinkSets { + height: 26px; + vertical-align: middle; +} .optimizerStarIcon { height: 18px; vertical-align: middle; @@ -703,12 +731,43 @@ input[type=number]::-webkit-outer-spin-button { margin-left: 40px; margin-right: 40px; } +.editGearFormVerticalShort { + border-left: 1px solid #e8e8e8; + height: 20px; + margin-top: 10px; + margin-bottom: 10px; + margin-left: 40px; + margin-right: 40px; +} +.editGearFormVerticalMed { + border-left: 1px solid #e8e8e8; + height: 300px; + margin-top: 10px; + margin-bottom: 10px; + margin-left: 40px; + margin-right: 40px; +} .editGearStatLabel { width: 140px; text-align: left; margin-top: auto; margin-bottom: auto; } +.editSkillLabel { + width: 200px; + text-align: left; + margin-top: auto; + margin-bottom: auto; +} + +.editSkillSelect { + height: 100%; + text-align: left; + padding-left: 4px !important; + width: 80px !important; + margin-top: auto; + margin-bottom: auto; +} .editEeStatLabel { width: 200px; @@ -837,7 +896,7 @@ input[type=number]::-webkit-outer-spin-button { min-width: 220px; } .constraints-right-panel { - width: 260px; + width: 210px; flex-shrink: 0; flex-grow: 0; display: flex; @@ -906,9 +965,10 @@ input[type=number]::-webkit-outer-spin-button { } .optimizer-checkbox { cursor: pointer; + margin-bottom: 1px; } .gearActionButton { - width: 120px; + width: 102px; cursor: pointer; margin-right: 5px; } @@ -1697,6 +1757,12 @@ input:checked + .darkSlider:before { #settingsTab { padding-left: 10px; } +#heroLibraryTab { + padding-left: 10px; +} +#gwMetaTab { + padding-left: 10px; +} .newFeatures { text-align: left; line-height: 28px; @@ -1717,14 +1783,16 @@ input:checked + .darkSlider:before { margin-left: 50px; } .enhanceChart { - width: 340px; - height: 340px; + width: 270px; + height: 290px; + margin-left: 30px; + padding-top: 10px; } .enhanceContainer { display: flex; flex-direction: row; - height: 300px; + height: 270px; } .bars { @@ -1734,13 +1802,24 @@ input:checked + .darkSlider:before { .radarChart { margin-left: 50px; - width: 420px; - height: 320px; + width: 400px; + height: 250px; +} + +.gsChart { + width: 820px; + height: 300px; } .enhanceSecondRow { display: flex; flex-direction: row; + height: 260px; +} +.enhanceThirdRow { + display: flex; + flex-direction: row; + height: 200px; } .stats { min-width: 150px; @@ -1880,4 +1959,64 @@ input:checked + .darkSlider:before { width: 113px; font-size: 12.5px; line-height: 17px; +} + +@import url('https://fonts.googleapis.com/css2?family=Jost:wght@100;300;400;700&display=swap'); + + +/* Tabs */ + + +.tabsWrapperBody { + text-align: center; +/* font-family: 'Jost', sans-serif;*/ +/* background-color: var(--bg-color);*/ +} + +.tabsWrapper { +/* width: 700px;*/ + margin: auto; +/* background-color: var(--inactive-color);*/ + border-radius: 10px; +/* box-shadow: 0px 5px 15px rgba(0, 0, 0, .1);*/ +} + +.tabsButtonWrapper { + display: grid; + grid-template-columns: 1fr 1fr 1fr; +} + +.tab-button { + letter-spacing: 3px; + border: none; + padding: 10px; + background-color: var(--inactive-color); + color: var(--font-color); + font-size: 18px; + cursor: pointer; + transition: 0.5s; +} + +.tab-button:hover { + background-color: var(--bg-color); +} + +.tab-button.active { + background-color: var(--bg-color); +} + +.tabsContent { + display: none; + padding: 10px 20px; + margin-top: 0px; + +} + +.tabsContent.active { + display: block; +/* background-color: var(--inactive-color);*/ +} + +.skillTypeSelect { + width: 250px !important; } \ No newline at end of file diff --git a/app/js/lib/api.js b/app/js/lib/api.js index 0de995a6..f55659b9 100644 --- a/app/js/lib/api.js +++ b/app/js/lib/api.js @@ -59,6 +59,8 @@ module.exports = { artifactName: bonusStats.artifactName, artifactLevel: bonusStats.artifactLevel, + artifactAttack: bonusStats.artifactAttack, + artifactHealth: bonusStats.artifactHealth, imprintNumber: bonusStats.imprintNumber, eeNumber: bonusStats.eeNumber, @@ -68,6 +70,19 @@ module.exports = { }); }, + getSkillOptions: async (id) => { + return post('/heroes/getSkillOptions', { + id: id + }); + }, + + setSkillOptions: async (skillOptions, heroId) => { + return post('/heroes/setSkillOptions', { + heroId: heroId, + skillOptions: skillOptions + }); + }, + setModStats: async (modStats, heroId) => { return post('/heroes/setModStats', { discardStats: modStats.discardStats, @@ -88,6 +103,17 @@ module.exports = { }); }, + setArtifacts: async (artifactsByName) => { + var fixedModel = JSON.parse(JSON.stringify(artifactsByName)) + for (var value of Object.values(fixedModel)) { + value.attack = value.stats.attack; + value.health = value.stats.health; + } + return post('/heroes/setArtifactStats', { + artifactStatsByName: fixedModel + }); + }, + getBaseStats: async (name) => { return post('/heroes/getBaseStats', { id: name diff --git a/app/js/lib/damageCalc.js b/app/js/lib/damageCalc.js new file mode 100644 index 00000000..cd40154b --- /dev/null +++ b/app/js/lib/damageCalc.js @@ -0,0 +1,197 @@ + + + // final int s1 = ((atk * s1AtkMod * s1Rate + s1FlatMod) * 1.871f + s1FlatMod2) * (s1Pow) * s1Multis; + // final int s2 = ((atk * s2AtkMod * s2Rate + s2FlatMod) * 1.871f + s2FlatMod2) * (s2Pow) * s2Multis; + // final int s3 = ((atk * s3AtkMod * s3Rate + s3FlatMod) * 1.871f + s3FlatMod2) * (s3Pow) * s3Multis; + + // (increase dmg) * [(atk + bonus atk) * (pow * multi) * (cdmg)] + + // {[(ATK !!)(Atkmod)(Rate **)+(FlatMod)] * (1.871)+(Flat2Mod)} × (pow **)(a) + + + // a = multis = (EnhanceMod)(HitTypeMod)(ElementMod)(DamageUpMod)(TargetDebuffMod) + // rate -> scaling + // flatmod -> max hp/def scaling + // flat2mod -> ddj + + + +function findSkill(skill, hero, heroData) { + var skillData = heroData.skills[skill]; + + // console.warn(skillData) + // console.warn(hero) + // console.warn(heroData) + + return skillData.options.find(x => x.name == hero.skillOptions[skill].skillEffect) || skillData.options[0] +} + +// function calculateRate(skill, hero, heroData, skillOptions) { +// return findSkill(skill, skillOptions, heroData).rate; +// } + +// function calculateAtkMod(skill, hero, heroData, skillOptions) { +// var atkMod = 1; + +// if (findSkill(skill, skillOptions, heroData).type == 0) { +// return atkMod; +// } + +// if (skillOptions[skill].greaterAttackBuffEnabled) { +// atkMod += 0.75 +// } else if (skillOptions[skill].attackBuffEnabled) { +// atkMod += 0.5 +// } + +// if (skillOptions[skill].vigorAttackBuffEnabled) { +// atkMod += 0.3 +// } + +// if (skillOptions[skill].decreasedAttackBuffEnabled) { +// atkMod -= 0.5 +// } + +// return atkMod; +// } + +// function calculateSelfHpScaling(skill, hero, heroData, skillOptions) { +// return findSkill(skill, skillOptions, heroData).selfHpScaling || 0; +// } + +// function calculateType(skill, hero, heroData, skillOptions) { +// return findSkill(skill, skillOptions, heroData).type || 0; +// } + +function getHitTypeMulti(skill, hero, heroData) { + if (!hero.skillOptions[skill].skillEffect) { + return 0 + } + if (hero.skillOptions[skill].skillEffect.includes("crit")) { + return 0 + } + if (hero.skillOptions[skill].skillEffect.includes("crushing")) { + return 1.3 // 130% + } + if (hero.skillOptions[skill].skillEffect.includes("normal")) { + return 1 // 130% + } + if (hero.skillOptions[skill].skillEffect.includes("miss")) { + return 0.75; // 75% + } + return 0 +} + +// function calculateMultis(skill, hero, heroData, skillOptions) { +// var multis = 1; + +// multis += findSkill(skill, skillOptions, heroData).type != 0 ? 0 : getHitTypeMulti(skill, hero, heroData, skillOptions) + +// if (skillOptions[skill].elementalAdvantageEnabled && findSkill(skill, skillOptions, heroData).type == 0) { +// multis *= 1.1 +// } + +// if (skillOptions[skill].targetTargetBuffEnabled && findSkill(skill, skillOptions, heroData).type == 0) { +// multis *= 1.15 +// } + +// // Enhance mod + +// // DamageUpMod + +// return multis +// } + +module.exports = { + getMultipliers: (hero, skillOptions) => { + var heroData = HeroData.getHeroExtraInfo(hero.name) + fixSkillOptions(hero, heroData); + + var s1FlatMod = 0; + var s2FlatMod = 0; + var s3FlatMod = 0; + + var s1FlatMod2 = 0; + var s2FlatMod2 = 0; + var s3FlatMod2 = 0; + + // var s1Multis = calculateMultis("S1", hero, heroData, skillOptions) + // var s2Multis = calculateMultis("S2", hero, heroData, skillOptions) + // var s3Multis = calculateMultis("S3", hero, heroData, skillOptions) + + // var s1Pow = heroData.skills.S1.find(x => x.name == skillOptions.S1.skillEffect).pow || 1; + // var s2Pow = heroData.skills.S2.find(x => x.name == skillOptions.S2.skillEffect).pow || 1; + // var s3Pow = heroData.skills.S3.find(x => x.name == skillOptions.S3.skillEffect).pow || 1; + + // private Float[] selfHpScaling = new Float[]{1f, 1f, 1f}; + // private Float[] selfAtkScaling = new Float[]{1f, 1f, 1f}; + // private Float[] selfDefScaling = new Float[]{1f, 1f, 1f}; + // private Float[] selfSpdScaling = new Float[]{1f, 1f, 1f}; + // private Float[] constantValue = new Float[]{1f, 1f, 1f}; + // private Float[] selfAtkConstantValue = new Float[]{1f, 1f, 1f}; + // private Float[] conditionalIncreasedValue = new Float[]{1f, 1f, 1f}; + // private Float[] defDiffPen = new Float[]{1f, 1f, 1f}; + // private Float[] defDiffPenMax = new Float[]{1f, 1f, 1f}; + // private Float[] atkDiffPen = new Float[]{1f, 1f, 1f}; + // private Float[] atkDiffPenMax = new Float[]{1f, 1f, 1f}; + // private Float[] spdDiffPen = new Float[]{1f, 1f, 1f}; + // private Float[] spdDiffPenMax = new Float[]{1f, 1f, 1f}; + // private Float[] penetration = new Float[]{1f, 1f, 1f}; + // private Float[] atkIncrease = new Float[]{1f, 1f, 1f}; + var skillNames = ["S1", "S2", "S3"] + var result = { + selfSpdScaling: skillNames.map(x => findSkill(x, hero, heroData).selfSpdScaling || 0), + selfHpScaling: skillNames.map(x => findSkill(x, hero, heroData).selfHpScaling || 0), + selfAtkScaling: skillNames.map(x => findSkill(x, hero, heroData).selfAtkScaling || 0), + selfDefScaling: skillNames.map(x => findSkill(x, hero, heroData).selfDefScaling || 0), + extraSelfHpScaling: skillNames.map(x => findSkill(x, hero, heroData).extraSelfHpScaling || 0), + extraSelfAtkScaling: skillNames.map(x => findSkill(x, hero, heroData).extraSelfAtkScaling || 0), + extraSelfDefScaling: skillNames.map(x => findSkill(x, hero, heroData).extraSelfDefScaling || 0), + constantValue: skillNames.map(x => findSkill(x, hero, heroData).constantValue || 0), + selfAtkConstantValue: skillNames.map(x => findSkill(x, hero, heroData).selfAtkConstantValue || 0), + increasedValue: skillNames.map(x => findSkill(x, hero, heroData).increasedValue || 0), + defDiffPen: skillNames.map(x => findSkill(x, hero, heroData).defDiffPen || 0), + defDiffPenMax: skillNames.map(x => findSkill(x, hero, heroData).defDiffPenMax || 0), + atkDiffPen: skillNames.map(x => findSkill(x, hero, heroData).atkDiffPen || 0), + atkDiffPenMax: skillNames.map(x => findSkill(x, hero, heroData).atkDiffPenMax || 0), + spdDiffPen: skillNames.map(x => findSkill(x, hero, heroData).spdDiffPen || 0), + spdDiffPenMax: skillNames.map(x => findSkill(x, hero, heroData).spdDiffPenMax || 0), + penetration: skillNames.map(x => findSkill(x, hero, heroData).penetration || 0), + atkIncrease: skillNames.map(x => findSkill(x, hero, heroData).atkIncrease || 0), + cdmgIncrease: skillNames.map(x => findSkill(x, hero, heroData).cdmgIncrease || 0), + note: skillNames.map(x => findSkill(x, hero, heroData).note || ""), + rate: skillNames.map(x => findSkill(x, hero, heroData).rate || 0), + pow: skillNames.map(x => findSkill(x, hero, heroData).pow || 0), + targets: skillNames.map(x => findSkill(x, hero, heroData).targets || 0), + crit: skillNames.map(x => findSkill(x, hero, heroData).name.includes("crit") ? 1 : 0), + support: skillNames.map(x => (findSkill(x, hero, heroData).name.includes("heal") || findSkill(x, hero, heroData).name.includes("barrier")) ? 1 : 0), + hitMulti: skillNames.map(x => getHitTypeMulti(x, hero, heroData) || 0), + } + + console.warn("calc") + console.warn(skillOptions) + console.warn(result) + + return result + }, +} +function fixSkillOptions(hero, heroData) { + if (!hero.skillOptions) { + hero.skillOptions = { + S1: {skillEffect: heroData.skills.S1.options[0].name}, + S2: {skillEffect: heroData.skills.S2.options[0].name}, + S3: {skillEffect: heroData.skills.S3.options[0].name}, + } + return + } + + if (!hero.skillOptions.S1) { + hero.skillOptions.S1 = {skillEffect: heroData.skills.S1.options[0].name} + } + + if (!hero.skillOptions.S2) { + hero.skillOptions.S2 = {skillEffect: heroData.skills.S2.options[0].name} + } + + if (!hero.skillOptions.S3) { + hero.skillOptions.S3 = {skillEffect: heroData.skills.S3.options[0].name} + } +} \ No newline at end of file diff --git a/app/js/lib/dialog.js b/app/js/lib/dialog.js index 9d070634..aefcb982 100644 --- a/app/js/lib/dialog.js +++ b/app/js/lib/dialog.js @@ -231,6 +231,165 @@ module.exports = { $("select[id='editArtifactLevel']").find('option').remove().end().append(html); }, + + changeSkillOptionsDialog: async (heroId) => { + return new Promise(async (resolve, reject) => { + const getAllHeroesResponse = await Api.getAllHeroes(); + const heroes = getAllHeroesResponse.heroes; + + + hero = heroes.find(x => x.id == heroId) + if (!hero) { + return; + } + const heroData = HeroData.getHeroExtraInfo(hero.name) + + // console.warn(hero); + // const heroInfo = heroData[hero.name]; + // const ee = heroInfo.ex_equip[0]; + + const result = await Swal.fire({ + title: '', + width: 600, + html: ` + + +

${i18next.t("Skill options")}

+
+
+ +
+
+
+ + + +
+
+
+ ${generateSkillOptionsHtml("S1", hero, heroData)} +
+
+ ${generateSkillOptionsHtml("S2", hero, heroData)} +
+
+ ${generateSkillOptionsHtml("S3", hero, heroData)} +
+
+
+
+ `, + // Disabled damage + // html: ` + // + + //

${i18next.t("Skill options")}

+ //
+ //
+ + //
+ //
+ //
+ // + // + // + //
+ //
+ //
+ // ${generateSkillOptionsHtml("S1", hero, heroData)} + //
+ //
+ // ${generateSkillOptionsHtml("S2", hero, heroData)} + //
+ //
+ // ${generateSkillOptionsHtml("S3", hero, heroData)} + //
+ //
+ //
+ //
+ // `, + didOpen: async () => { + // const options = { + // filter: true, + // maxHeight: 400, + // // customFilter: Utils.customFilter, + // filterAcceptOnEnter: true + // } + // const statSelectOptions = { + // maxHeight: 500, + // // customFilter: Utils.customFilter, + // } + + // $('#editArtifact').multipleSelect(options) + // $('#editArtifact').change(module.exports.changeArtifact) + const tabs = document.querySelector(".tabsWrapper"); + const tabButton = document.querySelectorAll(".tab-button"); + const contents = document.querySelectorAll(".tabsContent"); + + tabs.onclick = e => { + const id = e.target.dataset.id; + if (id) { + tabButton.forEach(btn => { + btn.classList.remove("active"); + }); + e.target.classList.add("active"); + + contents.forEach(content => { + content.classList.remove("active"); + }); + const element = document.getElementById(id); + element.classList.add("active"); + } + } + }, + focusConfirm: false, + showCancelButton: true, + confirmButtonText: i18next.t("OK"), + cancelButtonText: i18next.t("Cancel"), + preConfirm: async () => { + // const artifactName = $('#editArtifact').val(); + // const artifactLevel = $('#editArtifactLevel').val(); + // const imprintNumber = $('#editImprint').val(); + // const eeNumber = $('#editEe').val() + // const stars = $('#editStars').val() + + var skills = ["S1", "S2", "S3"] + const skillOptions = {} + + for (var skill of skills) { + skillOptions[skill] = { + // attackImprintPercent: parseFloat(document.getElementById(`${skill}EditAttackPercentImprint`).value) || 0, + // attackIncreasePercent: parseFloat(document.getElementById(`${skill}EditAttackPercentIncrease`).value) || 0, + // damageIncreasePercent: parseFloat(document.getElementById(`${skill}EditDamageIncrease`).value) || 0, + // elementalAdvantageEnabled: (document.getElementById(`${skill}EditElementalAdvantageBox`).checked), + // decreasedAttackBuffEnabled: (document.getElementById(`${skill}EditDecreasedAttackBox`).checked), + // attackBuffEnabled: (document.getElementById(`${skill}EditAttackBuffBox`).checked), + // greaterAttackBuffEnabled: (document.getElementById(`${skill}EditGreaterAttackBuffBox`).checked), + // critDamageBuffEnabled: (document.getElementById(`${skill}EditCritDamageBuffBox`).checked), + // vigorAttackBuffEnabled: (document.getElementById(`${skill}EditVigorAttackBuffBox`).checked), + + skillEffect: (document.getElementById(`${skill}SkillEffect`).value), + // applyToAllSkillsEnabled: (document.getElementById(`${skill}EditApplyToAllSkillsBox`).checked), + + // targetDefense: parseInt(document.getElementById(`${skill}EditTargetDefense`).value), + // targetDefenseIncreasePercent: parseFloat(document.getElementById(`${skill}EditTargetDefenseIncrease`).value) || 0, + // targetDamageReductionPercent: parseFloat(document.getElementById(`${skill}EditTargetDamageReduction`).value) || 0, + // targetDamageTransferPercent: parseFloat(document.getElementById(`${skill}EditTargetDamageTransfer`).value) || 0, + // targetDefenseBuffEnabled: (document.getElementById(`${skill}EditTargetDefenseBuffBox`).checked), + // targetVigorDefenseBuffEnabled: (document.getElementById(`${skill}EditTargetVigorBuffBox`).checked), + // targetDefenseBreakBuffEnabled: (document.getElementById(`${skill}EditTargetDefenseBreakBox`).checked), + // targetTargetBuffEnabled: (document.getElementById(`${skill}EditTargetTargetBuffBox`).checked) + } + } + + return skillOptions; + } + }); + + resolve(result.value); + }); + }, + editHeroDialog: async (hero) => { return new Promise(async (resolve, reject) => { const getAllHeroesResponse = await Api.getAllHeroes(); @@ -588,9 +747,13 @@ module.exports = {
-
${i18next.t("Score")}
+
${i18next.t("GS")}

+ +
${i18next.t("BS")}
+
+
${i18next.t("Prio")}

@@ -602,6 +765,20 @@ module.exports = {
${i18next.t("Conv")}

+ + + +
${i18next.t("S1")}
+
+ + +
${i18next.t("S2")}
+
+ + +
${i18next.t("S3")}
+
+
@@ -820,7 +997,7 @@ module.exports = { const assetsBySet = Assets.getAssetsBySet(); const groupSelectMultipleSelectOptions = { - maxHeight: 500, + maxHeight: 600, showClear: true, // hideOptgroupCheckboxes: true, minimumCountSelected: 99, @@ -1472,7 +1649,183 @@ module.exports = { } } +function safeGetSkill(hero, prefix) { + if (!hero.skillOptions) { + return {}; + } + + if (!hero.skillOptions[prefix]) { + return {}; + } + return hero.skillOptions[prefix]; +} + +function generateSkillOptionsHtml(prefix, hero, heroData) { + var skillTypes = !heroData.skills ? [] : heroData.skills[prefix] + var skillTypesHtml = "" + for (var skillType of skillTypes.options) { + var note = skillType.note ? " (" + skillType.note + ")" : ""; + skillTypesHtml += `\n` + } + const html = +` +
+
+
${i18next.t("Select Skill Effect")}
+ +
+
+` + return html +} + +function generateSkillOptionsHtmlOLDWITHDAMAGECALC(prefix, hero, heroData) { + var skillTypes = !heroData.skills ? [] : heroData.skills[prefix] + var skillTypesHtml = "" + for (var skillType of skillTypes.options) { + console.warn("---") + console.warn(hero) + console.warn(safeGetSkill(hero, prefix)) + console.warn(safeGetSkill(hero, prefix).skillEffect) + skillTypesHtml += `\n` + } + const html = +` +
+
+
+
${i18next.t("Select Skill Effect")}
+ +
+
+ +
+ + +
+
+
${i18next.t("Apply options to all skills")}
+ +
+
+
+ +
+ +
+
+ +
+
${i18next.t("Attack % Imprint")}
+ + + +
+ +
+
${i18next.t("Attack % Increase")}
+ + + +
+ +
+
${i18next.t("Damage Increase")}
+ + + +
+ +
+
${i18next.t("Elemental Advantage")}
+ +
+ +
+
${i18next.t("Decreased Attack")}
+ +
+ +
+
${i18next.t("Attack Buff")}
+ +
+ +
+
${i18next.t("Greater Attack Buff")}
+ +
+ +
+
${i18next.t("Crit Damage Buff")}
+ +
+ +
+
${i18next.t("Vigor")}
+ +
+
+ +
+ +
+
+
${i18next.t("Target Defense")}
+ + + +
+ +
+
${i18next.t("Defense Increase")}
+ + + +
+ +
+
${i18next.t("Damage Reduction")}
+ + + +
+ +
+
${i18next.t("Damage Transfer")}
+ + + +
+
+
${i18next.t("Defense Buff")}
+ +
+ +
+
${i18next.t("Vigor")}
+ +
+ +
+
${i18next.t("Defense Break")}
+ +
+ +
+
${i18next.t("Target")}
+ +
+
+
+` + return html +} function getEeHtml(hero, ee) { const statType = ee ? ee.stat.type : "None"; diff --git a/app/js/lib/gearRating.js b/app/js/lib/gearRating.js index 979ddc58..35f236de 100644 --- a/app/js/lib/gearRating.js +++ b/app/js/lib/gearRating.js @@ -1,4 +1,3 @@ - module.exports = { initialize: () => { diff --git a/app/js/lib/grids/heroesGrid.js b/app/js/lib/grids/heroesGrid.js index c6277564..35f4e1bf 100644 --- a/app/js/lib/grids/heroesGrid.js +++ b/app/js/lib/grids/heroesGrid.js @@ -50,6 +50,8 @@ module.exports = { var localeText = AG_GRID_LOCALE_JA; } else if (i18next.language == 'ko') { var localeText = AG_GRID_LOCALE_KO; + } else if (i18next.language == 'ru') { + var localeText = AG_GRID_LOCALE_RU; } else { var localeText = AG_GRID_LOCALE_EN; } diff --git a/app/js/lib/grids/itemsGrid.js b/app/js/lib/grids/itemsGrid.js index 80c69006..d14e099e 100644 --- a/app/js/lib/grids/itemsGrid.js +++ b/app/js/lib/grids/itemsGrid.js @@ -59,6 +59,8 @@ module.exports = { var localeText = AG_GRID_LOCALE_JA; } else if (i18next.language == 'ko') { var localeText = AG_GRID_LOCALE_KO; + } else if (i18next.language == 'ru') { + var localeText = AG_GRID_LOCALE_RU; } else { var localeText = AG_GRID_LOCALE_EN; } diff --git a/app/js/lib/grids/optimizerGrid.js b/app/js/lib/grids/optimizerGrid.js index 3d96a115..8ce72c13 100644 --- a/app/js/lib/grids/optimizerGrid.js +++ b/app/js/lib/grids/optimizerGrid.js @@ -58,6 +58,8 @@ module.exports = { var localeText = AG_GRID_LOCALE_JA; } else if (i18next.language == 'ko') { var localeText = AG_GRID_LOCALE_KO; + } else if (i18next.language == 'ru') { + var localeText = AG_GRID_LOCALE_RU; } else { var localeText = AG_GRID_LOCALE_EN; } @@ -217,7 +219,11 @@ function aggregateCurrentHeroStats(heroStats) { "mcdmgps", "dmgh", "dmgd", + "s1", + "s2", + "s3", "score", + "bs", "priority" ] @@ -263,11 +269,11 @@ function getField(heroStats, stat) { function buildGrid(localeText) { - const DIGITS_2 = 40; - const DIGITS_3 = 40; - const DIGITS_4 = 44; - const DIGITS_5 = 48; - const DIGITS_6 = 55; + const DIGITS_2 = 30; + const DIGITS_3 = 35; + const DIGITS_4 = 42; + const DIGITS_5 = 45; + const DIGITS_6 = 50; const gridOptions = { defaultColDef: { @@ -281,7 +287,7 @@ function buildGrid(localeText) { }, columnDefs: [ - {headerName: i18next.t('sets'), field: 'sets', width: 88, cellRenderer: (params) => GridRenderer.renderSets(params.value)}, + {headerName: i18next.t('sets'), field: 'sets', width: 80, cellRenderer: (params) => GridRenderer.renderSets(params.value, "shrinkSets")}, {headerName: i18next.t('atk'), field: 'atk', width: DIGITS_4}, {headerName: i18next.t('def'), field: 'def', width: DIGITS_4}, {headerName: i18next.t('hp'), field: 'hp', width: DIGITS_5}, @@ -301,10 +307,14 @@ function buildGrid(localeText) { {headerName: i18next.t('mcds'), field: 'mcdmgps', width: DIGITS_4}, {headerName: i18next.t('dmgh'), field: 'dmgh', width: DIGITS_5}, {headerName: i18next.t('dmgd'), field: 'dmgd', width: DIGITS_5}, - {headerName: i18next.t('score'), field: 'score', width: DIGITS_3}, + {headerName: i18next.t('s1'), field: 's1', width: DIGITS_5}, + {headerName: i18next.t('s2'), field: 's2', width: DIGITS_5}, + {headerName: i18next.t('s3'), field: 's3', width: DIGITS_5}, + {headerName: i18next.t('gs'), field: 'score', width: DIGITS_3}, + {headerName: i18next.t('bs'), field: 'bs', width: DIGITS_3}, {headerName: i18next.t('prio'), field: 'priority', width: DIGITS_3}, {headerName: i18next.t('upg'), field: 'upgrades', width: DIGITS_2}, - {headerName: i18next.t('actions'), field: 'property', width: 45, sortable: false, cellRenderer: (params) => GridRenderer.renderStar(params.value)}, + {headerName: i18next.t(''), field: 'property', width: 25, sortable: false, cellRenderer: (params) => GridRenderer.renderStar(params.value)}, ], rowHeight: 27, rowModelType: 'infinite', diff --git a/app/js/lib/heroData.js b/app/js/lib/heroData.js index 0f6bb25a..d0c695b4 100644 --- a/app/js/lib/heroData.js +++ b/app/js/lib/heroData.js @@ -87,10 +87,81 @@ module.exports = { const baseStatsByName = {}; Object.keys(heroesByName) .forEach(x => { + if (!heroesByName[x].skills) { + heroesByName[x].skills = { + "S1": { + "hitTypes": ["normal"], + "targets": 0, + "rate": 0, + "pow": 0, + "options": [] + }, + "S2": { + "hitTypes": ["normal"], + "targets": 0, + "rate": 0, + "pow": 0, + "options": [] + }, + "S3": { + "hitTypes": ["normal"], + "targets": 0, + "rate": 0, + "pow": 0, + "options": [] + } + } + } + + + var s = heroesByName[x].skills; + for (var skill of ["S1", "S2", "S3"]) { + var skillData = s[skill]; + + if (skillData) { + for (var z of skillData.hitTypes) { + if (!skillData.options.find(y => y.name.includes(z))) { + skillData.options.push({ + name: skill + " " + z, + rate: skillData.rate, + note: skillData.note, + pow: skillData.pow, + targets: skillData.targets, + selfHpScaling: skillData.selfHpScaling, + selfAtkScaling: skillData.selfAtkScaling, + selfDefScaling: skillData.selfDefScaling, + selfSpdScaling: skillData.selfSpdScaling, + increasedValue: skillData.increasedValue, + extraSelfHpScaling: skillData.extraSelfHpScaling, + extraSelfDefScaling: skillData.extraSelfDefScaling, + extraSelfAtkScaling: skillData.extraSelfAtkScaling, + cdmgIncrease: skillData.cdmgIncrease, + penetration: skillData.penetration, + }); + } + } + } + + if (!skillData) { + s[skill] = {} + } + + if (!s[skill].options || s[skill].options.length == 0) { + s[skill].options = []; + s[skill].options.push({ + name: skill + " n/a", + targets: 0, + rate: 0, + pow: 0, + }) + } + } + const baseStats = module.exports.getBaseStatsByName(x); baseStatsByName[x] = baseStats; }); + await Api.setArtifacts(artifactsByName); await Api.setBaseStats(baseStatsByName); }, @@ -150,7 +221,12 @@ module.exports = { const status = heroesByName[name].calculatedStatus; return { lv50FiveStarFullyAwakened: baseToStatObj(status.lv50FiveStarFullyAwakened), - lv60SixStarFullyAwakened: baseToStatObj(status.lv60SixStarFullyAwakened) + lv60SixStarFullyAwakened: baseToStatObj(status.lv60SixStarFullyAwakened), + skills: { + S1: heroesByName[name].skills.S1.options, + S2: heroesByName[name].skills.S2.options, + S3: heroesByName[name].skills.S3.options + } } }, diff --git a/app/js/lib/i18n/i18n.js b/app/js/lib/i18n/i18n.js index 18e68d69..fa2a4d9b 100644 --- a/app/js/lib/i18n/i18n.js +++ b/app/js/lib/i18n/i18n.js @@ -7,10 +7,11 @@ module.exports = { require(Files.path(Files.getDataPath() + '/locales/zh-TW/gridlocale.js')) require(Files.path(Files.getDataPath() + '/locales/fr/gridlocale.js')) require(Files.path(Files.getDataPath() + '/locales/ja/gridlocale.js')) + require(Files.path(Files.getDataPath() + '/locales/ru/gridlocale.js')) window.i18next.use(window.i18nextHttpBackend).use(window.i18nextBrowserLanguageDetector).init({ debug: false, - preload: ['en', 'zh', 'zh-TW', 'fr', 'ko', 'ja', 'dev'], + preload: ['en', 'zh', 'zh-TW', 'fr', 'ko', 'ja', 'ru', 'dev'], detection: { // order and from where user language should be detected order: ['querystring', 'cookie', 'sessionStorage', 'navigator', 'htmlTag', 'path', 'subdomain'], diff --git a/app/js/lib/importer.js b/app/js/lib/importer.js index 0ba9aa7d..e8407ec8 100644 --- a/app/js/lib/importer.js +++ b/app/js/lib/importer.js @@ -391,11 +391,18 @@ module.exports = { continue; } + console.log(newHero) + newHero.rarity = newHero.data.rarity; newHero.attribute = newHero.data.attribute; newHero.role = newHero.data.role; newHero.path = heroName; newHero.stars = hero.stars; + newHero.skills = { + S1: newHero.data.skills.S1.options, + S2: newHero.data.skills.S2.options, + S3: newHero.data.skills.S3.options + }; hero.data = newHero; filteredHeroes.push(hero); diff --git a/app/js/lib/inputHandler.js b/app/js/lib/inputHandler.js index a40f4411..7b3d9a69 100644 --- a/app/js/lib/inputHandler.js +++ b/app/js/lib/inputHandler.js @@ -97,6 +97,8 @@ global.fs = require('fs'); global.Notifier = require('./notifier'); global.Saves = require('./saves'); global.Scanner = require('./scanner'); +global.DamageCalc = require('./damageCalc'); +global.ItemSimulator = require('./itemSimulator'); const Jimp = require('jimp'); document.addEventListener("DOMContentLoaded", async () => { diff --git a/app/js/lib/itemSimulator.js b/app/js/lib/itemSimulator.js new file mode 100644 index 00000000..d9fe89ca --- /dev/null +++ b/app/js/lib/itemSimulator.js @@ -0,0 +1,668 @@ +const n = 25000; + +function possibleSubstatsByGear(item, substatTypes) { + var gear = item.gear; + return { + "Weapon": [ + "AttackPercent", + "Health", + "HealthPercent", + "Speed", + "CriticalHitChancePercent", + "CriticalHitDamagePercent", + "EffectivenessPercent", + "EffectResistancePercent" + ], + "Helmet": [ + "Attack", + "AttackPercent", + "Defense", + "DefensePercent", + "HealthPercent", + "Speed", + "CriticalHitChancePercent", + "CriticalHitDamagePercent", + "EffectivenessPercent", + "EffectResistancePercent" + ], + "Armor": [ + "DefensePercent", + "Health", + "HealthPercent", + "Speed", + "CriticalHitChancePercent", + "CriticalHitDamagePercent", + "EffectivenessPercent", + "EffectResistancePercent" + ], + "Necklace": [ + "Attack", + "AttackPercent", + "Defense", + "DefensePercent", + "Health", + "HealthPercent", + "Speed", + "CriticalHitChancePercent", + "CriticalHitDamagePercent", + "EffectivenessPercent", + "EffectResistancePercent" + ].filter(x => x != item.main.type && !substatTypes.includes(x)), + "Ring": [ + "Attack", + "AttackPercent", + "Defense", + "DefensePercent", + "Health", + "HealthPercent", + "Speed", + "CriticalHitChancePercent", + "CriticalHitDamagePercent", + "EffectivenessPercent", + "EffectResistancePercent" + ].filter(x => x != item.main.type && !substatTypes.includes(x)), + "Boots": [ + "Attack", + "AttackPercent", + "Defense", + "DefensePercent", + "Health", + "HealthPercent", + "Speed", + "CriticalHitChancePercent", + "CriticalHitDamagePercent", + "EffectivenessPercent", + "EffectResistancePercent" + ].filter(x => x != item.main.type && !substatTypes.includes(x)), + }[gear] +} +module.exports = { + + initialize: () => { + + }, + + getSimulationN: () => { + return n; + }, + + simulate: (item) => { + + var reforgeable = Reforge.isReforgeable(item); + + var tier = 85; + if (item.level == 88) { + tier = 88 + } + if (item.level < 72) { + tier = 71 + } + + var grade = "Rare"; + if (item.rank == "Epic") { + grade = "Epic" + } + if (item.rank == "Heroic") { + grade = "Heroic" + } + + + var baseSubstats = item.substats; + var substatTypeArr = [] + var gsArr = [] + var moddedGsArr = [] + for (var i = 0; i < n; i++) { + var substats = [] + for (var j = 0; j < 4; j++) { + if (baseSubstats[j]) { + substats[j] = { + type: baseSubstats[j].type, + rolls: baseSubstats[j].rolls, + value: baseSubstats[j].value + } + substatTypeArr[j] = baseSubstats[j].type + } else { + var possibleSubstats = possibleSubstatsByGear(item, substatTypeArr); + var randomSubstat = possibleSubstats[Math.floor(Math.random() * possibleSubstats.length)]; + substats[j] = { + type: randomSubstat, + rolls: 0, + value: 0 + } + substatTypeArr[j] = randomSubstat + } + } + + for (var j = Math.floor(item.enhance/3)*3; j < 15; j += 3) { + var substat = substats[Math.floor(Math.random() * 4)]; + if (grade == "Heroic") { + if (j == 12) { + substat = substats[3] + } + } + if (grade == "Rare") { + if (j == 12) { + substat = substats[3] + } + if (j == 9) { + substat = substats[2] + } + } + if (grade == "Good") { + if (j == 12) { + substat = substats[3] + } + if (j == 9) { + substat = substats[2] + } + if (j == 6) { + substat = substats[1] + } + } + if (grade == "Normal") { + if (j == 12) { + substat = substats[3] + } + if (j == 9) { + substat = substats[2] + } + if (j == 6) { + substat = substats[1] + } + if (j == 3) { + substat = substats[0] + } + } + // console.log(Math.floor(Math.random() * 4)) + // console.log(substats) + // console.log(substats[Math.floor(Math.random() * 4)]) + // console.log(substat) + // console.log("--------------") + var group = substatGroupByType[substat.type] + + if (group == "Flat") { + var range = flatRollsByTier[tier][substat.type][grade] + var value = Math.floor(Math.random() * (range[1] - range[0] + 1)) + range[0] + + substat.value += value; + substat.rolls += 1 + } else { + var probs = percentProbabilitiesByTier[tier][group][grade]; + var value = valueFromProbabilities(probs); + + substat.value += value; + substat.rolls += 1 + } + } + + var gs = 0; + for (var substat of substats) { + if (reforgeable) { + var plain = false + if (plainStats.includes(substat.type)) { + plain = true; + } + + if (plain) { + const added = plainStatRollsToValue[substat.rolls]; + substat.value = substat.value + added; + } + if (substat.type == "CriticalHitChancePercent") { + const added = substat.rolls; + substat.value = substat.value + added; + } + if (substat.type == "CriticalHitDamagePercent") { + const added = critDamageRollsToValue[substat.rolls]; + substat.value = substat.value + added; + } + if (substat.type == "Attack") { + const added = 11 * substat.rolls; + substat.value = substat.value + added; + } + if (substat.type == "Defense") { + const added = 9 * substat.rolls; + substat.value = substat.value + added; + } + if (substat.type == "Health") { + const added = 56 * substat.rolls; + substat.value = substat.value + added; + } + if (substat.type == "Speed") { + const added = speedRollsToValue[substat.rolls]; + substat.value = substat.value + added; + } + } + + substat.gs = substatWeights[substat.type] * substat.value + substat.potentialGs = potentialGsByRolls[substat.rolls - 1] + + gs += substat.gs + } + + var maxGsDiff = 0; + var maxGsDiffIndex = 0; + for (var substatIndex = 0; substatIndex < substats.length; substatIndex++) { + var substat = substats[substatIndex] + var diff = substats[substatIndex].potentialGs - substatWeights[substat.type] * substat.value + if (diff > maxGsDiff) { + maxGsDiff = diff; + maxGsDiffIndex = substatIndex + } + } + + var moddedGs = 0; + if (maxGsDiff > 0) { + for (var substatIndex = 0; substatIndex < substats.length; substatIndex++) { + var substat = substats[substatIndex] + if (substatIndex == maxGsDiffIndex) { + moddedGs += substat.potentialGs + } else { + moddedGs += substat.gs + } + } + } else { + moddedGs = gs + } + + // console.log("----------------") + // console.log(substats) + // console.log(gs) + // console.log(moddedGs) + + gsArr.push(Math.round(gs)) + moddedGsArr.push(Math.round(moddedGs)) + } + + // console.log(gsArr) + // console.log(reforgeable) + + return { + gsArr: gsArr, + moddedGsArr: moddedGsArr + } + + }, +} + +const potentialGsByRolls = { + 0: 9, + 1: 14, + 2: 18, + 3: 22, + 4: 25, + 5: 27 +} + +const substatGroupByType = { + "Attack": "Flat", + "AttackPercent": "Default", + "Defense": "Flat", + "DefensePercent": "Default", + "Health": "Flat", + "HealthPercent": "Default", + "Speed": "Speed", + "CriticalHitChancePercent": "CriticalHitChancePercent", + "CriticalHitDamagePercent": "CriticalHitDamagePercent", + "EffectivenessPercent": "Default", + "EffectResistancePercent": "Default" +} +const plainStats = [ + "AttackPercent", + "DefensePercent", + "HealthPercent", + "EffectivenessPercent", + "EffectResistancePercent", +] +function valueFromProbabilities(probs) { + var sum = 0; + for (var x of Object.values(probs)) { + sum += x + } + var rand = Math.random() * sum; + var value = Object.keys(probs)[0] + var cumulative = 0 + + for (var x of Object.entries(probs)) { + if (rand >= cumulative) { + cumulative += x[1] + value = x[0] + } else { + break + } + } + return parseInt(value) +} + +const substatWeights = { + "AttackPercent": 1, + "DefensePercent": 1, + "HealthPercent": 1, + "EffectivenessPercent": 1, + "EffectResistancePercent": 1, + "Attack": (3.46 / 39), + "Health": (3.09 / 174), + "Defense": (4.99 / 31), + "CriticalHitDamagePercent": (8/7), + "CriticalHitChancePercent": (8/5), + "Speed": (8/4), +} + +const plainStatRollsToValue = { + 1: 1, + 2: 3, + 3: 4, + 4: 5, + 5: 7, + 6: 8, +} + +const critDamageRollsToValue = { + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 6, + 6: 7, +} + +const speedRollsToValue = { + 1: 0, + 2: 1, + 3: 2, + 4: 3, + 5: 4, + 6: 4, +} + +const flatRollsByTier = { + "88": { + Attack: { + Epic: [37, 53], + Heroic: [36, 50], + Rare: [34, 48] + }, + Defense: { + Epic: [32, 40], + Heroic: [30, 38], + Rare: [28, 36] + }, + Health: { + Epic: [178, 229], + Heroic: [169, 218], + Rare: [160, 206] + } + }, + "85": { + Attack: { + Epic: [33, 46], + Heroic: [31, 44], + Rare: [29, 42] + }, + Defense: { + Epic: [28, 35], + Heroic: [26, 33], + Rare: [25, 31] + }, + Health: { + Epic: [157, 202], + Heroic: [149, 192], + Rare: [141, 182] + } + }, + "71": { + Attack: { + Epic: [28, 40], + Heroic: [27, 38], + Rare: [25, 36] + }, + Defense: { + Epic: [24, 30], + Heroic: [22, 28], + Rare: [21, 27] + }, + Health: { + Epic: [136, 175], + Heroic: [129, 166], + Rare: [122, 157] + } + } +} + +const percentProbabilitiesByTier = { + "88": { + Default: { + Epic: { + 5: 0.2, + 6: 0.2, + 7: 0.2, + 8: 0.2, + 9: 0.2, + }, + Heroic: { + 5: 0.2, + 6: 0.2, + 7: 0.2, + 8: 0.2, + 9: 0.2, + }, + Rare: { + 5: 0.4, + 6: 0.2, + 7: 0.2, + 8: 0.2, + } + }, + Speed: { + Epic: { + 3: 0.49751, + 4: 0.49751, + 5: 0.00498, + }, + Heroic: { + 2: 0.08333, + 3: 0.52083, + 4: 0.39583, + }, + Rare: { + 3: 0.17033, + 4: 0.54945, + 5: 0.28022, + } + }, + CriticalHitDamagePercent: { + Epic: { + 4: 0.2, + 5: 0.2, + 6: 0.2, + 7: 0.2, + 8: 0.2, + }, + Heroic: { + 4: 0.2, + 5: 0.2, + 6: 0.2, + 7: 0.2, + 8: 0.2, + }, + Rare: { + 4: 0.2, + 5: 0.4, + 6: 0.2, + 7: 0.2, + } + }, + CriticalHitChancePercent: { + Epic: { + 3: 0.25, + 4: 0.25, + 5: 0.25, + 6: 0.25, + }, + Heroic: { + 3: 0.25, + 4: 0.25, + 5: 0.25, + 6: 0.25, + }, + Rare: { + 3: 0.25, + 4: 0.25, + 5: 0.5, + } + } + }, + "85": { + Default: { + Epic: { + 4: 0.2, + 5: 0.2, + 6: 0.2, + 7: 0.2, + 8: 0.2, + }, + Heroic: { + 4: 0.2, + 5: 0.2, + 6: 0.2, + 7: 0.2, + 8: 0.2, + }, + Rare: { + 4: 0.2, + 5: 0.4, + 6: 0.2, + 7: 0.2, + } + }, + Speed: { + Epic: { + 2: 0.33223, + 3: 0.33223, + 4: 0.33223, + 5: 0.00332, + }, + Heroic: { + 1: 0.03833, + 2: 0.34843, + 3: 0.34843, + 4: 0.26481, + }, + Rare: { + 1: 0.07721, + 2: 0.36765, + 3: 0.36765, + 4: 0.18750, + } + }, + CriticalHitDamagePercent: { + Epic: { + 4: 0.25, + 5: 0.25, + 6: 0.25, + 7: 0.25, + }, + Heroic: { + 4: 0.25, + 5: 0.25, + 6: 0.25, + 7: 0.25, + }, + Rare: { + 4: 0.25, + 5: 0.50, + 6: 0.25, + } + }, + CriticalHitChancePercent: { + Epic: { + 3: 0.33333, + 4: 0.33333, + 5: 0.33333, + }, + Heroic: { + 3: 0.33333, + 4: 0.33333, + 5: 0.33333, + }, + Rare: { + 3: 0.33333, + 4: 0.33333, + 5: 0.33333, + } + } + }, + "71": { + Default: { + Epic: { + 4: 0.25, + 5: 0.25, + 6: 0.25, + 7: 0.25, + }, + Heroic: { + 4: 0.25, + 5: 0.25, + 6: 0.25, + 7: 0.25, + }, + Rare: { + 4: 0.25, + 5: 0.50, + 6: 0.25, + } + }, + Speed: { + Epic: { + 2: 0.49751, + 3: 0.49751, + 4: 0.00498, + }, + Heroic: { + 1: 0.05729, + 2: 0.52083, + 3: 0.42188, + }, + Rare: { + 1: 0.11538, + 2: 0.54945, + 3: 0.33516, + } + }, + CriticalHitDamagePercent: { + Epic: { + 3: 0.25, + 4: 0.25, + 5: 0.25, + 6: 0.25, + }, + Heroic: { + 3: 0.25, + 4: 0.25, + 5: 0.25, + 6: 0.25, + }, + Rare: { + 3: 0.25, + 4: 0.25, + 5: 0.50, + } + }, + CriticalHitChancePercent: { + Epic: { + 2: 0.33333, + 3: 0.33333, + 4: 0.33333, + }, + Heroic: { + 2: 0.33333, + 3: 0.33333, + 4: 0.33333, + }, + Rare: { + 2: 0.33333, + 3: 0.33333, + 4: 0.33333, + } + } + } +} \ No newline at end of file diff --git a/app/js/lib/locator.js b/app/js/lib/locator.js index e878128b..5af0b41b 100644 --- a/app/js/lib/locator.js +++ b/app/js/lib/locator.js @@ -102,10 +102,15 @@ function locateSingleItem(itemId, items) { return difference; }) } else { - // floating point sort items.sort((x, y) => { + if (!y.op) { + return 1; + } + if (!x.op) { + return -1; + } var yOpValues = y.op.slice(1).filter(x => opStatToSubstat[x[0]] == substat.type).map(x => parseFloat(x[1])) var ySum = yOpValues.reduce((a, b) => a + b, 0) diff --git a/app/js/lib/scanner.js b/app/js/lib/scanner.js index f6e43a53..27bcc04b 100644 --- a/app/js/lib/scanner.js +++ b/app/js/lib/scanner.js @@ -313,6 +313,20 @@ async function finishedReading(data, scanType) { if (rawItems.length == 0) { // This case is impossible? document.querySelectorAll('[id=loadFromGameExportOutputText]').forEach(x => x.value = i18next.t("Item reading failed, please try again.")); Notifier.error("Failed reading items, please try again. No items were found."); + Dialog.htmlError( +` +No items were found during the scan. This can happen due to network compatibility issues. Potential fixes:
+ +`); return } diff --git a/app/js/lib/selectors.js b/app/js/lib/selectors.js index 687906b0..08d988ed 100644 --- a/app/js/lib/selectors.js +++ b/app/js/lib/selectors.js @@ -22,28 +22,27 @@ module.exports = { const assetsBySet = Assets.getAssetsBySet(); const groupSelectMultipleSelectOptions = { - maxHeight: 500, + maxHeight: 600, showClear: true, // hideOptgroupCheckboxes: true, minimumCountSelected: 99, displayTitle: true, + displayValues: true, selectAll: false, - // textTemplate: function (el) { - // const val = el.html(); - // const enValue = el.val(); - // const fixedHtml = el.html().replace(enValue, i18next.t(enValue)) - // const assetKey = enValue + "Set"; - - // if (Object.keys(assetsBySet).includes(assetKey)) { - // const asset = assetsBySet[assetKey]; - // return `
${fixedHtml}
` - // } - - // return fixedHtml - // }, - // styler: function (row) { - // return ''; - // } + textTemplate: function (el) { + const val = el.html(); + const assetKey = val + "Set"; + + if (Object.keys(assetsBySet).includes(assetKey)) { + const asset = assetsBySet[assetKey]; + return `
${el.html()}
` + } + + return el.html() + }, + styler: function (row) { + return ''; + } }; const enhanceOptions = { maxHeight: 500, @@ -99,6 +98,10 @@ module.exports = { $('#optionsExcludeGearFrom').multipleSelect(Object.assign({}, excludeEquippedSelectOptions, {placeholder: i18next.t("Exclude equipped"), selectAll: true},{formatSelectAll () {return i18next.t('[Select all]')}})); $('#optionsEnhanceLimit').multipleSelect(Object.assign({}, enhanceOptions, {placeholder: i18next.t("Minimum enhance"), selectAll: false})); + $('#optionsS1').multipleSelect(Object.assign({}, excludeEquippedSelectOptions, {placeholder: i18next.t("Exclude equipped"), selectAll: true},{formatSelectAll () {return i18next.t('[Select all]')}})); + $('#optionsS2').multipleSelect(Object.assign({}, excludeEquippedSelectOptions, {placeholder: i18next.t("Exclude equipped"), selectAll: true},{formatSelectAll () {return i18next.t('[Select all]')}})); + $('#optionsS3').multipleSelect(Object.assign({}, excludeEquippedSelectOptions, {placeholder: i18next.t("Exclude equipped"), selectAll: true},{formatSelectAll () {return i18next.t('[Select all]')}})); + // $('#optionsExcludeGearFrom' + index).multipleSelect('setSelects', ["0", "3", "6", "9", "12", "15"]) console.log("DONE INITIALIZING SELECTORS"); @@ -203,13 +206,15 @@ module.exports = { setGearMainAndSetsFromRequest: (request, index) => { console.warn("SETS", request, index); + console.warn("SETS", request.inputExcludeSet); + console.warn("SETS", $('#inputExcludeSet' + index)); $('#inputSet1' + index).multipleSelect('setSelects', request.inputSetsOne.map(x => x.replace("Set", "")) || []) $('#inputSet2' + index).multipleSelect('setSelects', request.inputSetsTwo.map(x => x.replace("Set", "")) || []) $('#inputSet3' + index).multipleSelect('setSelects', request.inputSetsThree.map(x => x.replace("Set", "")) || []) + $('#inputExcludeSet' + index).multipleSelect('setSelects', request.inputExcludeSet.map(x => x.replace("Set", "")) || []) $('#inputNecklaceStat' + index).multipleSelect('setSelects', request.inputNecklaceStat || []) $('#inputRingStat' + index).multipleSelect('setSelects', request.inputRingStat || []) $('#inputBootsStat' + index).multipleSelect('setSelects', request.inputBootsStat || []) - $('#inputExcludeSet' + index).multipleSelect('setSelects', request.inputExcludeSet || []) } } diff --git a/app/js/lib/tabs/enhancingTab.js b/app/js/lib/tabs/enhancingTab.js index 128658c8..97d0c63e 100644 --- a/app/js/lib/tabs/enhancingTab.js +++ b/app/js/lib/tabs/enhancingTab.js @@ -3,6 +3,7 @@ var echarts = require('echarts'); barsCharts = [undefined, undefined, undefined, undefined]; guageChart = undefined; radarChart = undefined; +gsChart = undefined; const maxes = { "Attack": 346 * 1.5, @@ -251,6 +252,9 @@ module.exports = { var radarChartDom = document.getElementById('chart2'); radarChart = echarts.init(radarChartDom, DarkMode.isDark() ? 'dark' : undefined); + var gsChartDom = document.getElementById('gsChart'); + gsChart = echarts.init(gsChartDom, DarkMode.isDark() ? 'dark' : undefined); + initializeBars() // const getAllItemsResponse = await Api.getAllItems(); // const items = getAllItemsResponse.items; @@ -283,6 +287,7 @@ module.exports = { }, redrawEnhanceGuide: async (item) => { + var simulationResults = ItemSimulator.simulate(item); setTheme(); Reforge.calculateMaxes(item); console.log("redraw", item); @@ -473,6 +478,97 @@ module.exports = { option && radarChart.setOption(option); + // GS + + if (item.enhance < 16) { + var gs = simulationResults.gsArr; + var moddedGs = simulationResults.moddedGsArr + + var min = Math.min(Math.min(...gs), Math.min(...moddedGs)) - 1 + var max = Math.max(Math.max(...gs), Math.max(...moddedGs)) + 1 + + function generateLineArr(gs, min, max) { + // var minGs = Math.min(...gs) + // var maxGs = Math.max(...gs) + var xArr = [] + var yArr = [] + var count = 0; + for (var i = min; i <= max; i++) { + xArr[count] = i; + yArr[count] = 0; + count++; + } + for (var result of gs) { + var index = result - min; + yArr[index]++ + } + + var n = ItemSimulator.getSimulationN(); + for (var i = 0; i < yArr.length; i++) { + yArr[i] = yArr[i] / n * 100 + } + + if (item.enhance >= 15) { + for (var i = 0; i <= yArr.length; i++) { + if (yArr[i] == 0) { + yArr[i] = undefined; + } + } + } + return { + xArr: xArr, + yArr: yArr, + } + } + + var gsSeries = generateLineArr(gs, min, max) + var moddedGsSeries = generateLineArr(moddedGs, min, max) + + var option = { + xAxis: { + type: 'category', + data: gsSeries.xArr + }, + yAxis: { + type: 'value' + }, + legend: { + data: ['GS probabilities', 'GS probabilities with max substat mod'] + }, + series: [ + { + name: 'GS probabilities', + data: gsSeries.yArr, + type: (item.enhance >= 15 ? 'scatter' : 'line'), + areaStyle: {}, + smooth: true + }, + { + name: 'GS probabilities with max substat mod', + data: moddedGsSeries.yArr, + type: (item.enhance >= 15 ? 'scatter' : 'line'), + areaStyle: {}, + smooth: true, + lineStyle: {color: '#71de7c'}, + itemStyle: {color: '#71de7c'} + }, + ], + xAxis: { + type: 'category', + name: 'Gear score', + data: gsSeries.xArr + }, + yAxis: [{ + type: 'value', + name: '% chance', + tickAmount: 16 + // ... + }] + }; + // option.yaxis.labels.formatter = val => val.toFixed(2) + option && gsChart.setOption(option); + + } // Bars function buildBars(id, showAxis, item, index) { diff --git a/app/js/lib/tabs/heroesTab.js b/app/js/lib/tabs/heroesTab.js index 40e6cf58..128652bc 100644 --- a/app/js/lib/tabs/heroesTab.js +++ b/app/js/lib/tabs/heroesTab.js @@ -265,7 +265,7 @@ module.exports = { // HeroesGrid.refresh(response.heroes) // redrawHeroInputSelector(); // }); - await showBonusStatsWindow(row); + await module.exports.showBonusStatsWindow(row); Saves.autoSave(); }); @@ -389,75 +389,79 @@ module.exports = { equipped: new Array(6) } }, -} -async function showBonusStatsWindow(row) { - showEditHeroInfoPopups(row.name) - const bonusStats = await Dialog.editHeroDialog(row); - - if (!bonusStats) return; - - const e7StatToBonusStat = { - "att_rate": "aeiAttackPercent", - "max_hp_rate": "aeiHealthPercent", - "def_rate": "aeiDefensePercent", - "att": "aeiAttack", - "max_hp": "aeiHealth", - "def": "aeiDefense", - "speed": "aeiSpeed", - "res": "aeiEffectResistance", - "cri": "aeiCritChance", - "cri_dmg": "aeiCritDamage", - "acc": "aeiEffectiveness", - "coop": "aeiDualAttackChance" - } + showBonusStatsWindow: async (row) => { + showEditHeroInfoPopups(row.name) + const bonusStats = await Dialog.editHeroDialog(row); + + if (!bonusStats) return; + + const e7StatToBonusStat = { + "att_rate": "aeiAttackPercent", + "max_hp_rate": "aeiHealthPercent", + "def_rate": "aeiDefensePercent", + "att": "aeiAttack", + "max_hp": "aeiHealth", + "def": "aeiDefense", + "speed": "aeiSpeed", + "res": "aeiEffectResistance", + "cri": "aeiCritChance", + "cri_dmg": "aeiCritDamage", + "acc": "aeiEffectiveness", + "coop": "aeiDualAttackChance" + } - console.log("Bonus stats", bonusStats, row.id); + console.log("Bonus stats", bonusStats, row.id); - // Imprint - const imprintIngameType = bonusStats.heroInfo.self_devotion.type; - const imprintBonusType = e7StatToBonusStat[imprintIngameType]; - const imprintNumberText = bonusStats.imprintNumber; - if (imprintNumberText != "None") { - const imprintNumber = parseFloat(imprintNumberText) + // Imprint + const imprintIngameType = bonusStats.heroInfo.self_devotion.type; + const imprintBonusType = e7StatToBonusStat[imprintIngameType]; + const imprintNumberText = bonusStats.imprintNumber; + if (imprintNumberText != "None") { + const imprintNumber = parseFloat(imprintNumberText) - console.log("ADDING AEI IMPRINT", imprintNumber, imprintBonusType) + console.log("ADDING AEI IMPRINT", imprintNumber, imprintBonusType) - bonusStats[imprintBonusType] += imprintNumber; - } + bonusStats[imprintBonusType] += imprintNumber; + } + + // Artifact + const artifactName = bonusStats.artifactName; + if (artifactName != "None") { + const artifactLevelText = bonusStats.artifactLevel; + if (artifactLevelText != "None") { + const artifactLevel = parseInt(artifactLevelText); + const artifactStats = Artifact.getStats(artifactName, artifactLevel); - // Artifact - const artifactName = bonusStats.artifactName; - if (artifactName != "None") { - const artifactLevelText = bonusStats.artifactLevel; - if (artifactLevelText != "None") { - const artifactLevel = parseInt(artifactLevelText); - const artifactStats = Artifact.getStats(artifactName, artifactLevel); + console.log("ADDING AEI ARTIFACT", artifactLevel) + console.log("ADDING AEI ARTIFACT", artifactLevelText) + console.log("ADDING AEI ARTIFACT", artifactName) - console.log("ADDING AEI ARTIFACT", artifactLevel) - console.log("ADDING AEI ARTIFACT", artifactLevelText) - console.log("ADDING AEI ARTIFACT", artifactName) + bonusStats.aeiHealth += artifactStats.health; + bonusStats.aeiAttack += artifactStats.attack; + bonusStats.artifactHealth = artifactStats.health; + bonusStats.artifactAttack = artifactStats.attack; - bonusStats.aeiHealth += artifactStats.health; - bonusStats.aeiAttack += artifactStats.attack; + } } - } - // EE - const eeNumberText = bonusStats.eeNumber; - if (eeNumberText != "None") { - const eeNumber = parseInt(eeNumberText); - const eeIngameType = bonusStats.ee.stat.type; - const eeBonusType = e7StatToBonusStat[eeIngameType]; + // EE + const eeNumberText = bonusStats.eeNumber; + if (eeNumberText != "None") { + const eeNumber = parseInt(eeNumberText); + const eeIngameType = bonusStats.ee.stat.type; + const eeBonusType = e7StatToBonusStat[eeIngameType]; - console.log("ADDING AEI EE", eeBonusType, eeNumber) + console.log("ADDING AEI EE", eeBonusType, eeNumber) - bonusStats[eeBonusType] += eeNumber; - } + bonusStats[eeBonusType] += eeNumber; + } - await Api.setBonusStats(bonusStats, row.id).then(module.exports.redraw); - Notifier.success("Saved bonus stats"); + await Api.setBonusStats(bonusStats, row.id).then(module.exports.redraw); + Notifier.success("Saved bonus stats"); + } } + function showEditHeroInfoPopups(name) { if (name == "Eaton") { Notifier.info("Eaton's 20% total Health bonus from S2 is already automatically added.") @@ -518,7 +522,7 @@ function addHero(heroName, isBuild) { Api.getHeroById(newHero.id).then(async y => { const createdHero = y.hero; - await showBonusStatsWindow(createdHero); + await module.exports.showBonusStatsWindow(createdHero); Saves.autoSave(); }) }) diff --git a/app/js/lib/tabs/multiOptimizerTab.js b/app/js/lib/tabs/multiOptimizerTab.js index f94c3921..397e6f3b 100644 --- a/app/js/lib/tabs/multiOptimizerTab.js +++ b/app/js/lib/tabs/multiOptimizerTab.js @@ -83,15 +83,18 @@ function initializeBlank(index) { var localeText = AG_GRID_LOCALE_JA; } else if (i18next.language == 'ko') { var localeText = AG_GRID_LOCALE_KO; + } else if (i18next.language == 'ru') { + var localeText = AG_GRID_LOCALE_RU; } else { var localeText = AG_GRID_LOCALE_EN; } console.log('localeText:'+localeText); - const DIGITS_2 = 35; - const DIGITS_3 = 41; - const DIGITS_4 = 45; - const DIGITS_5 = 50; - const DIGITS_6 = 55; + + const DIGITS_2 = 30; + const DIGITS_3 = 35; + const DIGITS_4 = 42; + const DIGITS_5 = 45; + const DIGITS_6 = 50; function numberFormatter(params) { return params.value; @@ -122,7 +125,7 @@ function initializeBlank(index) { }, columnDefs: [ - {headerName: i18next.t('sets'), field: 'sets', width: 100, cellRenderer: (params) => GridRenderer.renderSets(params.value)}, + {headerName: i18next.t('sets'), field: 'sets', width: 90, cellRenderer: (params) => GridRenderer.renderSets(params.value)}, {headerName: i18next.t('atk'), field: 'atk', width: DIGITS_4}, {headerName: i18next.t('def'), field: 'def', width: DIGITS_4}, {headerName: i18next.t('hp'), field: 'hp', width: DIGITS_5}, @@ -142,10 +145,14 @@ function initializeBlank(index) { {headerName: i18next.t('mcds'), field: 'mcdmgps', width: DIGITS_4}, {headerName: i18next.t('dmgh'), field: 'dmgh', width: DIGITS_5}, {headerName: i18next.t('dmgd'), field: 'dmgd', width: DIGITS_5}, - {headerName: i18next.t('score'), field: 'score', width: DIGITS_3}, + {headerName: i18next.t('s1'), field: 's1', width: DIGITS_5}, + {headerName: i18next.t('s2'), field: 's2', width: DIGITS_5}, + {headerName: i18next.t('s3'), field: 's3', width: DIGITS_5}, + {headerName: i18next.t('gs'), field: 'score', width: DIGITS_3}, + {headerName: i18next.t('bs'), field: 'bs', width: DIGITS_3}, {headerName: i18next.t('prio'), field: 'priority', width: DIGITS_3}, - {headerName: i18next.t('upg'), field: 'upgrades', width: DIGITS_2, width: 48}, - {headerName: i18next.t('actions'), field: 'property', width: 50, sortable: false, cellRenderer: (params) => GridRenderer.renderStar(params.value)}, + {headerName: i18next.t('upg'), field: 'upgrades', width: DIGITS_2}, + {headerName: i18next.t(''), field: 'property', width: 50, sortable: false, cellRenderer: (params) => GridRenderer.renderStar(params.value)}, ], rowHeight: 27, rowModelType: 'infinite', @@ -710,7 +717,11 @@ function aggregateCurrentHeroStats(heroStats, index) { "mcdmgps", "dmgh", "dmgd", + "s1", + "s2", + "s3", "score", + "bs", "priority" ] diff --git a/app/js/lib/tabs/optimizerTab.js b/app/js/lib/tabs/optimizerTab.js index f80e8889..e26b657d 100644 --- a/app/js/lib/tabs/optimizerTab.js +++ b/app/js/lib/tabs/optimizerTab.js @@ -217,6 +217,49 @@ module.exports = { clearOptions(); recalculateFilters(); }); + + document.getElementById('skillOptionsButton').addEventListener("click", async () => { + var heroId = document.getElementById('inputHeroAdd').value; + if (!heroId) return; + console.log("addSkills", heroId); + + var skillOptions = await module.exports.showSkillOptionsWindow(heroId); + + Saves.autoSave(); + }); + + document.getElementById('addBonusStatsOptimizerButton').addEventListener("click", async () => { + var heroId = document.getElementById('inputHeroAdd').value; + if (!heroId) return; + + const hero = (await Api.getHeroById(heroId)).hero; + + await HeroesTab.showBonusStatsWindow(hero); + Saves.autoSave(); + }); + + document.getElementById('addSubstatModsOptimizerButton').addEventListener("click", async () => { + var heroId = document.getElementById('inputHeroAdd').value; + if (!heroId) return; + + const hero = (await Api.getHeroById(heroId)).hero; + + const modStats = await Dialog.editModStatsDialog(hero); + + // mods + + await Api.setModStats(modStats, hero.id); + Notifier.success("Saved mod stats"); + Saves.autoSave(); + + // var heroId = document.getElementById('inputHeroAdd').value; + // if (!heroId) return; + // console.log("addSkills", heroId); + + // var skillOptions = await module.exports.showSkillOptionsWindow(heroId); + + // Saves.autoSave(); + }); // document.getElementById('accessorySetsLabel').addEventListener("click", async () => { // Selectors.clearGearMainAndSets(); // recalculateFilters(); @@ -473,6 +516,13 @@ module.exports = { request.inputMinMcdmgpsLimit = readNumber('inputMinMcdmgpsLimit' + index); request.inputMaxMcdmgpsLimit = readNumber('inputMaxMcdmgpsLimit' + index); + request.inputMinS1Limit = readNumber('inputMinS1Limit' + index); + request.inputMaxS1Limit = readNumber('inputMaxS1Limit' + index); + request.inputMinS2Limit = readNumber('inputMinS2Limit' + index); + request.inputMaxS2Limit = readNumber('inputMaxS2Limit' + index); + request.inputMinS3Limit = readNumber('inputMinS3Limit' + index); + request.inputMaxS3Limit = readNumber('inputMaxS3Limit' + index); + request.inputMinDmgHLimit = readNumber('inputMinDmgHLimit' + index); request.inputMaxDmgHLimit = readNumber('inputMaxDmgHLimit' + index); request.inputMinDmgDLimit = readNumber('inputMinDmgDLimit' + index); @@ -483,6 +533,8 @@ module.exports = { request.inputMaxConversionsLimit = readNumber('inputMaxConversionsLimit' + index); request.inputMinScoreLimit = readNumber('inputMinScoreLimit' + index); request.inputMaxScoreLimit = readNumber('inputMaxScoreLimit' + index); + request.inputMinBSLimit = readNumber('inputMinBSLimit' + index); + request.inputMaxBSLimit = readNumber('inputMaxBSLimit' + index); request.inputMinPriorityLimit = readNumber('inputMinPriorityLimit' + index); request.inputMaxPriorityLimit = readNumber('inputMaxPriorityLimit' + index); @@ -601,6 +653,13 @@ module.exports = { $("#inputMinMcdmgpsLimit" + index).val(inputDisplayNumber(request.inputMinMcdmgpsLimit)); $("#inputMaxMcdmgpsLimit" + index).val(inputDisplayNumber(request.inputMaxMcdmgpsLimit)); + $("#inputMinS1Limit" + index).val(inputDisplayNumber(request.inputMinS1Limit)); + $("#inputMaxS1Limit" + index).val(inputDisplayNumber(request.inputMaxS1Limit)); + $("#inputMinS2Limit" + index).val(inputDisplayNumber(request.inputMinS2Limit)); + $("#inputMaxS2Limit" + index).val(inputDisplayNumber(request.inputMaxS2Limit)); + $("#inputMinS3Limit" + index).val(inputDisplayNumber(request.inputMinS3Limit)); + $("#inputMaxS3Limit" + index).val(inputDisplayNumber(request.inputMaxS3Limit)); + $("#inputMinDmgHLimit" + index).val(inputDisplayNumber(request.inputMinDmgHLimit)); $("#inputMaxDmgHLimit" + index).val(inputDisplayNumber(request.inputMaxDmgHLimit)); $("#inputMinDmgDLimit" + index).val(inputDisplayNumber(request.inputMinDmgDLimit)); @@ -611,6 +670,8 @@ module.exports = { $("#inputMaxConversionsLimit" + index).val(inputDisplayNumber(request.inputMaxConversionsLimit)); $("#inputMinScoreLimit" + index).val(inputDisplayNumber(request.inputMinScoreLimit)); $("#inputMaxScoreLimit" + index).val(inputDisplayNumber(request.inputMaxScoreLimit)); + $("#inputMinBSLimit" + index).val(inputDisplayNumber(request.inputMinBSLimit)); + $("#inputMaxBSLimit" + index).val(inputDisplayNumber(request.inputMaxBSLimit)); $("#inputMinPriorityLimit" + index).val(inputDisplayNumber(request.inputMinPriorityLimit)); $("#inputMaxPriorityLimit" + index).val(inputDisplayNumber(request.inputMaxPriorityLimit)); @@ -801,6 +862,22 @@ module.exports = { recalculateFilters(); Selectors.refreshInputHeroAdd(); Selectors.refreshAllowGearFrom(); + }, + + + showSkillOptionsWindow: async (heroId) => { + // showEditHeroInfoPopups(row.name) + const skillOptions = await Dialog.changeSkillOptionsDialog(heroId); + + if (!skillOptions) { + return; + } + + console.warn("skillOptions", skillOptions) + + Api.setSkillOptions(skillOptions, heroId) + Notifier.success("Saved skill options"); + Saves.autoSave(); } } @@ -1140,6 +1217,19 @@ async function submitOptimizationFilterRequest() { const heroId = document.getElementById('inputHeroAdd').value; const heroResponse = await Api.getHeroById(heroId, $('#inputPredictReforges').prop('checked')); params.hero = heroResponse.hero; + params.hero.artifactAttack = 0; + params.hero.artifactHealth = 0; + if (params.hero.artifactName && params.hero.artifactName != "None") { + const artifactLevelText = params.hero.artifactLevel; + if (artifactLevelText != "None") { + const artifactLevel = parseInt(artifactLevelText); + const artifactStats = Artifact.getStats(params.hero.artifactName, artifactLevel); + + params.hero.artifactHealth += artifactStats.health; + params.hero.artifactAttack += artifactStats.attack; + } + } + OptimizerGrid.showLoadingOverlay(); params.executionId = currentExecutionId; @@ -1167,6 +1257,7 @@ async function submitOptimizationRequest() { const hero = heroResponse.hero; const baseStats = heroResponse.baseStats; + var filterResult = await module.exports.applyItemFilters(params, heroResponse, allItemsResponse, true); var items = filterResult.items; @@ -1179,7 +1270,21 @@ async function submitOptimizationRequest() { items: items, bonusHp: hero.bonusHp, bonusAtk: hero.bonusAtk, - hero: hero + hero: hero, + damageMultipliers: DamageCalc.getMultipliers(hero, hero.skillOptions) + } + + request.hero.artifactAttack = 0; + request.hero.artifactHealth = 0; + if (request.hero.artifactName && request.hero.artifactName != "None") { + const artifactLevelText = request.hero.artifactLevel; + if (artifactLevelText != "None") { + const artifactLevel = parseInt(artifactLevelText); + const artifactStats = Artifact.getStats(request.hero.artifactName, artifactLevel); + + request.hero.artifactHealth = artifactStats.health; + request.hero.artifactAttack = artifactStats.attack; + } } if (!hero.artifactName || hero.artifactName == "None") { diff --git a/app/js/lib/tooltip.js b/app/js/lib/tooltip.js index 1a8d494a..b3ae6190 100644 --- a/app/js/lib/tooltip.js +++ b/app/js/lib/tooltip.js @@ -70,6 +70,9 @@ module.exports = { tippy('#filterStatsTooltip', { content: '

'+i18next.t("Select substat filters to filter results by. Left column is min (inclusive) and right column is max (inclusive).")+'

'}); + tippy('#filterSkillsTooltip', { + content: '

'+i18next.t("Select skill damage filters. Skill options can be changed through the Change skill options menu. Heroes with extra procs on S1 and no S2 damage will have their S2 replaced with the S1 proc value.")+'

'}); + tippy('#filterRatingsTooltip', { content: diff --git a/app/js/lib/updater.js b/app/js/lib/updater.js index a13cbeac..40b30c01 100644 --- a/app/js/lib/updater.js +++ b/app/js/lib/updater.js @@ -1,6 +1,6 @@ const { ipcRenderer } = require('electron'); global.ipcRenderer = ipcRenderer; -const currentVersion = "1.8.8"; +const currentVersion = "1.9.0"; global.TEST = true; @@ -13,6 +13,14 @@ global.TEST = true; - update version in app package.json - update repo in project package.json - yarn package + + Patch update checklist + - Update server temp unit ids + - Update server temp items + - Scan artifact ids, update artifact file + - Download unit images + - Upload herodata copy to server + *********************************************************************************************/ /******************************************************************************************** @@ -34,11 +42,14 @@ module.exports = { `

- New in v1.8.7 - 1.8.8 + New in v1.9.0

` ); diff --git a/app/package.json b/app/package.json index 80d7e36d..e20cdac1 100644 --- a/app/package.json +++ b/app/package.json @@ -5,7 +5,7 @@ "name": "Fribbels", "url": "https://github.com/fribbels/Fribbels-Epic-7-Optimizer" }, - "version": "1.8.8", + "version": "1.9.0", "description": "Epic 7 Gear Optimizer", "main": "./main.prod.js", "scripts": { diff --git a/backend/out/artifacts/backend_jar/backend.jar b/backend/out/artifacts/backend_jar/backend.jar index ae7ab23d..78c28c85 100644 Binary files a/backend/out/artifacts/backend_jar/backend.jar and b/backend/out/artifacts/backend_jar/backend.jar differ diff --git a/backend/src/main/java/com/fribbels/Main.java b/backend/src/main/java/com/fribbels/Main.java index d28b6ac6..b95ba412 100644 --- a/backend/src/main/java/com/fribbels/Main.java +++ b/backend/src/main/java/com/fribbels/Main.java @@ -9,6 +9,7 @@ import com.aparapi.internal.kernel.KernelManager; import com.aparapi.internal.opencl.OpenCLPlatform; import com.fribbels.core.StatCalculator; +import com.fribbels.db.ArtifactStatsDb; import com.fribbels.db.BaseStatsDb; import com.fribbels.db.HeroDb; import com.fribbels.db.ItemDb; @@ -32,9 +33,10 @@ public class Main { private static HttpServer server; private static ExecutorService executorService; - private static final HeroDb heroDb = new HeroDb(); - private static final ItemDb itemDb = new ItemDb(heroDb); + public static final ArtifactStatsDb artifactStatsDb = new ArtifactStatsDb(); private static final BaseStatsDb baseStatsDb = new BaseStatsDb(); + private static final HeroDb heroDb = new HeroDb(baseStatsDb); + private static final ItemDb itemDb = new ItemDb(heroDb); private static final OptimizationDb optimizationDb = new OptimizationDb(); public static boolean interrupt = false; @@ -67,7 +69,8 @@ public static void start() throws Exception { return; } - final HeroesRequestHandler heroesRequestHandler = new HeroesRequestHandler(heroDb, baseStatsDb, itemDb, new StatCalculator()); + + final HeroesRequestHandler heroesRequestHandler = new HeroesRequestHandler(heroDb, baseStatsDb, artifactStatsDb, itemDb, new StatCalculator()); server.createContext("/system", new SystemRequestHandler()); server.createContext("/items", new ItemsRequestHandler(itemDb, heroDb, baseStatsDb, heroesRequestHandler)); diff --git a/backend/src/main/java/com/fribbels/core/Sorter.java b/backend/src/main/java/com/fribbels/core/Sorter.java index 8998a67d..9d62427d 100644 --- a/backend/src/main/java/com/fribbels/core/Sorter.java +++ b/backend/src/main/java/com/fribbels/core/Sorter.java @@ -71,12 +71,24 @@ public static void sortHeroes(final HeroStats[] data, final OptimizationColumn c case DMGD: Arrays.sort(data, Comparator.comparingInt(HeroStats::getDmgd)); break; + case S1: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getS1)); + break; + case S2: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getS2)); + break; + case S3: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getS3)); + break; case UPGRADES: Arrays.sort(data, Comparator.comparingInt(HeroStats::getUpgrades)); break; case SCORE: Arrays.sort(data, Comparator.comparingInt(HeroStats::getScore)); break; + case BS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getBs)); + break; case PRIORITY: Arrays.sort(data, Comparator.comparingInt(HeroStats::getPriority)); break; @@ -147,12 +159,24 @@ public static void sortHeroes(final HeroStats[] data, final OptimizationColumn c case DMGD: Arrays.sort(data, Comparator.comparingInt(HeroStats::getDmgd).reversed()); break; + case S1: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getS1).reversed()); + break; + case S2: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getS2).reversed()); + break; + case S3: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getS3).reversed()); + break; case UPGRADES: Arrays.sort(data, Comparator.comparingInt(HeroStats::getUpgrades).reversed()); break; case SCORE: Arrays.sort(data, Comparator.comparingInt(HeroStats::getScore).reversed()); break; + case BS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getBs).reversed()); + break; case PRIORITY: Arrays.sort(data, Comparator.comparingInt(HeroStats::getPriority).reversed()); break; diff --git a/backend/src/main/java/com/fribbels/core/StatCalculator.java b/backend/src/main/java/com/fribbels/core/StatCalculator.java index d9161f8a..da0d1919 100644 --- a/backend/src/main/java/com/fribbels/core/StatCalculator.java +++ b/backend/src/main/java/com/fribbels/core/StatCalculator.java @@ -1,11 +1,11 @@ package com.fribbels.core; +import com.fribbels.Main; import com.fribbels.enums.StatType; -import com.fribbels.model.AugmentedStats; -import com.fribbels.model.Hero; -import com.fribbels.model.HeroStats; -import com.fribbels.model.Item; +import com.fribbels.model.*; +import org.apache.commons.lang3.StringUtils; +import javax.swing.*; import java.util.Map; import static com.fribbels.handler.OptimizationRequestHandler.SET_COUNT; @@ -121,28 +121,121 @@ public HeroStats addAccumulatorArrsToHero(final HeroStats base, final int cp = (int) (((atk * 1.6f + atk * 1.6f * critRate * critDamage) * (1.0 + (spd - 45f) * 0.02f) + hp + def * 9.3f) * (1f + (res/100f + eff/100f) / 4f)); + final float penSetOn = sets[13] > 1 ? 1 : 0; final float rageMultiplier = SETTING_RAGE_SET && sets[11] > 3 ? 0.3f : 0; - final float torrentMultiplier = sets[17] > 1 ? sets[17] / 2 * 0.1f : 0; - final float pctDmgMultiplier = 1 + rageMultiplier + torrentMultiplier; final float penMultiplier = SETTING_PEN_SET && sets[13] > 1 ? penSetDmgBonus : 1; + final float torrentMultiplier = sets[17] > 1 ? sets[17] / 2 * 0.1f : 0; final float spdDiv1000 = (float)spd/1000; + final float pctDmgMultiplier = 1 + rageMultiplier + torrentMultiplier; final int ehp = (int) (hp * (def/300 + 1)); final int hpps = (int) (hp*spdDiv1000); final int ehpps = (int) ((float)ehp*spdDiv1000); - final int dmg = (int) (((critRate * atk * critDamage) + (1-critRate) * atk) * pctDmgMultiplier * penMultiplier); + final int dmg = (int) (((critRate * atk * critDamage) + (1-critRate) * atk) * penMultiplier * pctDmgMultiplier); final int dmgps = (int) ((float)dmg*spdDiv1000); - final int mcdmg = (int) (atk * critDamage * pctDmgMultiplier * penMultiplier); + final int mcdmg = (int) (atk * critDamage * penMultiplier * pctDmgMultiplier); final int mcdmgps = (int) ((float)mcdmg*spdDiv1000); - final int dmgh = (int) ((critDamage * hp)/10 * pctDmgMultiplier * penMultiplier); - final int dmgd = (int) ((critDamage * def) * pctDmgMultiplier * penMultiplier); + final int dmgh = (int) ((critDamage * hp)/10 * penMultiplier * pctDmgMultiplier); + final int dmgd = (int) ((critDamage * def) * penMultiplier * pctDmgMultiplier); +/* + +(increase dmg) * [(atk + bonus atk) * (pow * multi) * (cdmg)] + +{[(ATK !!)(Atkmod)(Rate **)+(FlatMod)] * (1.871)+(Flat2Mod)} × (pow **)(a) + + +a = (EnhanceMod)(HitTypeMod)(ElementMod)(DamageUpMod)(TargetDebuffMod) +rate -> scaling +flatmod -> max hp/def scaling +flat2mod -> ddj + */ + DamageMultipliers multis = hero.getDamageMultipliers(); + if (multis == null) { + multis = new DamageMultipliers(); + } +// final int s1 = (int)(((atk * multis.getAtkMods()[0] * multis.getRates()[0] + getFlatMod(multis, 0, hp)) * getTypeMultiplier(multis, 0)) * multis.getPows()[0] * multis.getMultis()[0]); +// final int s2 = (int)(((atk * multis.getAtkMods()[1] * multis.getRates()[1] + getFlatMod(multis, 1, hp)) * getTypeMultiplier(multis, 1)) * multis.getPows()[1] * multis.getMultis()[1]); +// final int s3 = (int)(((atk * multis.getAtkMods()[2] * multis.getRates()[2] + getFlatMod(multis, 2, hp)) * getTypeMultiplier(multis, 2)) * multis.getPows()[2] * multis.getMultis()[2]); + // (1 + multis.getAtkIncrease()[0]) + + final int s1 = getSkillValue(multis, 0, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); + final int s2 = getSkillValue(multis, 1, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); + final int s3 = getSkillValue(multis, 2, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); +// final int score = (int) (accs0[11]+accs1[11]+accs2[11]+accs3[11]+accs4[11]+accs5[11]); - return new HeroStats((int)atk, (int)hp, (int)def, (int) cr, cd, eff, res, 0, spd, cp, ehp, hpps, ehpps, dmg, dmgps, mcdmg, mcdmgps, dmgh, dmgd, upgrades, conversions, score, priority, +// final ArtifactStats artifactStats = Main.artifactStatsDb.getArtifactStats(hero.artifactName, Integer.parseInt(hero.getArtifactLevel())); +// final float artifactHealth = artifactStats.getHealth(); +// final float artifactAttack = artifactStats.getAttack(); + + final float bsHp = (hp - base.hp - hero.artifactHealth - (sets[0] > 1 ? sets[0] / 2 * hpSetBonus : 0) + (sets[17] > 1 ? sets[17] / 2 * hpSetBonus/2 : 0)) / base.hp * 100; + final float bsAtk = (atk - base.atk - hero.artifactAttack - (sets[2] > 1 ? sets[2] / 4 * atkSetBonus : 0)) / base.atk * 100; + final float bsDef = (def - base.def - (sets[1] > 1 ? sets[1] / 2 * defSetBonus : 0)) / base.def * 100; + final float bsCr = (cr - base.cr - (sets[4] > 1 ? sets[4] / 2 * 12 : 0)); + final float bsCd = (cd - base.cd - (sets[6] > 3 ? 60 : 0)); + final float bsEff = (eff - base.eff - (sets[5] > 1 ? sets[5] / 2 * 20 : 0)); + final float bsRes = (res - base.res - (sets[9] > 1 ? sets[9] / 2 * 20 : 0)); + final float bsSpd = (spd - base.spd - (sets[3] > 3 ? speedSetBonus : 0) - (sets[14] > 3 ? revengeSetBonus : 0)); + +// hp: (row.hp - base.hp - artiHp - bonusSetMaxHp/100*base.hp - bonusSetTorrent/100*base.hp) / base.hp * 100, +// atk: (row.atk - base.atk - artiAtk - bonusSetAtt/100*base.atk) / base.atk * 100, +// def: (row.def - base.def - bonusSetDef/100*base.def) / base.def * 100, +// chc: (Math.min(100, row.chc) - base.chc*100 - bonusSetCri), +// chd: (Math.min(350, row.chd) - base.chd*100 - bonusSetCriDmg), +// eff: (row.eff - base.eff*100 - bonusSetAcc), +// res: (row.efr - base.efr*100 - bonusSetRes), +// spd: (row.spd - base.spd - bonusSetSpeed - bonusSetRevenge), + + final int bs = (int) (bsHp + bsAtk + bsDef + bsCr*1.6f + bsCd*1.14f + bsEff + bsRes + bsSpd*2); + + return new HeroStats((int)atk, (int)hp, (int)def, (int) cr, cd, eff, res, 0, spd, cp, ehp, hpps, ehpps, + dmg, dmgps, mcdmg, mcdmgps, dmgh, dmgd, s1, s2, s3, upgrades, conversions, score, bs, priority, base.bonusStats, null, null, null, null, null, null, null); } + private int getSkillValue(final DamageMultipliers m, + final int s, + final float atk, + final float def, + final float hp, + final float spd, + final float critDamage, + final float pctDmgMultiplier, + final float penSetOn) { + final int targets = m.getTargets()[s] == 1 ? 1 : 0; + final float realPenetration = (1 - m.getPenetration()[s]) * (1 - penSetOn * 0.15f * targets); + final float statScalings = + m.getSelfHpScaling()[s] *hp + + m.getSelfAtkScaling()[s]*atk + + m.getSelfDefScaling()[s]*def + + m.getSelfSpdScaling()[s]*spd; + final float hitTypeMultis = m.getCrit()[s] * (critDamage+m.getCdmgIncrease()[s]) + m.getHitMulti()[s]; + final float increasedValue = 1 + m.getIncreasedValue()[s]; + final float dmgUpMod = 1 + m.getSelfSpdScaling()[s] * spd; + final float extraDamage = ( + m.getExtraSelfHpScaling()[s] *hp + + m.getExtraSelfAtkScaling()[s]*atk + + m.getExtraSelfDefScaling()[s]*def) * 1.871f * 1f/(StatCalculator.SETTING_PEN_DEFENSE*0.3f/300f + 1f); + final float offensive = (atk * m.getRate()[s] + statScalings) * 1.871f * m.getPow()[s] * increasedValue * hitTypeMultis * dmgUpMod * pctDmgMultiplier; + final float support = m.getSelfHpScaling()[s] * hp * m.getSupport()[s] + m.getSelfAtkScaling()[s] * atk * m.getSupport()[s] + m.getSelfDefScaling()[s] * def * m.getSupport()[s]; + final float defensive = 1f/(StatCalculator.SETTING_PEN_DEFENSE*Math.max(0, realPenetration)/300f + 1f); + final int value = (int)(offensive * defensive + support + extraDamage); + +// System.out.println("S" + (s+1) + " " + value + " " + (hitTypeMultis) + " " + (1.871f * m.getPow()[s])); +// System.out.println(m); + + return value; + } + + private float getFlatMod(final DamageMultipliers damageMultipliers, final int skill, final float hp) { + float value = 0; +// if (damageMultipliers.getSelfHpScalings()[skill] != 0) { +// value += damageMultipliers.getSelfHpScalings()[skill] * hp; +// } + + return value; + } + public float[] getStatAccumulatorArr(final HeroStats base, final Item item, final Map accumulatorsByItemId, diff --git a/backend/src/main/java/com/fribbels/db/ArtifactStatsDb.java b/backend/src/main/java/com/fribbels/db/ArtifactStatsDb.java new file mode 100644 index 00000000..81ec94dd --- /dev/null +++ b/backend/src/main/java/com/fribbels/db/ArtifactStatsDb.java @@ -0,0 +1,47 @@ +package com.fribbels.db; + +import com.fribbels.core.SpecialStats; +import com.fribbels.model.ArtifactStats; +import com.fribbels.model.BaseStats; +import com.fribbels.model.HeroStats; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class ArtifactStatsDb { + + private Map artifactStatsByName; + + public ArtifactStatsDb() { + artifactStatsByName = new HashMap<>(); + } + + public ArtifactStats getArtifactStats(final String name, final int level) { + if (artifactStatsByName.containsKey(name)) { + final ArtifactStats base = artifactStatsByName.get(name); + final float maxAttack = base.getAttack() * 13; + final float maxHealth = base.getHealth() * 13; + + final float leveledAttack = (maxAttack - base.getAttack()) * (level / 30f) + base.getAttack(); + final float leveledHealth = (maxHealth - base.getHealth()) * (level / 30f) + base.getHealth(); + + return ArtifactStats + .builder() + .attack(leveledAttack) + .health(leveledHealth) + .build(); + } + + return ArtifactStats + .builder() + .attack(0f) + .health(0f) + .build(); + } + + public void setArtifactStatsByName(final Map artifactStatsByName) { + this.artifactStatsByName = artifactStatsByName; + } +} + diff --git a/backend/src/main/java/com/fribbels/db/BaseStatsDb.java b/backend/src/main/java/com/fribbels/db/BaseStatsDb.java index 5d04cd28..5445af55 100644 --- a/backend/src/main/java/com/fribbels/db/BaseStatsDb.java +++ b/backend/src/main/java/com/fribbels/db/BaseStatsDb.java @@ -16,9 +16,13 @@ public BaseStatsDb() { baseStatsByName = new HashMap<>(); } public BaseStats getBaseStatsByName(final String name) { + if (!baseStatsByName.containsKey(name)) { + return null; + } return BaseStats.builder() .lv50FiveStarFullyAwakened(getBaseStatsByName(name, 5)) .lv60SixStarFullyAwakened(getBaseStatsByName(name, 6)) + .skills(baseStatsByName.get(name).getSkills()) .build(); } diff --git a/backend/src/main/java/com/fribbels/db/HeroDb.java b/backend/src/main/java/com/fribbels/db/HeroDb.java index 4f5d3182..33649bd3 100644 --- a/backend/src/main/java/com/fribbels/db/HeroDb.java +++ b/backend/src/main/java/com/fribbels/db/HeroDb.java @@ -14,10 +14,12 @@ public class HeroDb { + private BaseStatsDb baseStatsDb; private List heroes; - public HeroDb() { + public HeroDb(final BaseStatsDb baseStatsDb) { heroes = new ArrayList<>(); + this.baseStatsDb = baseStatsDb; } public void addHeroes(final List newHeroes) { @@ -51,6 +53,8 @@ public void setHeroes(final List newHeroes) { } for (int i = 0 ; i < newHeroes.size(); i++) { final Hero newHero = newHeroes.get(i); + newHero.setSkills(baseStatsDb.getBaseStatsByName(newHero.name).getSkills()); + sanitizeHero(newHero); newHero.setIndex(i + 1); } diff --git a/backend/src/main/java/com/fribbels/db/OptimizationDb.java b/backend/src/main/java/com/fribbels/db/OptimizationDb.java index c845c28d..23c33977 100644 --- a/backend/src/main/java/com/fribbels/db/OptimizationDb.java +++ b/backend/src/main/java/com/fribbels/db/OptimizationDb.java @@ -59,8 +59,8 @@ public void setFilteredIds(final Set newFilteredIds, final int newFilter } public HeroStats[] getRows(final int startRow, final int endRow) { - System.out.println("Filtered indices.length " + filteredIndices.length); - System.out.println("FilteredIds size " + filteredIds.size()); +// System.out.println("Filtered indices.length " + filteredIndices.length); +// System.out.println("FilteredIds size " + filteredIds.size()); if (filteredIds.size() == 0) { return ArrayUtils.subarray(resultHeroStats, startRow, endRow); @@ -95,9 +95,9 @@ public void sort(final OptimizationColumn newColumn, final SortOrder newOrder) { return; } - System.out.println("START SORT"); +// System.out.println("START SORT"); Sorter.sortHeroes(resultHeroStats, newColumn, newOrder); - System.out.println("END SORT"); +// System.out.println("END SORT"); int count = 0; final int[] sortedFilteredIndices = new int[Integer.parseInt("" + maximum)]; diff --git a/backend/src/main/java/com/fribbels/enums/OptimizationColumn.java b/backend/src/main/java/com/fribbels/enums/OptimizationColumn.java index 207c44c7..bbbae720 100644 --- a/backend/src/main/java/com/fribbels/enums/OptimizationColumn.java +++ b/backend/src/main/java/com/fribbels/enums/OptimizationColumn.java @@ -27,8 +27,12 @@ public enum OptimizationColumn { @SerializedName("mcdmgps") MCDMGPS, @SerializedName("dmgh") DMGH, @SerializedName("dmgd") DMGD, + @SerializedName("s1") S1, + @SerializedName("s2") S2, + @SerializedName("s3") S3, @SerializedName("upgrades") UPGRADES, @SerializedName("conversions") CONVERSIONS, @SerializedName("score") SCORE, + @SerializedName("bs") BS, @SerializedName("priority") PRIORITY, } diff --git a/backend/src/main/java/com/fribbels/gpu/GpuOptimizerKernel.java b/backend/src/main/java/com/fribbels/gpu/GpuOptimizerKernel.java index 67698d88..30018fd7 100644 --- a/backend/src/main/java/com/fribbels/gpu/GpuOptimizerKernel.java +++ b/backend/src/main/java/com/fribbels/gpu/GpuOptimizerKernel.java @@ -1,6 +1,7 @@ package com.fribbels.gpu; import com.aparapi.Kernel; +import com.fribbels.model.DamageMultipliers; import com.fribbels.model.Hero; import com.fribbels.model.HeroStats; import com.fribbels.request.OptimizationRequest; @@ -16,14 +17,14 @@ public class GpuOptimizerKernel extends Kernel { @Constant final float[] flattenedRingAccs; @Constant final float[] flattenedBootAccs; - @Constant final int wSize; - @Constant final int hSize; - @Constant final int aSize; - @Constant final int nSize; - @Constant final int rSize; - @Constant final int bSize; + @Constant final long wSize; + @Constant final long hSize; + @Constant final long aSize; + @Constant final long nSize; + @Constant final long rSize; + @Constant final long bSize; - @Constant final int argSize; + @Constant final long argSize; @Constant final float bonusBaseAtk; @Constant final float bonusBaseHp; @@ -36,6 +37,8 @@ public class GpuOptimizerKernel extends Kernel { @Constant final float revengeSetBonus; @Constant final float penSetDmgBonus; + @Constant final float targetDefense; + @Constant final float bonusMaxAtk; @Constant final float bonusMaxHp; @Constant final float bonusMaxDef; @@ -43,6 +46,9 @@ public class GpuOptimizerKernel extends Kernel { @Constant final int SETTING_RAGE_SET; @Constant final int SETTING_PEN_SET; + @Constant final float baseAtk; + @Constant final float baseHp; + @Constant final float baseDef; @Constant final float baseCr; @Constant final float baseCd; @Constant final float baseEff; @@ -60,11 +66,30 @@ public class GpuOptimizerKernel extends Kernel { @Constant final float aeiEff; @Constant final float aeiRes; @Constant final float aeiSpeed; +// +// +// @Constant final float s1Rate; +// @Constant final float s1Pow; +// @Constant final float s1SelfHpScaling; +// @Constant final float s1SelfAtkScaling; +// @Constant final float s1SelfDefScaling; +// @Constant final float s1SelfSpdScaling; +// @Constant final float s1ConstantValue; +// @Constant final float s1SelfAtkConstantValue; +// @Constant final float s1ConditionalIncreasedValue; +// @Constant final float s1DefDiffPen; +// @Constant final float s1DefDiffPenMax; +// @Constant final float s1AtkDiffPen; +// @Constant final float s1AtkDiffPenMax; +// @Constant final float s1SpdDiffPen; +// @Constant final float s1SpdDiffPenMax; +// @Constant final float s1Penetration; +// @Constant final float s1AtkIncrease; @Constant final boolean[] boolArr; @Constant final int[] setPermutationIndicesPlusOne; final int[] setSolutionCounters; - @Constant final int max; + @Constant final long max; // Attempt at optimizing filters // @Constant final int[] sumValues = new int[] {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // 21 values, one per filter @@ -113,12 +138,54 @@ public class GpuOptimizerKernel extends Kernel { @Constant final int inputMaxDmgHLimit; @Constant final int inputMinDmgDLimit; @Constant final int inputMaxDmgDLimit; + + @Constant final int inputMinS1Limit; + @Constant final int inputMaxS1Limit; + @Constant final int inputMinS2Limit; + @Constant final int inputMaxS2Limit; + @Constant final int inputMinS3Limit; + @Constant final int inputMaxS3Limit; + + @Constant final float[] rate; + @Constant final float[] pow; + @Constant final int[] targets; + + @Constant final float[] selfHpScaling; + @Constant final float[] selfAtkScaling; + @Constant final float[] selfDefScaling; + @Constant final float[] selfSpdScaling; + @Constant final float[] constantValue; + @Constant final float[] selfAtkConstantValue; + @Constant final float[] increasedValue; + @Constant final float[] defDiffPen; + @Constant final float[] defDiffPenMax; + @Constant final float[] atkDiffPen; + @Constant final float[] atkDiffPenMax; + @Constant final float[] spdDiffPen; + @Constant final float[] spdDiffPenMax; + @Constant final float[] penetration; + @Constant final float[] atkIncrease; + @Constant final float[] cdmgIncrease; + @Constant final float[] crit; + @Constant final float[] damage; + @Constant final float[] support; + @Constant final float[] hitMulti; + + @Constant final float[] extraSelfAtkScaling; + @Constant final float[] extraSelfDefScaling; + @Constant final float[] extraSelfHpScaling; + + @Constant final float artifactHealth; + @Constant final float artifactAttack; + @Constant final int inputMinUpgradesLimit; @Constant final int inputMaxUpgradesLimit; @Constant final int inputMinConversionsLimit; @Constant final int inputMaxConversionsLimit; @Constant final int inputMinScoreLimit; @Constant final int inputMaxScoreLimit; + @Constant final int inputMinBSLimit; + @Constant final int inputMaxBSLimit; @Constant final int inputMinPriorityLimit; @Constant final int inputMaxPriorityLimit; @@ -148,6 +215,7 @@ public GpuOptimizerKernel( final float speedSetBonus, final float revengeSetBonus, final float penSetDmgBonus, + final float targetDefense, final float bonusMaxAtk, final float bonusMaxDef, final float bonusMaxHp, @@ -155,14 +223,14 @@ public GpuOptimizerKernel( final int SETTING_PEN_SET, final HeroStats base, final Hero hero, - final int argSize, - final int wSize, - final int hSize, - final int aSize, - final int nSize, - final int rSize, - final int bSize, - final int max, + final long argSize, + final long wSize, + final long hSize, + final long aSize, + final long nSize, + final long rSize, + final long bSize, + final long max, final int[] setSolutionBitMasks ) { this.flattenedWeaponAccs = flattenedWeaponAccs; @@ -259,6 +327,8 @@ public GpuOptimizerKernel( this.revengeSetBonus = revengeSetBonus; this.penSetDmgBonus = penSetDmgBonus; + this.targetDefense = targetDefense; + this.bonusMaxAtk = bonusMaxAtk; this.bonusMaxDef = bonusMaxDef; this.bonusMaxHp = bonusMaxHp; @@ -266,6 +336,9 @@ public GpuOptimizerKernel( this.SETTING_RAGE_SET = SETTING_RAGE_SET; this.SETTING_PEN_SET = SETTING_PEN_SET; + this.baseAtk = base.atk; + this.baseHp = base.hp; + this.baseDef = base.def; this.baseCr = base.cr; this.baseCd = base.cd; this.baseEff = base.eff; @@ -329,22 +402,95 @@ public GpuOptimizerKernel( inputMaxDmgHLimit = request.inputMaxDmgHLimit; inputMinDmgDLimit = request.inputMinDmgDLimit; inputMaxDmgDLimit = request.inputMaxDmgDLimit; + + inputMinS1Limit = request.inputMinS1Limit; + inputMaxS1Limit = request.inputMaxS1Limit; + inputMinS2Limit = request.inputMinS2Limit; + inputMaxS2Limit = request.inputMaxS2Limit; + inputMinS3Limit = request.inputMinS3Limit; + inputMaxS3Limit = request.inputMaxS3Limit; + + artifactAttack = request.hero.artifactAttack; + artifactHealth = request.hero.artifactHealth; + inputMinUpgradesLimit = request.inputMinUpgradesLimit; inputMaxUpgradesLimit = request.inputMaxUpgradesLimit; inputMinConversionsLimit = request.inputMinConversionsLimit; inputMaxConversionsLimit = request.inputMaxConversionsLimit; inputMinScoreLimit = request.inputMinScoreLimit; inputMaxScoreLimit = request.inputMaxScoreLimit; + inputMinBSLimit = request.inputMinBSLimit; + inputMaxBSLimit = request.inputMaxBSLimit; inputMinPriorityLimit = request.inputMinPriorityLimit; inputMaxPriorityLimit = request.inputMaxPriorityLimit; +// s1SelfSpdScaling = hero + this.max = max; this.boolArr = request.boolArr; this.setPermutationIndicesPlusOne = request.setPermutationIndicesPlusOne; this.setSolutionCounters = request.setSolutionCounters; this.setSolutionBitMasks = setSolutionBitMasks; + + final DamageMultipliers dm = hero.getDamageMultipliers(); + + this.rate = floatArr(dm.getRate()); + this.pow = floatArr(dm.getPow()); + this.targets = flattenTargets(dm.getTargets()); + this.selfHpScaling = floatArr(dm.getSelfHpScaling()); + this.selfAtkScaling = floatArr(dm.getSelfAtkScaling()); + this.selfDefScaling = floatArr(dm.getSelfDefScaling()); + this.selfSpdScaling = floatArr(dm.getSelfSpdScaling()); + this.constantValue = floatArr(dm.getConstantValue()); + this.selfAtkConstantValue = floatArr(dm.getSelfAtkConstantValue()); + this.increasedValue = floatArr(dm.getIncreasedValue()); + this.defDiffPen = floatArr(dm.getDefDiffPen()); + this.defDiffPenMax = floatArr(dm.getDefDiffPenMax()); + this.atkDiffPen = floatArr(dm.getAtkDiffPen()); + this.atkDiffPenMax = floatArr(dm.getAtkDiffPenMax()); + this.spdDiffPen = floatArr(dm.getSpdDiffPen()); + this.spdDiffPenMax = floatArr(dm.getSpdDiffPenMax()); + this.penetration = floatArr(dm.getPenetration()); + this.atkIncrease = floatArr(dm.getAtkIncrease()); + this.cdmgIncrease = floatArr(dm.getCdmgIncrease()); + this.crit = floatArr(dm.getCrit()); + this.damage = floatArr(dm.getDamage()); + this.support = floatArr(dm.getSupport()); + this.hitMulti = floatArr(dm.getHitMulti()); + this.extraSelfAtkScaling = floatArr(dm.getExtraSelfAtkScaling()); + this.extraSelfDefScaling = floatArr(dm.getExtraSelfDefScaling()); + this.extraSelfHpScaling = floatArr(dm.getExtraSelfHpScaling()); + } + + private float[] floatArr(final Float[] arr) { + if (arr == null) { + return new float[]{0, 0, 0}; + } + return new float[]{arr[0], arr[1], arr[2]}; + } + + private int[] intArr(final Integer[] arr) { + if (arr == null) { + return new int[]{0, 0, 0}; + } + return new int[]{arr[0], arr[1], arr[2]}; + } + + private int[] flattenTargets(final Integer[] arr) { + if (arr == null) { + return new int[]{0, 0, 0}; + } + return new int[]{zeroOrOne(arr[0]), zeroOrOne(arr[1]), zeroOrOne(arr[2])}; + } + + private int zeroOrOne(final int i) { + if (i == 1) { + return 1; + } + return 0; } + int oneIfNegativeElseZero(int a) { return ((a ^ 1) >> 31) * -1; } @@ -357,16 +503,16 @@ public void run() { final int id = getGlobalId(); // final int localId = getLocalId(); - final long i = ((long)max) * iteration + id; - if (i < ((long)(wSize)) * hSize * aSize * nSize * rSize * bSize) { - final int b = (int)(i % bSize); - final int r = (int)(( ( i - b ) / bSize ) % rSize); - final int n = (int)(( ( i - r * bSize - b ) / (bSize * rSize) ) % nSize); - final int a = (int)(( ( i - n * rSize * bSize - r * bSize - b ) / (bSize * rSize * nSize) ) % aSize); - final int h = (int)(( ( i - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize) ) % hSize); - final int w = (int)(( ( i - h * aSize * nSize * rSize * bSize - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize * hSize) ) % wSize); + final long i = max * iteration + id; + if (i < wSize * hSize * aSize * nSize * rSize * bSize) { + final long b = i % bSize; + final long r = ( ( i - b ) / bSize ) % rSize; + final long n = ( ( i - r * bSize - b ) / (bSize * rSize) ) % nSize; + final long a = ( ( i - n * rSize * bSize - r * bSize - b ) / (bSize * rSize * nSize) ) % aSize; + final long h = ( ( i - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize) ) % hSize; + final long w = ( ( i - h * aSize * nSize * rSize * bSize - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize * hSize) ) % wSize; - final int wargSize = w * argSize; + final int wargSize = (int)(w * argSize); final float wAtk = flattenedWeaponAccs[wargSize]; final float wHp = flattenedWeaponAccs[wargSize + 1]; final float wDef = flattenedWeaponAccs[wargSize + 2]; @@ -381,7 +527,7 @@ public void run() { final float wUpg = flattenedWeaponAccs[wargSize + 14]; final float wConv = flattenedWeaponAccs[wargSize + 15]; - final int hargSize = h * argSize; + final int hargSize = (int)(h * argSize); final float hAtk = flattenedHelmetAccs[hargSize]; final float hHp = flattenedHelmetAccs[hargSize + 1]; final float hDef = flattenedHelmetAccs[hargSize + 2]; @@ -396,7 +542,7 @@ public void run() { final float hUpg = flattenedHelmetAccs[hargSize + 14]; final float hConv = flattenedHelmetAccs[hargSize + 15]; - final int aargSize = a * argSize; + final int aargSize = (int)(a * argSize); final float aAtk = flattenedArmorAccs[aargSize]; final float aHp = flattenedArmorAccs[aargSize + 1]; final float aDef = flattenedArmorAccs[aargSize + 2]; @@ -411,7 +557,7 @@ public void run() { final float aUpg = flattenedArmorAccs[aargSize + 14]; final float aConv = flattenedArmorAccs[aargSize + 15]; - final int nargSize = n * argSize; + final int nargSize = (int)(n * argSize); final float nAtk = flattenedNecklaceAccs[nargSize]; final float nHp = flattenedNecklaceAccs[nargSize + 1]; final float nDef = flattenedNecklaceAccs[nargSize + 2]; @@ -426,7 +572,7 @@ public void run() { final float nUpg = flattenedNecklaceAccs[nargSize + 14]; final float nConv = flattenedNecklaceAccs[nargSize + 15]; - final int rargSize = r * argSize; + final int rargSize = (int)(r * argSize); final float rAtk = flattenedRingAccs[rargSize]; final float rHp = flattenedRingAccs[rargSize + 1]; final float rDef = flattenedRingAccs[rargSize + 2]; @@ -441,7 +587,7 @@ public void run() { final float rUpg = flattenedRingAccs[rargSize + 14]; final float rConv = flattenedRingAccs[rargSize + 15]; - final int bargSize = b * argSize; + final int bargSize = (int)(b * argSize); final float bAtk = flattenedBootAccs[bargSize]; final float bHp = flattenedBootAccs[bargSize + 1]; final float bDef = flattenedBootAccs[bargSize + 2]; @@ -573,26 +719,72 @@ public void run() { final int cp = (int) (((atk * 1.6f + atk * 1.6f * critRate * critDamage) * (1.0 + (spd - 45f) * 0.02f) + hp + def * 9.3f) * (1f + (res/100f + eff/100f) / 4f)); - final float rageMultiplier = max(1, rageSet * SETTING_RAGE_SET * 1.3f); - final float penMultiplier = max(1, min(penSet, 1) * SETTING_PEN_SET * penSetDmgBonus); - final float torrentMultiplier = max(1, 1 + torrentSet * 0.1f); + final float penSetOn = min(penSet, 1); + final float rageMultiplier = max(0, rageSet * SETTING_RAGE_SET * 0.3f); + final float penMultiplier = max(1, penSetOn * SETTING_PEN_SET * penSetDmgBonus); + final float torrentMultiplier = max(0, torrentSet * 0.1f); final float spdDiv1000 = (float)spd/1000; + final float pctDmgMultiplier = 1 + rageMultiplier + torrentMultiplier; final int ehp = (int) (hp * (def/300 + 1)); final int hpps = (int) (hp*spdDiv1000); final int ehpps = (int) ((float)ehp*spdDiv1000); - final int dmg = (int) (((critRate * atk * critDamage) + (1-critRate) * atk) * rageMultiplier * penMultiplier * torrentMultiplier); + final int dmg = (int) (((critRate * atk * critDamage) + (1-critRate) * atk) * penMultiplier * pctDmgMultiplier); final int dmgps = (int) ((float)dmg*spdDiv1000); - final int mcdmg = (int) (atk * critDamage * rageMultiplier * penMultiplier * torrentMultiplier); + final int mcdmg = (int) (atk * critDamage * penMultiplier * pctDmgMultiplier); final int mcdmgps = (int) ((float)mcdmg*spdDiv1000); - final int dmgh = (int) ((critDamage * hp * rageMultiplier * penMultiplier * torrentMultiplier)/10); - final int dmgd = (int) ((critDamage * def * rageMultiplier * penMultiplier * torrentMultiplier)); + final int dmgh = (int) ((critDamage * hp * penMultiplier * pctDmgMultiplier)/10); + final int dmgd = (int) ((critDamage * def * penMultiplier * pctDmgMultiplier)); + + final int s1 = getSkillValue(0, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); + final int s2 = getSkillValue(1, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); + final int s3 = getSkillValue(2, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); + +// {1.871 * [(ATK)(Atkmod)(Rate)+(FlatMod)]} * (pow!)(EnhanceMod)(HitTypeMod)(ElementMod)(DamageUpMod)(TargetDebuffMod) + // flatmod + +// @Constant final float s1SelfHpScaling = 0; +// @Constant final float s1SelfAtkScaling = 0; +// @Constant final float s1SelfDefScaling = 0; +// @Constant final float s1SelfSpdScaling = 0; + +// @Constant final float s1ConstantValue = 0; +// @Constant final float s1SelfAtkConstantValue = 0; +// @Constant final float s1ConditionalIncreasedValue = 0; +// @Constant final float s1DefDiffPen = 0; +// @Constant final float s1DefDiffPenMax = 0; +// @Constant final float s1AtkDiffPen = 0; +// @Constant final float s1AtkDiffPenMax = 0; +// @Constant final float s1SpdDiffPen = 0; +// @Constant final float s1SpdDiffPenMax = 0; +// @Constant final float s1Penetration = 0; +// x @Constant final float s1AtkIncrease = 0; final int score = (int) (wScore+hScore+aScore+nScore+rScore+bScore); final int priority = (int) (wPrio+hPrio+aPrio+nPrio+rPrio+bPrio); final int upgrades = (int) (wUpg+hUpg+aUpg+nUpg+rUpg+bUpg); final int conversions = (int) (wConv+hConv+aConv+nConv+rConv+bConv); + final float bsHp = (hp - baseHp - artifactHealth - (hpSet * hpSetBonus) + (torrentSet * hpSetBonus/2)) / baseHp * 100; + final float bsAtk = (atk - baseAtk - artifactAttack - (atkSet * atkSetBonus)) / baseAtk * 100; + final float bsDef = (def - baseDef - (defSet * defSetBonus)) / baseDef * 100; + final float bsCr = (cr - baseCr - (crSet * 12)); + final float bsCd = (cd - baseCd - (cdSet * 60)); + final float bsEff = (eff - baseEff - (effSet * 20)); + final float bsRes = (res - baseRes - (resSet * 20)); + final float bsSpd = (spd - baseSpeed - (speedSet * speedSetBonus) - (revengeSet * revengeSetBonus)); + +// final float atk = ((bonusBaseAtk + wAtk+hAtk+aAtk+nAtk+rAtk+bAtk + (atkSet * atkSetBonus)) * bonusMaxAtk); +// final float hp = ((bonusBaseHp + wHp+hHp+aHp+nHp+rHp+bHp + (hpSet * hpSetBonus + torrentSet * hpSetBonus/-2)) * bonusMaxHp); +// final float def = ((bonusBaseDef + wDef+hDef+aDef+nDef+rDef+bDef + (defSet * defSetBonus)) * bonusMaxDef); +// final int cr = (int) (baseCr + wCr+hCr+aCr+nCr+rCr+bCr + (crSet * 12) + bonusCr + aeiCr); +// final int cd = (int) (baseCd + wCd+hCd+aCd+nCd+rCd+bCd + (cdSet * 60) + bonusCd + aeiCd); +// final int eff = (int) (baseEff + wEff+hEff+aEff+nEff+rEff+bEff + (effSet * 20) + bonusEff + aeiEff); +// final int res = (int) (baseRes + wRes+hRes+aRes+nRes+rRes+bRes + (resSet * 20) + bonusRes + aeiRes); +// final int spd = (int) (baseSpeed + wSpeed+hSpeed+aSpeed+nSpeed+rSpeed+bSpeed + (speedSet * speedSetBonus) + (revengeSet * revengeSetBonus) + bonusSpeed + aeiSpeed); + + final int bs = (int) (bsHp + bsAtk + bsDef + bsCr*1.6f + bsCd*1.14f + bsEff + bsRes + bsSpd*2); + final boolean f1 = atk < inputAtkMinLimit || atk > inputAtkMaxLimit || hp < inputHpMinLimit || hp > inputHpMaxLimit || def < inputDefMinLimit || def > inputDefMaxLimit @@ -614,9 +806,11 @@ public void run() { || score < inputMinScoreLimit || score > inputMaxScoreLimit; final boolean f3 = priority < inputMinPriorityLimit || priority > inputMaxPriorityLimit || upgrades < inputMinUpgradesLimit || upgrades > inputMaxUpgradesLimit - || conversions < inputMinConversionsLimit || conversions > inputMaxConversionsLimit; - - + || conversions < inputMinConversionsLimit || conversions > inputMaxConversionsLimit + || s1 < inputMinS1Limit || s1 > inputMaxS1Limit + || s2 < inputMinS2Limit || s2 > inputMaxS2Limit + || s3 < inputMinS3Limit || s3 > inputMaxS3Limit + || bs < inputMinBSLimit || bs > inputMaxBSLimit; // if (true) // return; @@ -625,6 +819,41 @@ public void run() { // passes[id] = setIndex >= 340122242; } } + + + private int getSkillValue(final int s, + final float atk, + final float def, + final float hp, + final float spd, + final float critDamage, + final float pctDmgMultiplier, + final float penSetOn) { +// final float effectiveDefense = targetDefense * targets[s] * penMultiplier +// final float realDefense = targetDefense * (penSetOn * 0.12f + 0); + final float realPenetration = (1 - penetration[s]) * (1 - penSetOn * 0.12f * targets[s]); + final float statScalings = + selfHpScaling[s] *hp + + selfAtkScaling[s]*atk + + selfDefScaling[s]*def + + selfSpdScaling[s]*spd; + final float hitTypeMultis = crit[s] * (critDamage+cdmgIncrease[s]) + hitMulti[s]; + final float increasedValueMulti = 1 + increasedValue[s]; + final float dmgUpMod = 1 + selfSpdScaling[s] * spd; + final float extraDamage = ( + extraSelfHpScaling[s] *hp + + extraSelfAtkScaling[s]*atk + + extraSelfDefScaling[s]*def) * 1.871f * 1f/(targetDefense*0.3f/300f + 1f); + final float offensiveValue = (atk * rate[s] + statScalings) * 1.871f * pow[s] * increasedValueMulti * hitTypeMultis * dmgUpMod * pctDmgMultiplier; + final float supportValue = selfHpScaling[s] * hp * support[s] + selfAtkScaling[s] * atk * support[s] + selfDefScaling[s] * def * support[s]; + final float defensiveValue = 1f/(targetDefense*max(0, realPenetration)/300f + 1f); + final int value = (int)(offensiveValue * defensiveValue + supportValue + extraDamage); + + // System.out.println("S" + (s+1) + " " + value + " " + (hitTypeMultis) + " " + (1.871f * m.getPow()[s])); + // System.out.println(m); + + return value; + } } /* diff --git a/backend/src/main/java/com/fribbels/gpu/SetFormat000OptimizerKernel.java b/backend/src/main/java/com/fribbels/gpu/SetFormat000OptimizerKernel.java index 2891e165..2c436b52 100644 --- a/backend/src/main/java/com/fribbels/gpu/SetFormat000OptimizerKernel.java +++ b/backend/src/main/java/com/fribbels/gpu/SetFormat000OptimizerKernel.java @@ -6,24 +6,24 @@ public class SetFormat000OptimizerKernel extends GpuOptimizerKernel { - public SetFormat000OptimizerKernel(final OptimizationRequest request, final float[] flattenedWeaponAccs, final float[] flattenedHelmetAccs, final float[] flattenedArmorAccs, final float[] flattenedNecklaceAccs, final float[] flattenedRingAccs, final float[] flattenedBootAccs, final float bonusBaseAtk, final float bonusBaseDef, final float bonusBaseHp, final float atkSetBonus, final float hpSetBonus, final float defSetBonus, final float speedSetBonus, final float revengeSetBonus, final float penSetDmgBonus, final float bonusMaxAtk, final float bonusMaxDef, final float bonusMaxHp, final int SETTING_RAGE_SET, final int SETTING_PEN_SET, final HeroStats base, final Hero hero, final int argSize, final int wSize, final int hSize, final int aSize, final int nSize, final int rSize, final int bSize, final int max, final int[] setSolutionBitMasks) { - super(request, flattenedWeaponAccs, flattenedHelmetAccs, flattenedArmorAccs, flattenedNecklaceAccs, flattenedRingAccs, flattenedBootAccs, bonusBaseAtk, bonusBaseDef, bonusBaseHp, atkSetBonus, hpSetBonus, defSetBonus, speedSetBonus, revengeSetBonus, penSetDmgBonus, bonusMaxAtk, bonusMaxDef, bonusMaxHp, SETTING_RAGE_SET, SETTING_PEN_SET, base, hero, argSize, wSize, hSize, aSize, nSize, rSize, bSize, max, setSolutionBitMasks); + public SetFormat000OptimizerKernel(final OptimizationRequest request, final float[] flattenedWeaponAccs, final float[] flattenedHelmetAccs, final float[] flattenedArmorAccs, final float[] flattenedNecklaceAccs, final float[] flattenedRingAccs, final float[] flattenedBootAccs, final float bonusBaseAtk, final float bonusBaseDef, final float bonusBaseHp, final float atkSetBonus, final float hpSetBonus, final float defSetBonus, final float speedSetBonus, final float revengeSetBonus, final float penSetDmgBonus, final float targetDefense, final float bonusMaxAtk, final float bonusMaxDef, final float bonusMaxHp, final int SETTING_RAGE_SET, final int SETTING_PEN_SET, final HeroStats base, final Hero hero, final long argSize, final long wSize, final long hSize, final long aSize, final long nSize, final long rSize, final long bSize, final long max, final int[] setSolutionBitMasks) { + super(request, flattenedWeaponAccs, flattenedHelmetAccs, flattenedArmorAccs, flattenedNecklaceAccs, flattenedRingAccs, flattenedBootAccs, bonusBaseAtk, bonusBaseDef, bonusBaseHp, atkSetBonus, hpSetBonus, defSetBonus, speedSetBonus, revengeSetBonus, penSetDmgBonus, targetDefense, bonusMaxAtk, bonusMaxDef, bonusMaxHp, SETTING_RAGE_SET, SETTING_PEN_SET, base, hero, argSize, wSize, hSize, aSize, nSize, rSize, bSize, max, setSolutionBitMasks); } @Override public void run() { final int id = getGlobalId(); - final long i = ((long)max) * iteration + id; - if (i < ((long)(wSize)) * hSize * aSize * nSize * rSize * bSize) { - final int b = (int)(i % bSize); - final int r = (int)(( ( i - b ) / bSize ) % rSize); - final int n = (int)(( ( i - r * bSize - b ) / (bSize * rSize) ) % nSize); - final int a = (int)(( ( i - n * rSize * bSize - r * bSize - b ) / (bSize * rSize * nSize) ) % aSize); - final int h = (int)(( ( i - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize) ) % hSize); - final int w = (int)(( ( i - h * aSize * nSize * rSize * bSize - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize * hSize) ) % wSize); + final long i = max * iteration + id; + if (i < wSize * hSize * aSize * nSize * rSize * bSize) { + final long b = i % bSize; + final long r = ( ( i - b ) / bSize ) % rSize; + final long n = ( ( i - r * bSize - b ) / (bSize * rSize) ) % nSize; + final long a = ( ( i - n * rSize * bSize - r * bSize - b ) / (bSize * rSize * nSize) ) % aSize; + final long h = ( ( i - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize) ) % hSize; + final long w = ( ( i - h * aSize * nSize * rSize * bSize - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize * hSize) ) % wSize; - final int wargSize = w * argSize; + final int wargSize = (int)(w * argSize); final float wAtk = flattenedWeaponAccs[wargSize]; final float wHp = flattenedWeaponAccs[wargSize + 1]; final float wDef = flattenedWeaponAccs[wargSize + 2]; @@ -38,7 +38,7 @@ public void run() { final float wUpg = flattenedWeaponAccs[wargSize + 14]; final float wConv = flattenedWeaponAccs[wargSize + 15]; - final int hargSize = h * argSize; + final int hargSize = (int)(h * argSize); final float hAtk = flattenedHelmetAccs[hargSize]; final float hHp = flattenedHelmetAccs[hargSize + 1]; final float hDef = flattenedHelmetAccs[hargSize + 2]; @@ -53,7 +53,7 @@ public void run() { final float hUpg = flattenedHelmetAccs[hargSize + 14]; final float hConv = flattenedHelmetAccs[hargSize + 15]; - final int aargSize = a * argSize; + final int aargSize = (int)(a * argSize); final float aAtk = flattenedArmorAccs[aargSize]; final float aHp = flattenedArmorAccs[aargSize + 1]; final float aDef = flattenedArmorAccs[aargSize + 2]; @@ -68,7 +68,7 @@ public void run() { final float aUpg = flattenedArmorAccs[aargSize + 14]; final float aConv = flattenedArmorAccs[aargSize + 15]; - final int nargSize = n * argSize; + final int nargSize = (int)(n * argSize); final float nAtk = flattenedNecklaceAccs[nargSize]; final float nHp = flattenedNecklaceAccs[nargSize + 1]; final float nDef = flattenedNecklaceAccs[nargSize + 2]; @@ -83,7 +83,7 @@ public void run() { final float nUpg = flattenedNecklaceAccs[nargSize + 14]; final float nConv = flattenedNecklaceAccs[nargSize + 15]; - final int rargSize = r * argSize; + final int rargSize = (int)(r * argSize); final float rAtk = flattenedRingAccs[rargSize]; final float rHp = flattenedRingAccs[rargSize + 1]; final float rDef = flattenedRingAccs[rargSize + 2]; @@ -98,7 +98,7 @@ public void run() { final float rUpg = flattenedRingAccs[rargSize + 14]; final float rConv = flattenedRingAccs[rargSize + 15]; - final int bargSize = b * argSize; + final int bargSize = (int)(b * argSize); final float bAtk = flattenedBootAccs[bargSize]; final float bHp = flattenedBootAccs[bargSize + 1]; final float bDef = flattenedBootAccs[bargSize + 2]; @@ -156,26 +156,52 @@ public void run() { final int cp = (int) (((atk * 1.6f + atk * 1.6f * critRate * critDamage) * (1.0 + (spd - 45f) * 0.02f) + hp + def * 9.3f) * (1f + (res/100f + eff/100f) / 4f)); - final float rageMultiplier = max(1, rageSet * SETTING_RAGE_SET * 1.3f); - final float penMultiplier = max(1, min(penSet, 1) * SETTING_PEN_SET * penSetDmgBonus); - final float torrentMultiplier = max(1, torrentSet * 0.1f + 1); + final float penSetOn = min(penSet, 1); + final float rageMultiplier = max(0, rageSet * SETTING_RAGE_SET * 0.3f); + final float penMultiplier = max(1, penSetOn * SETTING_PEN_SET * penSetDmgBonus); + final float torrentMultiplier = max(0, torrentSet * 0.1f); final float spdDiv1000 = (float)spd/1000; + final float pctDmgMultiplier = 1 + rageMultiplier + torrentMultiplier; final int ehp = (int) (hp * (def/300 + 1)); final int hpps = (int) (hp*spdDiv1000); final int ehpps = (int) ((float)ehp*spdDiv1000); - final int dmg = (int) (((critRate * atk * critDamage) + (1-critRate) * atk) * rageMultiplier * penMultiplier * torrentMultiplier); + final int dmg = (int) (((critRate * atk * critDamage) + (1-critRate) * atk) * penMultiplier * pctDmgMultiplier); final int dmgps = (int) ((float)dmg*spdDiv1000); - final int mcdmg = (int) (atk * critDamage * rageMultiplier * penMultiplier * torrentMultiplier); + final int mcdmg = (int) (atk * critDamage * penMultiplier * pctDmgMultiplier); final int mcdmgps = (int) ((float)mcdmg*spdDiv1000); - final int dmgh = (int) ((critDamage * hp * rageMultiplier * penMultiplier * torrentMultiplier)/10); - final int dmgd = (int) ((critDamage * def * rageMultiplier * penMultiplier * torrentMultiplier)); + final int dmgh = (int) ((critDamage * hp * penMultiplier * pctDmgMultiplier)/10); + final int dmgd = (int) ((critDamage * def * penMultiplier * pctDmgMultiplier)); + + final int s1 = getSkillValue(0, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); + final int s2 = getSkillValue(1, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); + final int s3 = getSkillValue(2, atk, def, hp, spd, critDamage, pctDmgMultiplier, penSetOn); final int score = (int) (wScore+hScore+aScore+nScore+rScore+bScore); final int priority = (int) (wPrio+hPrio+aPrio+nPrio+rPrio+bPrio); final int upgrades = (int) (wUpg+hUpg+aUpg+nUpg+rUpg+bUpg); final int conversions = (int) (wConv+hConv+aConv+nConv+rConv+bConv); + final float bsHp = (hp - baseHp - artifactHealth - (hpSet * hpSetBonus) + (torrentSet * hpSetBonus/2)) / baseHp * 100; + final float bsAtk = (atk - baseAtk - artifactAttack - (atkSet * atkSetBonus)) / baseAtk * 100; + final float bsDef = (def - baseDef - (defSet * defSetBonus)) / baseDef * 100; + final float bsCr = (cr - baseCr - (crSet * 12)); + final float bsCd = (cd - baseCd - (cdSet * 60)); + final float bsEff = (eff - baseEff - (effSet * 20)); + final float bsRes = (res - baseRes - (resSet * 20)); + final float bsSpd = (spd - baseSpeed - (speedSet * speedSetBonus) - (revengeSet * revengeSetBonus)); + + // final float atk = ((bonusBaseAtk + wAtk+hAtk+aAtk+nAtk+rAtk+bAtk + (atkSet * atkSetBonus)) * bonusMaxAtk); + // final float hp = ((bonusBaseHp + wHp+hHp+aHp+nHp+rHp+bHp + (hpSet * hpSetBonus + torrentSet * hpSetBonus/-2)) * bonusMaxHp); + // final float def = ((bonusBaseDef + wDef+hDef+aDef+nDef+rDef+bDef + (defSet * defSetBonus)) * bonusMaxDef); + // final int cr = (int) (baseCr + wCr+hCr+aCr+nCr+rCr+bCr + (crSet * 12) + bonusCr + aeiCr); + // final int cd = (int) (baseCd + wCd+hCd+aCd+nCd+rCd+bCd + (cdSet * 60) + bonusCd + aeiCd); + // final int eff = (int) (baseEff + wEff+hEff+aEff+nEff+rEff+bEff + (effSet * 20) + bonusEff + aeiEff); + // final int res = (int) (baseRes + wRes+hRes+aRes+nRes+rRes+bRes + (resSet * 20) + bonusRes + aeiRes); + // final int spd = (int) (baseSpeed + wSpeed+hSpeed+aSpeed+nSpeed+rSpeed+bSpeed + (speedSet * speedSetBonus) + (revengeSet * revengeSetBonus) + bonusSpeed + aeiSpeed); + + final int bs = (int) (bsHp + bsAtk + bsDef + bsCr*1.6f + bsCd*1.14f + bsEff + bsRes + bsSpd*2); + final boolean f1 = atk < inputAtkMinLimit || atk > inputAtkMaxLimit || hp < inputHpMinLimit || hp > inputHpMaxLimit || def < inputDefMinLimit || def > inputDefMaxLimit @@ -197,10 +223,47 @@ public void run() { || score < inputMinScoreLimit || score > inputMaxScoreLimit; final boolean f3 = priority < inputMinPriorityLimit || priority > inputMaxPriorityLimit || upgrades < inputMinUpgradesLimit || upgrades > inputMaxUpgradesLimit - || conversions < inputMinConversionsLimit || conversions > inputMaxConversionsLimit; - + || conversions < inputMinConversionsLimit || conversions > inputMaxConversionsLimit + || s1 < inputMinS1Limit || s1 > inputMaxS1Limit + || s2 < inputMinS2Limit || s2 > inputMaxS2Limit + || s3 < inputMinS3Limit || s3 > inputMaxS3Limit + || bs < inputMinBSLimit || bs > inputMaxBSLimit; passes[id] = !(f1 || f2 || f3); } } + + private int getSkillValue(final int s, + final float atk, + final float def, + final float hp, + final float spd, + final float critDamage, + final float pctDmgMultiplier, + final float penSetOn) { + // final float effectiveDefense = targetDefense * targets[s] * penMultiplier + // final float realDefense = targetDefense * (penSetOn * 0.12f + 0); + final float realPenetration = (1 - penetration[s]) * (1 - penSetOn * 0.12f * targets[s]); + final float statScalings = + selfHpScaling[s] *hp + + selfAtkScaling[s]*atk + + selfDefScaling[s]*def + + selfSpdScaling[s]*spd; + final float hitTypeMultis = crit[s] * (critDamage+cdmgIncrease[s]) + hitMulti[s]; + final float increasedValueMulti = 1 + increasedValue[s]; + final float dmgUpMod = 1 + selfSpdScaling[s] * spd; + final float extraDamage = ( + extraSelfHpScaling[s] *hp + + extraSelfAtkScaling[s]*atk + + extraSelfDefScaling[s]*def) * 1.871f * 1f/(targetDefense*0.3f/300f + 1f); + final float offensiveValue = (atk * rate[s] + statScalings) * 1.871f * pow[s] * increasedValueMulti * hitTypeMultis * dmgUpMod * pctDmgMultiplier; + final float supportValue = selfHpScaling[s] * hp * support[s] + selfAtkScaling[s] * atk * support[s] + selfDefScaling[s] * def * support[s]; + final float defensiveValue = 1f/(targetDefense*max(0, realPenetration)/300f + 1f); + final int value = (int)(offensiveValue * defensiveValue + supportValue + extraDamage); + + // System.out.println("S" + (s+1) + " " + value + " " + (hitTypeMultis) + " " + (1.871f * m.getPow()[s])); + // System.out.println(m); + + return value; + } } diff --git a/backend/src/main/java/com/fribbels/handler/HeroesRequestHandler.java b/backend/src/main/java/com/fribbels/handler/HeroesRequestHandler.java index 87e1dfba..e9f01d6d 100644 --- a/backend/src/main/java/com/fribbels/handler/HeroesRequestHandler.java +++ b/backend/src/main/java/com/fribbels/handler/HeroesRequestHandler.java @@ -1,28 +1,19 @@ package com.fribbels.handler; import com.fribbels.core.StatCalculator; +import com.fribbels.db.ArtifactStatsDb; import com.fribbels.db.BaseStatsDb; import com.fribbels.db.HeroDb; import com.fribbels.db.ItemDb; import com.fribbels.enums.Gear; +import com.fribbels.model.ArtifactStats; import com.fribbels.model.AugmentedStats; import com.fribbels.model.BaseStats; import com.fribbels.model.Hero; import com.fribbels.model.HeroStats; import com.fribbels.model.Item; import com.fribbels.model.Mod; -import com.fribbels.request.BaseStatsRequest; -import com.fribbels.request.BonusStatsRequest; -import com.fribbels.request.BuildsRequest; -import com.fribbels.request.EquipItemsOnHeroRequest; -import com.fribbels.request.GetAllHeroesRequest; -import com.fribbels.request.GetHeroByIdRequest; -import com.fribbels.request.HeroesRequest; -import com.fribbels.request.IdRequest; -import com.fribbels.request.IdsRequest; -import com.fribbels.request.ModStatsRequest; -import com.fribbels.request.OptimizationRequest; -import com.fribbels.request.ReorderRequest; +import com.fribbels.request.*; import com.fribbels.response.GetAllHeroesResponse; import com.fribbels.response.GetHeroByIdResponse; import com.fribbels.response.HeroStatsResponse; @@ -47,6 +38,7 @@ public class HeroesRequestHandler extends RequestHandler implements HttpHandler private final HeroDb heroDb; private final BaseStatsDb baseStatsDb; + private final ArtifactStatsDb artifactStatsDb; private final ItemDb itemDb; private StatCalculator statCalculator; @@ -106,10 +98,18 @@ public synchronized void handle(final HttpExchange exchange) throws IOException final BaseStatsRequest baseStatsRequest = parseRequest(exchange, BaseStatsRequest.class); sendResponse(exchange, setBaseStats(baseStatsRequest)); return; + case "/heroes/setArtifactStats": + final ArtifactStatsRequest artifactStatsRequest = parseRequest(exchange, ArtifactStatsRequest.class); + sendResponse(exchange, setArtifactsStats(artifactStatsRequest)); + return; case "/heroes/setBonusStats": final BonusStatsRequest bonusStatsRequest = parseRequest(exchange, BonusStatsRequest.class); sendResponse(exchange, setBonusStats(bonusStatsRequest)); return; + case "/heroes/setSkillOptions": + final SkillOptionsRequest skillOptionsRequest = parseRequest(exchange, SkillOptionsRequest.class); + sendResponse(exchange, setSkillOptions(skillOptionsRequest)); + return; case "/heroes/setModStats": final ModStatsRequest modStatsRequest = parseRequest(exchange, ModStatsRequest.class); sendResponse(exchange, setModStats(modStatsRequest)); @@ -240,6 +240,12 @@ public String setBaseStats(final BaseStatsRequest request) { return ""; } + public String setArtifactsStats(final ArtifactStatsRequest request) { + artifactStatsDb.setArtifactStatsByName(request.getArtifactStatsByName()); + + return ""; + } + public String setBonusStats(final BonusStatsRequest request) { final Hero hero = heroDb.getHeroById(request.getHeroId()); if (hero == null) return ""; @@ -249,6 +255,16 @@ public String setBonusStats(final BonusStatsRequest request) { return ""; } + public String setSkillOptions(final SkillOptionsRequest request) { + System.out.println(request); + final Hero hero = heroDb.getHeroById(request.getHeroId()); + if (hero == null) return ""; + + hero.setSkillOptions(request); + + return ""; + } + public String setModStats(final ModStatsRequest request) { final Hero hero = heroDb.getHeroById(request.getHeroId()); if (hero == null) return ""; @@ -289,6 +305,13 @@ public String getAllHeroes(final GetAllHeroesRequest request) { } } + private int parseArtifactLevel(final String artifactLevel) { + if (StringUtils.isNumeric(artifactLevel)) { + return Integer.parseInt(artifactLevel); + } + return 0; + } + private void addStatsToHero(final Hero hero, final boolean useReforgeStats) { // if ("Angelic Montmorancy".equals(hero.getName())) { // System.out.println("p"); @@ -296,6 +319,10 @@ private void addStatsToHero(final Hero hero, final boolean useReforgeStats) { final HeroStats baseStats = baseStatsDb.getBaseStatsByName(hero.getName(), hero.getStars()); + // Update artifact + final ArtifactStats artifactStats = artifactStatsDb.getArtifactStats(hero.getArtifactName(), parseArtifactLevel(hero.getArtifactLevel())); + hero.artifactHealth = artifactStats.getHealth(); + hero.artifactAttack = artifactStats.getAttack(); // Update equipment final Map equipment = hero.getEquipment(); @@ -352,6 +379,11 @@ private void clearNullBuilds(final Hero hero, final boolean useReforgeStats) { } public boolean addStatsToBuild(final Hero hero, final HeroStats baseStats, final HeroStats build, final boolean useReforgeStats) { + // Update artifact + final ArtifactStats artifactStats = artifactStatsDb.getArtifactStats(hero.getArtifactName(), parseArtifactLevel(hero.getArtifactLevel())); + hero.artifactHealth = artifactStats.getHealth(); + hero.artifactAttack = artifactStats.getAttack(); + final List itemIds = build.getItems(); final List items = itemDb.getItemsById(itemIds); for (final Item item : items) { @@ -415,8 +447,12 @@ public boolean addStatsToBuild(final Hero hero, final HeroStats baseStats, final build.mcdmgps = finalStats.mcdmgps; build.dmgh = finalStats.dmgh; build.dmgd = finalStats.dmgd; + build.s1 = finalStats.s1; + build.s2 = finalStats.s2; + build.s3 = finalStats.s3; build.upgrades = finalStats.upgrades; build.score = finalStats.score; + build.bs = finalStats.bs; build.priority = finalStats.priority; build.conversions = finalStats.conversions; diff --git a/backend/src/main/java/com/fribbels/handler/ItemsRequestHandler.java b/backend/src/main/java/com/fribbels/handler/ItemsRequestHandler.java index f52da3c6..7f50bcea 100644 --- a/backend/src/main/java/com/fribbels/handler/ItemsRequestHandler.java +++ b/backend/src/main/java/com/fribbels/handler/ItemsRequestHandler.java @@ -135,9 +135,7 @@ public String mergeItems(final MergeRequest request) { if (ingameId != null && itemsByIngameId.containsKey(ingameId) && itemsByHash.containsKey(item.getHash())) { final List matchingItems = itemsByHash.get(item.getHash()); - if (matchingItems == null) { - System.out.println("1"); - } + matchingItems.add(item); continue; } else { diff --git a/backend/src/main/java/com/fribbels/handler/OptimizationRequestHandler.java b/backend/src/main/java/com/fribbels/handler/OptimizationRequestHandler.java index f27a9ca8..01d4bdac 100644 --- a/backend/src/main/java/com/fribbels/handler/OptimizationRequestHandler.java +++ b/backend/src/main/java/com/fribbels/handler/OptimizationRequestHandler.java @@ -367,7 +367,7 @@ public String handleOptimizationFilterRequest(final OptimizationRequest request) } } - System.out.println("Indices count: " + count); +// System.out.println("Indices count: " + count); optimizationDb.setFilteredIds(ids, count); return ""; @@ -392,7 +392,11 @@ private boolean passesUpdatedFilter(final OptimizationRequest request, final Her || heroStats.getMcdmgps() < request.getInputMinMcdmgpsLimit() || heroStats.getMcdmgps() > request.getInputMaxMcdmgpsLimit() || heroStats.getDmgh() < request.getInputMinDmgHLimit() || heroStats.getDmgh() > request.getInputMaxDmgHLimit() || heroStats.getDmgd() < request.getInputMinDmgDLimit() || heroStats.getDmgd() > request.getInputMaxDmgDLimit() + || heroStats.getS1() < request.getInputMinS1Limit() || heroStats.getS1() > request.getInputMaxS1Limit() + || heroStats.getS2() < request.getInputMinS2Limit() || heroStats.getS2() > request.getInputMaxS2Limit() + || heroStats.getS3() < request.getInputMinS3Limit() || heroStats.getS3() > request.getInputMaxS3Limit() || heroStats.getScore() < request.getInputMinScoreLimit() || heroStats.getScore() > request.getInputMaxScoreLimit() + || heroStats.getBs() < request.getInputMinBSLimit() || heroStats.getBs() > request.getInputMaxBSLimit() || heroStats.getPriority() < request.getInputMinPriorityLimit() || heroStats.getPriority() > request.getInputMaxPriorityLimit() || heroStats.getUpgrades() < request.getInputMinUpgradesLimit() || heroStats.getUpgrades() > request.getInputMaxUpgradesLimit() || heroStats.getConversions() < request.getInputMinConversionsLimit() || heroStats.getConversions() > request.getInputMaxConversionsLimit() @@ -499,7 +503,7 @@ private String handleEditResultRowsRequest(final EditResultRowsRequest request) final HeroStats heroStat = heroStats[0]; heroStat.setProperty(request.getProperty()); - System.out.println(heroStat); +// System.out.println(heroStat); return ""; } @@ -603,12 +607,12 @@ public String optimize(final OptimizationRequest request, final HeroStats unused searchedCounter = new AtomicLong(0); resultsCounter = new AtomicLong(0); - final int wSize = itemsByGear.get(Gear.WEAPON).size(); - final int hSize = itemsByGear.get(Gear.HELMET).size(); - final int aSize = itemsByGear.get(Gear.ARMOR).size(); - final int nSize = itemsByGear.get(Gear.NECKLACE).size(); - final int rSize = itemsByGear.get(Gear.RING).size(); - final int bSize = itemsByGear.get(Gear.BOOTS).size(); + final long wSize = itemsByGear.get(Gear.WEAPON).size(); + final long hSize = itemsByGear.get(Gear.HELMET).size(); + final long aSize = itemsByGear.get(Gear.ARMOR).size(); + final long nSize = itemsByGear.get(Gear.NECKLACE).size(); + final long rSize = itemsByGear.get(Gear.RING).size(); + final long bSize = itemsByGear.get(Gear.BOOTS).size(); final Item[] allweapons = itemsByGear.get(Gear.WEAPON).toArray(new Item[0]); final Item[] allhelmets = itemsByGear.get(Gear.HELMET).toArray(new Item[0]); @@ -671,10 +675,17 @@ public String optimize(final OptimizationRequest request, final HeroStats unused final int SETTING_RAGE_SET = StatCalculator.SETTING_RAGE_SET ? 1 : 0; final int SETTING_PEN_SET = StatCalculator.SETTING_PEN_SET ? 1 : 0; - final long maxPerms = ((long)wSize) * hSize * aSize * nSize * rSize * bSize; + final long maxPerms = wSize * hSize * aSize * nSize * rSize * bSize; final GpuOptimizerKernel kernel; + hero.setDamageMultipliers(request.damageMultipliers); + +// System.out.println(); + +// System.out.println("multis"); +// System.out.println(request.damageMultipliers.toString()); + if (SETTING_GPU && canUseGpu && maxPerms >= 20_000_000) { // GPU Optimize @@ -698,6 +709,7 @@ public String optimize(final OptimizationRequest request, final HeroStats unused speedSetBonus, revengeSetBonus, penSetDmgBonus, + StatCalculator.SETTING_PEN_DEFENSE, bonusMaxAtk, bonusMaxDef, bonusMaxHp, @@ -808,67 +820,70 @@ public String optimize(final OptimizationRequest request, final HeroStats unused executorService.submit(() -> { + try { + searchedCounter.addAndGet(Math.min(max, maxPerms)); - searchedCounter.addAndGet(Math.min(max, maxPerms)); - - for (int j = 0; j < max; j++) { - final long iteration = ((long) finalI) * max + j; + for (int j = 0; j < max; j++) { + final long iteration = ((long) finalI) * max + j; - // System.out.println(longSetMasks[0]); - // System.out.println(debug[j]); + // System.out.println(longSetMasks[0]); + // System.out.println(debug[j]); - if (passes[j]) { - if (iteration >= maxPerms) { - break; - } - if (Main.interrupt || exit.get()) { - break; - } + if (passes[j]) { + if (iteration >= maxPerms) { + break; + } + if (Main.interrupt || exit.get()) { + break; + } - final int b = (int) (iteration % bSize); - final int r = (int) (((iteration - b) / bSize) % rSize); - final int n = (int) (((iteration - r * bSize - b) / (bSize * rSize)) % nSize); - final int a = (int) (((iteration - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize)) % aSize); - final int h = (int) (((iteration - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize)) % hSize); - final int w = (int) (((iteration - h * aSize * nSize * rSize * bSize - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize * hSize)) % wSize); - - final Item weapon = allweapons[w]; - final Item helmet = allhelmets[h]; - final Item armor = allarmors[a]; - final Item necklace = allnecklaces[n]; - final Item ring = allrings[r]; - final Item boots = allboots[b]; - - final Item[] collectedItems = new Item[]{weapon, helmet, armor, necklace, ring, boots}; - final int[] collectedSets = statCalculator.buildSetsArr(collectedItems); - - final int reforges = weapon.upgradeable + helmet.upgradeable + armor.upgradeable + necklace.upgradeable + ring.upgradeable + boots.upgradeable; - final int conversions = weapon.convertable + helmet.convertable + armor.convertable + necklace.convertable + ring.convertable + boots.convertable; - final int priority = weapon.priority + helmet.priority + armor.priority + necklace.priority + ring.priority + boots.priority; - final HeroStats result = statCalculator.addAccumulatorArrsToHero(base, new float[][]{weapon.tempStatAccArr, helmet.tempStatAccArr, armor.tempStatAccArr, necklace.tempStatAccArr, ring.tempStatAccArr, boots.tempStatAccArr}, collectedSets, request.hero, reforges, conversions, priority); - - result.setSets(collectedSets); - result.setItems(ImmutableList.of(allweapons[w].getId(), allhelmets[h].getId(), allarmors[a] - .getId(), allnecklaces[n].id, allrings[r].id, allboots[b].id)); - result.setModIds(ImmutableList.of(allweapons[w].getModId(), allhelmets[h].getModId(), allarmors[a] - .getModId(), allnecklaces[n].modId, allrings[r].modId, allboots[b].modId)); - result.setMods(Lists.newArrayList(allweapons[w].getMod(), allhelmets[h].getMod(), allarmors[a] - .getMod(), allnecklaces[n].getMod(), allrings[r].getMod(), allboots[b].getMod())); - - final long resultsIndex = resultsCounter.getAndIncrement(); - result.setId("" + resultsIndex); - resultHeroStats[(int) resultsIndex] = result; - - if (resultsIndex >= MAXIMUM_RESULTS - 1) { - maxReached.set(MAXIMUM_RESULTS - 1); - exit.set(true); - break; + final int b = (int) (iteration % bSize); + final int r = (int) (((iteration - b) / bSize) % rSize); + final int n = (int) (((iteration - r * bSize - b) / (bSize * rSize)) % nSize); + final int a = (int) (((iteration - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize)) % aSize); + final int h = (int) (((iteration - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize)) % hSize); + final int w = (int) (((iteration - h * aSize * nSize * rSize * bSize - a * nSize * rSize * bSize - n * rSize * bSize - r * bSize - b) / (bSize * rSize * nSize * aSize * hSize)) % wSize); + + final Item weapon = allweapons[w]; + final Item helmet = allhelmets[h]; + final Item armor = allarmors[a]; + final Item necklace = allnecklaces[n]; + final Item ring = allrings[r]; + final Item boots = allboots[b]; + + final Item[] collectedItems = new Item[]{weapon, helmet, armor, necklace, ring, boots}; + final int[] collectedSets = statCalculator.buildSetsArr(collectedItems); + + final int reforges = weapon.upgradeable + helmet.upgradeable + armor.upgradeable + necklace.upgradeable + ring.upgradeable + boots.upgradeable; + final int conversions = weapon.convertable + helmet.convertable + armor.convertable + necklace.convertable + ring.convertable + boots.convertable; + final int priority = weapon.priority + helmet.priority + armor.priority + necklace.priority + ring.priority + boots.priority; + final HeroStats result = statCalculator.addAccumulatorArrsToHero(base, new float[][]{weapon.tempStatAccArr, helmet.tempStatAccArr, armor.tempStatAccArr, necklace.tempStatAccArr, ring.tempStatAccArr, boots.tempStatAccArr}, collectedSets, request.hero, reforges, conversions, priority); + + result.setSets(collectedSets); + result.setItems(ImmutableList.of(allweapons[w].getId(), allhelmets[h].getId(), allarmors[a] + .getId(), allnecklaces[n].id, allrings[r].id, allboots[b].id)); + result.setModIds(ImmutableList.of(allweapons[w].getModId(), allhelmets[h].getModId(), allarmors[a] + .getModId(), allnecklaces[n].modId, allrings[r].modId, allboots[b].modId)); + result.setMods(Lists.newArrayList(allweapons[w].getMod(), allhelmets[h].getMod(), allarmors[a] + .getMod(), allnecklaces[n].getMod(), allrings[r].getMod(), allboots[b].getMod())); + + final long resultsIndex = resultsCounter.getAndIncrement(); + result.setId("" + resultsIndex); + resultHeroStats[(int) resultsIndex] = result; + + if (resultsIndex >= MAXIMUM_RESULTS - 1) { + maxReached.set(MAXIMUM_RESULTS - 1); + exit.set(true); + break; + } } } - } - passesPool.get(passesId).setLocked(false); - executionCounter.decrementAndGet(); + passesPool.get(passesId).setLocked(false); + executionCounter.decrementAndGet(); + } catch (final Exception e) { + e.printStackTrace(); + } }); } @@ -1039,10 +1054,6 @@ public String optimize(final OptimizationRequest request, final HeroStats unused return ""; } - public void optimizeKernel() { - - } - public int[] convertSetsArrayIntoIndexArray(final int[] sets) { final int[] output = new int[]{0, 0, 0, 0, 0, 0}; int count = 0; @@ -1088,7 +1099,11 @@ public boolean passesFilter(final HeroStats heroStats, final OptimizationRequest || heroStats.mcdmgps < request.inputMinMcdmgpsLimit || heroStats.mcdmgps > request.inputMaxMcdmgpsLimit || heroStats.dmgh < request.inputMinDmgHLimit || heroStats.dmgh > request.inputMaxDmgHLimit || heroStats.dmgd < request.inputMinDmgDLimit || heroStats.dmgd > request.inputMaxDmgDLimit + || heroStats.s1 < request.inputMinS1Limit || heroStats.s1 > request.inputMaxS1Limit + || heroStats.s2 < request.inputMinS2Limit || heroStats.s2 > request.inputMaxS2Limit + || heroStats.s3 < request.inputMinS3Limit || heroStats.s3 > request.inputMaxS3Limit || heroStats.score < request.inputMinScoreLimit || heroStats.score > request.inputMaxScoreLimit + || heroStats.bs < request.inputMinBSLimit || heroStats.bs > request.inputMaxBSLimit || heroStats.priority < request.inputMinPriorityLimit || heroStats.priority > request.inputMaxPriorityLimit || heroStats.upgrades < request.inputMinUpgradesLimit || heroStats.upgrades > request.inputMaxUpgradesLimit || heroStats.conversions < request.inputMinConversionsLimit || heroStats.conversions > request.inputMaxConversionsLimit @@ -1394,6 +1409,7 @@ public static GpuOptimizerKernel selectKernel( final float speedSetBonus, final float revengeSetBonus, final float penSetDmgBonus, + final float targetDefense, final float bonusMaxAtk, final float bonusMaxDef, final float bonusMaxHp, @@ -1401,14 +1417,14 @@ public static GpuOptimizerKernel selectKernel( final int SETTING_PEN_SET, final HeroStats base, final Hero hero, - final int argSize, - final int wSize, - final int hSize, - final int aSize, - final int nSize, - final int rSize, - final int bSize, - final int max, + final long argSize, + final long wSize, + final long hSize, + final long aSize, + final long nSize, + final long rSize, + final long bSize, + final long max, final int[] longSetMasks ) { if (request.getSetFormat() == 0) { @@ -1429,6 +1445,7 @@ public static GpuOptimizerKernel selectKernel( speedSetBonus, revengeSetBonus, penSetDmgBonus, + targetDefense, bonusMaxAtk, bonusMaxDef, bonusMaxHp, @@ -1464,6 +1481,7 @@ public static GpuOptimizerKernel selectKernel( speedSetBonus, revengeSetBonus, penSetDmgBonus, + targetDefense, bonusMaxAtk, bonusMaxDef, bonusMaxHp, diff --git a/backend/src/main/java/com/fribbels/model/ArtifactStats.java b/backend/src/main/java/com/fribbels/model/ArtifactStats.java new file mode 100644 index 00000000..18a43330 --- /dev/null +++ b/backend/src/main/java/com/fribbels/model/ArtifactStats.java @@ -0,0 +1,14 @@ +package com.fribbels.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +@Getter +@Builder +@ToString +public class ArtifactStats { + + private final Float attack; + private final Float health; +} diff --git a/backend/src/main/java/com/fribbels/model/BaseStats.java b/backend/src/main/java/com/fribbels/model/BaseStats.java index b9905e0c..fba0ab7f 100644 --- a/backend/src/main/java/com/fribbels/model/BaseStats.java +++ b/backend/src/main/java/com/fribbels/model/BaseStats.java @@ -11,4 +11,5 @@ public class BaseStats { private final HeroStats lv50FiveStarFullyAwakened; private final HeroStats lv60SixStarFullyAwakened; + private final HeroSkills skills; } diff --git a/backend/src/main/java/com/fribbels/model/DamageMultipliers.java b/backend/src/main/java/com/fribbels/model/DamageMultipliers.java new file mode 100644 index 00000000..f2980e5f --- /dev/null +++ b/backend/src/main/java/com/fribbels/model/DamageMultipliers.java @@ -0,0 +1,50 @@ +package com.fribbels.model; + +import com.aparapi.Kernel; +import com.fribbels.enums.Gear; +import com.fribbels.enums.Rank; +import com.fribbels.enums.Set; +import com.google.gson.Gson; +import lombok.*; + +import java.util.List; + +@Getter +@Setter +@Builder +@ToString +@AllArgsConstructor +@RequiredArgsConstructor +@EqualsAndHashCode +public class DamageMultipliers { + + private Float[] rate = new Float[]{1f, 1f, 1f}; + private Float[] pow = new Float[]{1f, 1f, 1f}; + private Integer[] targets = new Integer[]{0, 0, 0}; + + private Float[] selfHpScaling = new Float[]{1f, 1f, 1f}; + private Float[] selfAtkScaling = new Float[]{1f, 1f, 1f}; + private Float[] selfDefScaling = new Float[]{1f, 1f, 1f}; + private Float[] selfSpdScaling = new Float[]{1f, 1f, 1f}; + private Float[] constantValue = new Float[]{1f, 1f, 1f}; + private Float[] selfAtkConstantValue = new Float[]{1f, 1f, 1f}; + private Float[] increasedValue = new Float[]{1f, 1f, 1f}; + private Float[] defDiffPen = new Float[]{1f, 1f, 1f}; + private Float[] defDiffPenMax = new Float[]{1f, 1f, 1f}; + private Float[] atkDiffPen = new Float[]{1f, 1f, 1f}; + private Float[] atkDiffPenMax = new Float[]{1f, 1f, 1f}; + private Float[] spdDiffPen = new Float[]{1f, 1f, 1f}; + private Float[] spdDiffPenMax = new Float[]{1f, 1f, 1f}; + private Float[] penetration = new Float[]{0f, 0f, 0f}; + private Float[] atkIncrease = new Float[]{1f, 1f, 1f}; + private Float[] cdmgIncrease = new Float[]{1f, 1f, 1f}; + private Float[] crit = new Float[]{1f, 1f, 1f}; + private Float[] damage = new Float[]{1f, 1f, 1f}; + private Float[] support = new Float[]{1f, 1f, 1f}; + private Float[] hitMulti = new Float[]{1f, 1f, 1f}; + + private Float[] extraSelfAtkScaling = new Float[]{1f, 1f, 1f}; + private Float[] extraSelfDefScaling = new Float[]{1f, 1f, 1f}; + private Float[] extraSelfHpScaling = new Float[]{1f, 1f, 1f}; + +} diff --git a/backend/src/main/java/com/fribbels/model/Hero.java b/backend/src/main/java/com/fribbels/model/Hero.java index ccd79dbc..cac828cb 100644 --- a/backend/src/main/java/com/fribbels/model/Hero.java +++ b/backend/src/main/java/com/fribbels/model/Hero.java @@ -5,13 +5,17 @@ import com.fribbels.request.BonusStatsRequest; import com.fribbels.request.ModStatsRequest; import com.fribbels.request.OptimizationRequest; +import com.fribbels.request.SkillOptionsRequest; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.Setter; import lombok.ToString; import lombok.experimental.Wither; +import org.apache.commons.lang3.StringUtils; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -44,8 +48,13 @@ public class Hero { public int dmgh; public int dmgd; + public int s1; + public int s2; + public int s3; + public int upgrades; public int score; + public int bs; public int priority; public int conversions; @@ -81,6 +90,9 @@ public class Hero { public float aeiEff; public float aeiRes; + public float artifactAttack; + public float artifactHealth; + public String artifactName; public String artifactLevel; public String imprintNumber; @@ -107,6 +119,102 @@ public class Hero { private OptimizationRequest optimizationRequest; + private HeroSkillOptions skillOptions; + private DamageMultipliers damageMultipliers; + private HeroSkills skills; + + public DamageMultipliers getDamageMultipliers() { + if (damageMultipliers != null) { + return damageMultipliers; + } + if (skills == null) { + skills = HeroSkills.builder() + .S1(new SkillData[]{SkillData.builder().build(), SkillData.builder().build(), SkillData.builder().build()}) + .S2(new SkillData[]{SkillData.builder().build(), SkillData.builder().build(), SkillData.builder().build()}) + .S3(new SkillData[]{SkillData.builder().build(), SkillData.builder().build(), SkillData.builder().build()}) + .build(); + } + if (skillOptions == null) { + return DamageMultipliers.builder() + .rate(new Float[]{skills.S1[0].rate, skills.S2[0].rate, skills.S3[0].rate}) + .pow(new Float[]{skills.S1[0].pow, skills.S2[0].pow, skills.S3[0].pow}) + .targets(new Integer[]{skills.S1[0].targets, skills.S2[0].targets, skills.S3[0].targets}) + .selfHpScaling(new Float[]{skills.S1[0].selfHpScaling, skills.S2[0].selfHpScaling, skills.S3[0].selfHpScaling}) + .selfAtkScaling(new Float[]{skills.S1[0].selfAtkScaling, skills.S2[0].selfAtkScaling, skills.S3[0].selfAtkScaling}) + .selfDefScaling(new Float[]{skills.S1[0].selfDefScaling, skills.S2[0].selfDefScaling, skills.S3[0].selfDefScaling}) + .selfSpdScaling(new Float[]{skills.S1[0].selfSpdScaling, skills.S2[0].selfSpdScaling, skills.S3[0].selfSpdScaling}) + .increasedValue(new Float[]{skills.S1[0].increasedValue, skills.S2[0].increasedValue, skills.S3[0].increasedValue}) + .extraSelfHpScaling(new Float[]{skills.S1[0].extraSelfHpScaling, skills.S2[0].extraSelfHpScaling, skills.S3[0].extraSelfHpScaling}) + .extraSelfDefScaling(new Float[]{skills.S1[0].extraSelfDefScaling, skills.S2[0].extraSelfDefScaling, skills.S3[0].extraSelfDefScaling}) + .extraSelfAtkScaling(new Float[]{skills.S1[0].extraSelfAtkScaling, skills.S2[0].extraSelfAtkScaling, skills.S3[0].extraSelfAtkScaling}) + .cdmgIncrease(new Float[]{skills.S1[0].cdmgIncrease, skills.S2[0].cdmgIncrease, skills.S3[0].cdmgIncrease}) + .penetration(new Float[]{skills.S1[0].penetration, skills.S2[0].penetration, skills.S3[0].penetration}) + .hitMulti(new Float[]{calculateHitMulti(0, skills.S1[0].name), calculateHitMulti(1, skills.S2[0].name), calculateHitMulti(2, skills.S3[0].name)}) + .support( new Float[]{calculateSupport(0, skills.S1[0].name), calculateSupport(1, skills.S2[0].name), calculateSupport(2, skills.S3[0].name)}) + .crit( new Float[]{calculateCrit(0, skills.S1[0].name), calculateCrit(1, skills.S2[0].name), calculateCrit(2, skills.S3[0].name)}) + .build(); + } else { + final SkillData s1 = Arrays.stream(skills.S1).filter(x -> StringUtils.equals(x.name, skillOptions.getS1().skillEffect)).findFirst().orElse(skills.S1[0]); + final SkillData s2 = Arrays.stream(skills.S2).filter(x -> StringUtils.equals(x.name, skillOptions.getS2().skillEffect)).findFirst().orElse(skills.S2[0]); + final SkillData s3 = Arrays.stream(skills.S3).filter(x -> StringUtils.equals(x.name, skillOptions.getS3().skillEffect)).findFirst().orElse(skills.S3[0]); + return DamageMultipliers.builder() + .rate(new Float[]{s1.rate, s2.rate, s3.rate}) + .pow(new Float[]{s1.pow, s2.pow, s3.pow}) + .targets(new Integer[]{s1.targets, s2.targets, s3.targets}) + .selfHpScaling(new Float[]{s1.selfHpScaling, s2.selfHpScaling, s3.selfHpScaling}) + .selfAtkScaling(new Float[]{s1.selfAtkScaling, s2.selfAtkScaling, s3.selfAtkScaling}) + .selfDefScaling(new Float[]{s1.selfDefScaling, s2.selfDefScaling, s3.selfDefScaling}) + .selfSpdScaling(new Float[]{s1.selfSpdScaling, s2.selfSpdScaling, s3.selfSpdScaling}) + .increasedValue(new Float[]{s1.increasedValue, s2.increasedValue, s3.increasedValue}) + .extraSelfHpScaling(new Float[]{s1.extraSelfHpScaling, s2.extraSelfHpScaling, s3.extraSelfHpScaling}) + .extraSelfDefScaling(new Float[]{s1.extraSelfDefScaling, s2.extraSelfDefScaling, s3.extraSelfDefScaling}) + .extraSelfAtkScaling(new Float[]{s1.extraSelfAtkScaling, s2.extraSelfAtkScaling, s3.extraSelfAtkScaling}) + .cdmgIncrease(new Float[]{s1.cdmgIncrease, s2.cdmgIncrease, s3.cdmgIncrease}) + .penetration(new Float[]{s1.penetration, s2.penetration, s3.penetration}) + .hitMulti(new Float[]{calculateHitMulti(0, getSkillOptionsByIndex(0).skillEffect), calculateHitMulti(1, getSkillOptionsByIndex(1).skillEffect), calculateHitMulti(2, getSkillOptionsByIndex(2).skillEffect)}) + .support(new Float[]{calculateSupport(0, getSkillOptionsByIndex(0).skillEffect), calculateSupport(1, getSkillOptionsByIndex(1).skillEffect), calculateSupport(2, getSkillOptionsByIndex(2).skillEffect)}) + .crit(new Float[]{calculateCrit(0, getSkillOptionsByIndex(0).skillEffect), calculateCrit(1, getSkillOptionsByIndex(1).skillEffect), calculateCrit(2, getSkillOptionsByIndex(2).skillEffect)}) + .build(); + } + } + + private SingleSkillOptions getSkillOptionsByIndex(final int skill) { + if (skill == 0) return skillOptions.S1; + if (skill == 1) return skillOptions.S2; + return skillOptions.S3; + } + + private float calculateSupport(final int skill, final String name) { + if (StringUtils.contains(name, "heal") || + StringUtils.contains(name, "barrier")) { + return 1f; + } + return 0f; + } + + private float calculateCrit(final int skill, final String name) { + if (StringUtils.contains(name, "crit")) { + return 1f; + } + return 0f; + } + + private Float calculateHitMulti(final int skill, final String name) { + if (StringUtils.contains(name, "crit")) { + return 0f; + } + if (StringUtils.contains(name, "crushing")) { + return 1.3f; + } + if (StringUtils.contains(name, "normal")) { + return 1f; + } + if (StringUtils.contains(name, "miss")) { + return 0.75f; + } + return 0f; + } + public Item switchItem(final Item item) { final Gear gear = item.getGear(); final Item previousItem = addToEquipment(gear, item); @@ -161,6 +269,9 @@ public void setBonusStats(final BonusStatsRequest bonusStats) { this.aeiEff = bonusStats.getAeiEff(); this.aeiRes = bonusStats.getAeiRes(); + this.artifactAttack = bonusStats.getArtifactAttack(); + this.artifactHealth = bonusStats.getArtifactHealth(); + this.artifactName = bonusStats.getArtifactName(); this.artifactLevel = bonusStats.getArtifactLevel(); this.imprintNumber = bonusStats.getImprintNumber(); @@ -169,6 +280,10 @@ public void setBonusStats(final BonusStatsRequest bonusStats) { this.stars = bonusStats.getStars(); } + public void setSkillOptions(final SkillOptionsRequest request) { + this.skillOptions = request.getSkillOptions(); + } + public Map getEquipment() { if (equipment == null) { equipment = new HashMap<>(); @@ -201,8 +316,13 @@ public void setStats(final HeroStats heroStats) { this.dmgh = heroStats.getDmgh(); this.dmgd = heroStats.getDmgd(); + this.s1 = heroStats.getS1(); + this.s2 = heroStats.getS2(); + this.s3 = heroStats.getS3(); + this.upgrades = heroStats.getUpgrades(); this.score = heroStats.getScore(); + this.bs = heroStats.getBs(); this.priority = heroStats.getPriority(); this.conversions = heroStats.getConversions(); } diff --git a/backend/src/main/java/com/fribbels/model/HeroSkillOptions.java b/backend/src/main/java/com/fribbels/model/HeroSkillOptions.java new file mode 100644 index 00000000..f0e13bc5 --- /dev/null +++ b/backend/src/main/java/com/fribbels/model/HeroSkillOptions.java @@ -0,0 +1,21 @@ +package com.fribbels.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class HeroSkillOptions { + + public SingleSkillOptions S1; + public SingleSkillOptions S2; + public SingleSkillOptions S3; +} diff --git a/backend/src/main/java/com/fribbels/model/HeroSkills.java b/backend/src/main/java/com/fribbels/model/HeroSkills.java new file mode 100644 index 00000000..08ae5d30 --- /dev/null +++ b/backend/src/main/java/com/fribbels/model/HeroSkills.java @@ -0,0 +1,21 @@ +package com.fribbels.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class HeroSkills { + + public SkillData[] S1; + public SkillData[] S2; + public SkillData[] S3; +} diff --git a/backend/src/main/java/com/fribbels/model/HeroStats.java b/backend/src/main/java/com/fribbels/model/HeroStats.java index c72aea29..2262cbbd 100644 --- a/backend/src/main/java/com/fribbels/model/HeroStats.java +++ b/backend/src/main/java/com/fribbels/model/HeroStats.java @@ -41,9 +41,14 @@ public class HeroStats { public int dmgh; public int dmgd; + public int s1; + public int s2; + public int s3; + public int upgrades; public int conversions; public int score; + public int bs; public int priority; public BonusStats bonusStats; diff --git a/backend/src/main/java/com/fribbels/model/Mod.java b/backend/src/main/java/com/fribbels/model/Mod.java index a33274bd..85bfca94 100644 --- a/backend/src/main/java/com/fribbels/model/Mod.java +++ b/backend/src/main/java/com/fribbels/model/Mod.java @@ -20,7 +20,7 @@ public class Mod { private Integer index; public String toString() { - System.out.println(new Gson().toJson(this)); +// System.out.println(new Gson().toJson(this)); return new Gson().toJson(this); } diff --git a/backend/src/main/java/com/fribbels/model/SingleSkillOptions.java b/backend/src/main/java/com/fribbels/model/SingleSkillOptions.java new file mode 100644 index 00000000..f9998143 --- /dev/null +++ b/backend/src/main/java/com/fribbels/model/SingleSkillOptions.java @@ -0,0 +1,39 @@ +package com.fribbels.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class SingleSkillOptions { + + public Float attackImprintPercent; + public Float attackIncreasePercent; + public Float damageIncreasePercent; + public Boolean elementalAdvantageEnabled; + public Boolean decreasedAttackBuffEnabled; + public Boolean attackBuffEnabled; + public Boolean greaterAttackBuffEnabled; + public Boolean critDamageBuffEnabled; + public Boolean vigorAttackBuffEnabled; + + public String skillEffect; + public Boolean applyToAllSkills; + + public Integer targetDefense; + public Float targetDefenseIncreasePercent; + public Float targetDamageReductionPercent; + public Float targetDamageTransferPercent; + public Boolean targetDefenseBuffEnabled; + public Boolean targetVigorDefenseBuffEnabled; + public Boolean targetDefenseBreakBuffEnabled; + public Boolean targetTargetBuffEnabled; +} diff --git a/backend/src/main/java/com/fribbels/model/SkillData.java b/backend/src/main/java/com/fribbels/model/SkillData.java new file mode 100644 index 00000000..3b59146d --- /dev/null +++ b/backend/src/main/java/com/fribbels/model/SkillData.java @@ -0,0 +1,31 @@ +package com.fribbels.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class SkillData { + + public String name; + public Float rate = 0f; + public Float pow = 0f; + public Integer targets = 0; + public Float selfHpScaling = 0f; + public Float selfAtkScaling = 0f; + public Float selfDefScaling = 0f; + public Float selfSpdScaling = 0f; + public Float increasedValue = 0f; + public Float extraSelfHpScaling = 0f; + public Float extraSelfDefScaling = 0f; + public Float extraSelfAtkScaling = 0f; + public Float cdmgIncrease = 0f; + public Float penetration = 0f;} diff --git a/backend/src/main/java/com/fribbels/request/ArtifactStatsRequest.java b/backend/src/main/java/com/fribbels/request/ArtifactStatsRequest.java new file mode 100644 index 00000000..b083e081 --- /dev/null +++ b/backend/src/main/java/com/fribbels/request/ArtifactStatsRequest.java @@ -0,0 +1,21 @@ +package com.fribbels.request; + +import com.fribbels.model.ArtifactStats; +import com.fribbels.model.BaseStats; +import com.fribbels.model.HeroStats; +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.Map; + +@Setter +@Getter +@Builder +@ToString +public class ArtifactStatsRequest extends Request { + + final Map artifactStatsByName; +} diff --git a/backend/src/main/java/com/fribbels/request/BonusStatsRequest.java b/backend/src/main/java/com/fribbels/request/BonusStatsRequest.java index b80ae440..85346dd6 100644 --- a/backend/src/main/java/com/fribbels/request/BonusStatsRequest.java +++ b/backend/src/main/java/com/fribbels/request/BonusStatsRequest.java @@ -36,6 +36,9 @@ public class BonusStatsRequest extends Request { private float aeiEff; private float aeiRes; + private float artifactAttack; + private float artifactHealth; + private String artifactName; private String artifactLevel; private String imprintNumber; diff --git a/backend/src/main/java/com/fribbels/request/OptimizationRequest.java b/backend/src/main/java/com/fribbels/request/OptimizationRequest.java index 1b4fccdb..33898e00 100644 --- a/backend/src/main/java/com/fribbels/request/OptimizationRequest.java +++ b/backend/src/main/java/com/fribbels/request/OptimizationRequest.java @@ -2,6 +2,7 @@ import com.fribbels.enums.Set; import com.fribbels.enums.StatType; +import com.fribbels.model.DamageMultipliers; import com.fribbels.model.Hero; import com.fribbels.model.Item; import com.fribbels.model.Request; @@ -28,6 +29,7 @@ public class OptimizationRequest extends Request { private String heroId; public Hero hero; + public DamageMultipliers damageMultipliers; private List items; private List> inputSets; @@ -61,6 +63,9 @@ public class OptimizationRequest extends Request { private int spd; private int dac; + private float artifactAttack; + private float artifactHealth; + public int inputAtkMinLimit; public int inputAtkMaxLimit = Integer.MAX_VALUE; public int inputHpMinLimit; @@ -98,12 +103,22 @@ public class OptimizationRequest extends Request { public int inputMaxDmgHLimit = Integer.MAX_VALUE; public int inputMinDmgDLimit; public int inputMaxDmgDLimit = Integer.MAX_VALUE; + + public int inputMinS1Limit; + public int inputMaxS1Limit = Integer.MAX_VALUE; + public int inputMinS2Limit; + public int inputMaxS2Limit = Integer.MAX_VALUE; + public int inputMinS3Limit; + public int inputMaxS3Limit = Integer.MAX_VALUE; + public int inputMinUpgradesLimit; public int inputMaxUpgradesLimit = Integer.MAX_VALUE; public int inputMinConversionsLimit; public int inputMaxConversionsLimit = Integer.MAX_VALUE; public int inputMinScoreLimit; public int inputMaxScoreLimit = Integer.MAX_VALUE; + public int inputMinBSLimit; + public int inputMaxBSLimit = Integer.MAX_VALUE; public int inputMinPriorityLimit; public int inputMaxPriorityLimit = Integer.MAX_VALUE; diff --git a/backend/src/main/java/com/fribbels/request/SkillOptionsRequest.java b/backend/src/main/java/com/fribbels/request/SkillOptionsRequest.java new file mode 100644 index 00000000..b7c474e7 --- /dev/null +++ b/backend/src/main/java/com/fribbels/request/SkillOptionsRequest.java @@ -0,0 +1,20 @@ +package com.fribbels.request; + +import com.fribbels.model.HeroSkillOptions; +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class SkillOptionsRequest extends Request { + + private String heroId; + + private HeroSkillOptions skillOptions; +} + diff --git a/data/cache/herodata.json b/data/cache/herodata.json index 9a07171e..01abe96f 100644 --- a/data/cache/herodata.json +++ b/data/cache/herodata.json @@ -68,57 +68,47 @@ } ], "skills": { - "s1": [ - { - "name": "S1 crit", - "type": 0, - "rate": 1, - "pow": 0.95 - }, - { - "name": "S1 crushing", - "type": 0, - "rate": 1, - "pow": 0.95 - }, - { - "name": "S1 normal", - "type": 0, - "rate": 1, - "pow": 0.95 - }, - { - "name": "S1 miss", - "type": 0, - "rate": 1, - "pow": 0.95 - } - ], - "s2": [ - { - "name": "S2 heal", - "type": 1, - "rate": 0, - "pow": 0, - "selfHpScaling": 0.15 - } - ], - "s3": [ - { - "name": "S3 heal", - "type": 1, - "rate": 0, - "pow": 0, - "selfHpScaling": 0.3 - }, - { - "name": "S3 soulburn heal", - "type": 1, - "rate": 0, - "pow": 0, - "selfHpScaling": 0.5 - } - ] + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "targets": 0, + "rate": 0, + "pow": 0, + "selfHpScaling": 0.3 + }, + { + "name": "S3 soulburn heal", + "targets": 0, + "rate": 0, + "pow": 0, + "selfHpScaling": 0.5 + } + ] + } }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { @@ -174,6 +164,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3143_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1.05, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11477, @@ -228,6 +241,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3043_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11614, @@ -282,6 +315,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c5001_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.04, + "increasedValue": 0.1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.04, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12124, @@ -356,6 +415,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1138_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 2, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12684, @@ -408,6 +487,39 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1137_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfDefScaling": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfDefScaling": 0.7 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "with proc dmg", + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.5, + "extraSelfDefScaling": 1.4, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13403, @@ -460,6 +572,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1140_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16221, @@ -512,6 +644,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1139_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13285, @@ -566,6 +718,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3105_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13832, @@ -620,6 +792,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4105_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13832, @@ -636,7 +828,7 @@ "bonusMaxDefPercent": 0, "bonusMaxHpPercent": 0, "overrideAtk": 0, - "overrideHp": 4275, + "overrideHp": 4801, "overrideDef": 688, "overrideAdditionalCr": 0, "overrideAdditionalCd": 0, @@ -659,7 +851,7 @@ "bonusMaxDefPercent": 0, "bonusMaxHpPercent": 0, "overrideAtk": 0, - "overrideHp": 4275, + "overrideHp": 4801, "overrideDef": 688, "overrideAdditionalCr": 0, "overrideAdditionalCd": 0, @@ -696,6 +888,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3093_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11788, @@ -750,6 +962,43 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1018_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15, + "selfAtkScaling": 0.45 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15, + "selfAtkScaling": 0.35 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13996, @@ -816,6 +1065,33 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.08, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.11, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.15, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13640, @@ -870,6 +1146,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3012_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11477, @@ -924,6 +1223,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4065_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11667, @@ -998,6 +1317,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2042_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.12, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13591, @@ -1050,6 +1391,23 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1143_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15716, @@ -1103,6 +1461,23 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c6062_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13090, @@ -1157,6 +1532,41 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4042_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.07 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.35 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14246, @@ -1274,6 +1684,41 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15120, @@ -1326,6 +1771,37 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2019_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.12, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.08 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.2, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13640, @@ -1414,6 +1890,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13525, @@ -1466,6 +1965,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2007_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.975, + "pow": 1, + "targets": 2, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.04, + "pow": 0.85, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13126, @@ -1518,6 +2037,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c5004_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1.3, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14048, @@ -1570,6 +2112,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2099_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "80% penetration", + "rate": 0.9, + "pow": 0.9, + "targets": 3, + "penetration": 0.8, + "selfSpdScaling": 0.001125, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13675, @@ -1622,6 +2187,37 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1129_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 2, + "selfDefScaling": 0.85, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1.3, + "targets": 3, + "selfDefScaling": 1.4, + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfDefScaling": 1 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13970, @@ -1739,6 +2335,34 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "single target", + "rate": 0.8, + "pow": 0.9, + "targets": 1, + "selfDefScaling": 0.6, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfDefScaling": 0.6 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13184, @@ -1793,6 +2417,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3004_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.05, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.15, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12124, @@ -1845,6 +2491,41 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1124_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [ + { + "name": "S1 proc normal", + "rate": 1.3, + "pow": 1.3, + "targets": 1 + }, + { + "name": "S1 proc miss", + "rate": 1.3, + "pow": 1.3, + "targets": 1 + } + ] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "note": "70% penetration", + "rate": 0.9, + "pow": 1, + "targets": 1, + "penetration": 0.7, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16221, @@ -1964,6 +2645,26 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12819, @@ -2034,6 +2735,28 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "selfSpdScaling": 0.001, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11993, @@ -2135,6 +2858,28 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.8, + "targets": 1, + "selfSpdScaling": 0.001125, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11777, @@ -2187,6 +2932,25 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2091_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 0.9, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13144, @@ -2240,6 +3004,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2031_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.8, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12736, @@ -2294,6 +3078,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3031_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12002, @@ -2360,6 +3167,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 2, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 0.9, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13525, @@ -2413,6 +3243,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c6008_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.06, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.16, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13440, @@ -2465,6 +3317,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1093_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13275, @@ -2517,6 +3392,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1053_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.9, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14048, @@ -2571,6 +3469,37 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3006_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.9, + "targets": 1, + "selfHpScaling": 0.07, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.12, + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.3 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12037, @@ -2625,6 +3554,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3095_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 0.5, + "pow": 0.95, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11888, @@ -2677,6 +3630,27 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1141_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["normal", "miss"], + "note": "S1 proc", + "rate": 1.2, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13285, @@ -2751,6 +3725,33 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1117_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1.05, + "targets": 3, + "selfHpScaling": 0.09, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 0.6, + "pow": 1.3, + "targets": 3, + "selfHpScaling": 0.045, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1.3, + "targets": 3, + "selfHpScaling": 0.12, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13403, @@ -2847,6 +3848,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.95, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13285, @@ -2900,6 +3924,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2043_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 0.5, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13090, @@ -2953,6 +4001,29 @@ }, "ex_equip": [ ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 2, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13380, @@ -3052,10 +4123,30 @@ } } ], - "calculatedStatus": { - "lv50FiveStarFullyAwakened": { - "cp": 14809, - "atk": 709, + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 0.95, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, + "calculatedStatus": { + "lv50FiveStarFullyAwakened": { + "cp": 14809, + "atk": 709, "hp": 3321, "spd": 109, "def": 506, @@ -3105,6 +4196,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2011_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 0.95, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12463, @@ -3157,6 +4268,38 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2039_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.12, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.6 + } + ] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "rate": 0.3, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.12, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16093, @@ -3226,6 +4369,27 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.75, + "pow": 1, + "targets": 2, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13288, @@ -3278,6 +4442,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2024_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "with proc damage", + "rate": 0.85, + "pow": 1, + "targets": 1, + "extraSelfAtkScaling": 0.3, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "with proc damage", + "rate": 0.95, + "pow": 1.1, + "targets": 3, + "extraSelfAtkScaling": 0.3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13288, @@ -3332,6 +4522,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3001_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.85, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11820, @@ -3386,6 +4596,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3124_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16298, @@ -3440,6 +4670,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4034_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11788, @@ -3516,6 +4766,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3071_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12152, @@ -3570,6 +4843,35 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3051_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfAtkScaling": 0.78 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11614, @@ -3623,6 +4925,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1013_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.06, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.05, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12802, @@ -3718,6 +5042,32 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.07, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.4, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.06, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1.05, + "targets": 3, + "selfHpScaling": 0.12, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13403, @@ -3772,6 +5122,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3064_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11234, @@ -3825,6 +5195,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2005_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.9, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 0.8, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12684, @@ -3919,6 +5312,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.4, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13275, @@ -3971,6 +5387,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1081_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12803, @@ -4071,6 +5510,27 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.15, + "pow": 0.9, + "penetration": 0.5, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13727, @@ -4124,6 +5584,23 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2037_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12684, @@ -4177,6 +5654,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2010_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 2, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13209, @@ -4231,6 +5728,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4001_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.85, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11820, @@ -4307,6 +5824,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4025_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.06, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.95, + "targets": 3, + "selfHpScaling": 0.08, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "selfHpScaling": 0.2, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11978, @@ -4325,7 +5868,7 @@ "overrideAtk": 0, "overrideHp": 4788, "overrideDef": 503, - "overrideAdditionalCr": 0.05, + "overrideAdditionalCr": 0, "overrideAdditionalCd": 0, "overrideAdditionalSpd": 0, "overrideAdditionalEff": 0, @@ -4348,7 +5891,7 @@ "overrideAtk": 0, "overrideHp": 6013, "overrideDef": 624, - "overrideAdditionalCr": 0.05, + "overrideAdditionalCr": 0, "overrideAdditionalCd": 0, "overrideAdditionalSpd": 0, "overrideAdditionalEff": 0, @@ -4426,6 +5969,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13243, @@ -4520,6 +6086,26 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.4, + "pow": 0.9, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13494, @@ -4621,6 +6207,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.7, + "pow": 0.8, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13380, @@ -4718,6 +6327,32 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.11, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.15, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13730, @@ -4772,6 +6407,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3123_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.12 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12320, @@ -4788,7 +6449,7 @@ "lv60SixStarFullyAwakened": { "cp": 15835, "atk": 667, - "hp": 5704, + "hp": 5784, "spd": 90, "def": 749, "chc": 0.15, @@ -4826,6 +6487,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3025_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.06, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.95, + "targets": 3, + "selfHpScaling": 0.08, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "selfHpScaling": 0.2, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11978, @@ -4893,6 +6580,28 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.95, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.0021, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12112, @@ -4988,6 +6697,30 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12841, @@ -5040,6 +6773,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2027_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13275, @@ -5093,6 +6850,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1033_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.3, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12463, @@ -5147,6 +6927,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4035_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11978, @@ -5221,6 +7021,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2080_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.75, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "70% penetration", + "rate": 0.75, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16394, @@ -5273,6 +7097,23 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2089_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 17097, @@ -5326,6 +7167,37 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1012_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.9, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.3, + "pow": 0.9, + "targets": 3, + "selfDefScaling": 0.7, + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.5 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12802, @@ -5379,6 +7251,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2054_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11777, @@ -5432,6 +7327,24 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2008_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.6, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12975, @@ -5485,6 +7398,37 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1036_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1.05, + "targets": 1, + "selfDefScaling": 0.7, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 0.95, + "targets": 3, + "selfDefScaling": 0.6, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12936, @@ -5537,6 +7481,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2012_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.07, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "rate": 0, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.25, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13730, @@ -5589,6 +7556,23 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2090_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16072, @@ -5641,6 +7625,23 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2053_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15700, @@ -5694,6 +7695,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2095_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 1, + "selfDefScaling": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 3, + "selfDefScaling": 1.15, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13640, @@ -5786,6 +7809,41 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.16 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.3 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16072, @@ -5878,6 +7936,32 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15706, @@ -5931,6 +8015,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1021_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12701, @@ -5983,6 +8087,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1094_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["miss"], + "rate": 2.5, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13970, @@ -6037,6 +8164,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4073_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12694, @@ -6112,6 +8262,35 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1037_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.25 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.75, + "pow": 0.95, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13090, @@ -6166,6 +8345,41 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3044_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.25 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14137, @@ -6220,6 +8434,33 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3094_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.05, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.361 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12139, @@ -6294,6 +8535,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1111_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.05, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 17217, @@ -6346,6 +8610,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1134_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.08, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.25, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11377, @@ -6438,6 +8728,35 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15706, @@ -6490,6 +8809,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1142_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.95, + "pow": 0.9, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1.3, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12952, @@ -6542,6 +8885,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1105_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1.1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13285, @@ -6596,6 +8962,35 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3054_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.9, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.1 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14246, @@ -6648,6 +9043,47 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1116_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.95, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + }, + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15706, @@ -6702,6 +9138,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3022_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12002, @@ -6754,6 +9210,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1108_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.4, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13275, @@ -6806,6 +9285,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c5050_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13970, @@ -6858,6 +9360,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2046_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.4, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13288, @@ -6912,6 +9437,24 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4003_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 0.9, + "targets": 1, + "selfDefScaling": 0.7, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11779, @@ -6986,6 +9529,37 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2002_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.07, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.65, + "pow": 0.95, + "targets": 3, + "selfHpScaling": 0.12, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13591, @@ -7039,6 +9613,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2032_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.75, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "selfDefScaling": 1.5, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12975, @@ -7090,50 +9686,24 @@ "image": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/question_circle.png", "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1110_l.png" }, - "ex_equip": [ - { - "_id": "exc100201", - "id": "exc100201", - "name": "Black Winter Spear", - "description": "\"A requiem for the fallen heroes of Wintenberg.\" These are the words the blacksmith spoke as he offered this weapon to Cecilia.", - "unit": "c1002", - "role": "knight", - "rarity": 5, - "stat": { - "type": "acc", - "value": 0.08 - }, - "skills": [ - { - "skill": 1, - "description": "Increases decrease Defense chance by 10% when using Deliverance.", - "skill_description": null, - "values": [], - "_id": 0 - }, - { - "skill": 2, - "description": "Dispels one buff from all enemies after using Steel Cloudburst.", - "skill_description": "Attacks all enemies with a magical spear, with a {{variable}} chance to decrease Attack for 2 turns and a 100% chance to dispel one buff. Damage dealt increases proportional to the caster's max Health.", - "values": [], - "_id": 1 - }, - { - "skill": 2, - "description": "Makes all enemies unhealable for 2 turns when using Steel Cloudburst.", - "skill_description": "Attacks all enemies with a magical spear, with a {{variable}} chance to decrease Attack for 2 turns and a 100% chance to make them unhealable for 2 turns. Damage dealt increases proportional to the caster's max Health.", - "values": [ - 17, - 27 - ], - "_id": 2 - } - ], - "assets": { - "icon": "https://assets.epicsevendb.com/_source/item/icon_eq_exclusive_c1002.png" - } + "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] } - ], + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13285, @@ -7201,6 +9771,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12701, @@ -7268,6 +9861,26 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.65, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12530, @@ -7363,6 +9976,28 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.06, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.08, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12802, @@ -7417,6 +10052,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3103_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11520, @@ -7471,6 +10126,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3074_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12597, @@ -7525,6 +10200,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3101_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.65, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11667, @@ -7596,6 +10291,32 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfAtkScaling": 0.5 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12997, @@ -7697,6 +10418,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12997, @@ -7751,6 +10495,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3024_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["normal", "miss"], + "rate": 1, + "pow": 0.85, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "rate": 2.2, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "bonusMaxAtkPercent": 75, "bonusMaxDefPercent": 0, @@ -7830,6 +10594,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3135_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.05, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.05, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11779, @@ -7899,6 +10685,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12981, @@ -7953,6 +10762,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3091_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.95, + "pow": 0.95, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 0.85, + "targets": 1, + "selfSpdScaling": 0.00125, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11477, @@ -8007,6 +10838,43 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3041_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.3, + "selfAtkScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.3, + "selfAtkScaling": 0.12 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14054, @@ -8061,6 +10929,37 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3122_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.8, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "selfDefScaling": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfDefScaling": 0.8 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12139, @@ -8115,6 +11014,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3023_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.55, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11710, @@ -8167,6 +11086,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c5016_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13440, @@ -8221,6 +11160,20 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4141_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": [], + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11477, @@ -8297,6 +11250,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3055_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11922, @@ -8349,6 +11322,37 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1128_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfAtkScaling": 0.45 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "100% penetration", + "rate": 1.25, + "pow": 1, + "targets": 1, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13440, @@ -8425,6 +11429,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3102_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11323, @@ -8491,6 +11515,32 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.18, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.15, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13243, @@ -8584,6 +11634,27 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.95, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "no detonations", + "rate": 0.7, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12819, @@ -8636,6 +11707,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1024_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 2, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13356, @@ -8688,6 +11779,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1130_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.75, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.95, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13624, @@ -8742,6 +11857,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3131_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11978, @@ -8796,6 +11931,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3053_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.9, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13832, @@ -8850,6 +12005,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3052_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 0.95, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12313, @@ -8902,6 +12077,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2006_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13569, @@ -8956,6 +12154,23 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3011_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11003, @@ -9010,6 +12225,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3151_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11710, @@ -9106,6 +12341,30 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 0.85, + "targets": 1, + "cdmgIncrease": 0.5, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12292, @@ -9206,6 +12465,31 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.4, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "targets": 3, + "selfSpdScaling": 0.00075, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13675, @@ -9301,6 +12585,26 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.7, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12898, @@ -9353,6 +12657,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1047_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "selfHpScaling": 0.3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13730, @@ -9406,6 +12736,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1086_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12124, @@ -9459,6 +12813,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1085_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.7, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12819, @@ -9513,6 +12887,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3084_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.7, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.4, + "pow": 1, + "targets": 3, + "selfDefScaling": 0.5, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12320, @@ -9567,6 +12963,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3063_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11702, @@ -9661,6 +13077,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13126, @@ -9754,6 +13193,30 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.8, + "targets": 1, + "selfHpScaling": 0.06, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12701, @@ -9807,6 +13270,42 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1107_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 0.9, + "targets": 1, + "selfHpScaling": 0.12, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.145 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.182 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15120, @@ -9861,6 +13360,24 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3003_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 0.9, + "targets": 1, + "selfDefScaling": 0.7, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11779, @@ -9927,6 +13444,33 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.085, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.13, + "options": [] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "note": "no missing health", + "rate": 0.3, + "pow": 1, + "targets": 1, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13718, @@ -9993,6 +13537,25 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13288, @@ -10045,6 +13608,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1109_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13356, @@ -10096,7 +13679,40 @@ "image": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/question_circle.png", "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2070_l.png" }, - "ex_equip": [], + "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.105 + } + ] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "rate": 0.3, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.06, + "selfSpdScaling": 0.001125, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13718, @@ -10151,6 +13767,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3092_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.15, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11788, @@ -10226,6 +13862,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1029_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.35, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.8, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12475, @@ -10321,6 +13980,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12952, @@ -10375,6 +14057,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3153_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.9, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11667, @@ -10427,6 +14129,36 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1089_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "selfHpScaling": 0.12, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13403, @@ -10522,6 +14254,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 2, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13440, @@ -10574,6 +14329,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2079_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 0.9, + "targets": 1, + "selfDefScaling": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.3, + "pow": 0.9, + "targets": 3, + "selfDefScaling": 1.35, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13727, @@ -10626,6 +14403,27 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2009_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "not including splash", + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13440, @@ -10678,6 +14476,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2071_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16221, @@ -10732,6 +14553,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3035_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11978, @@ -10785,6 +14626,41 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1031_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.1 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14745, @@ -10837,6 +14713,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1126_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16999, @@ -10891,6 +14787,35 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3113_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.95, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13894, @@ -10985,6 +14910,31 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.65, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "60% penetration", + "rate": 0.9, + "pow": 0.95, + "targets": 3, + "penetration": 0.6, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13169, @@ -11084,6 +15034,35 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfAtkScaling": 0.375 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1.05, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14048, @@ -11182,6 +15161,27 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "max hits", + "rate": 2.1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1.05, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13440, @@ -11236,6 +15236,41 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4044_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.25 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14137, @@ -11310,6 +15345,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2049_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.12 + } + ] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15694, @@ -11362,6 +15423,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2047_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13727, @@ -11438,6 +15522,43 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4041_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15, + "selfAtkScaling": 0.3 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.12, + "selfAtkScaling": 0.3 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14054, @@ -11513,6 +15634,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1032_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 0.95, + "targets": 1, + "selfDefScaling": 0.75, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.8, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13492, @@ -11565,6 +15708,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2073_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.04, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.09, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13730, @@ -11619,6 +15784,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3121_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11788, @@ -11685,6 +15870,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13169, @@ -11738,6 +15946,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c0002_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.95, + "targets": 2, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.15, + "pow": 0.95, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12684, @@ -11792,6 +16023,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4023_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.55, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11710, @@ -11867,6 +16118,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/m0063_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0, + "pow": 0, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0, + "pow": 0, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0, + "pow": 0, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12452, @@ -11961,6 +16232,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.7, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13929, @@ -12015,6 +16309,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3014_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 0.85, + "targets": 1, + "selfSpdScaling": 0.0015, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11405, @@ -12069,6 +16385,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3072_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11929, @@ -12123,6 +16462,41 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3042_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.07 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.35 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14246, @@ -12176,6 +16550,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c6037_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.3045 + } + ] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14749, @@ -12292,6 +16692,28 @@ } } ], + "skills": { + "S1": { + "hitTypes": [], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.08, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.15, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13243, @@ -12346,6 +16768,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3033_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11710, @@ -12444,6 +16888,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13569, @@ -12498,6 +16965,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4062_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.8, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11248, @@ -12574,6 +17061,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3132_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11607, @@ -12628,6 +17138,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3061_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.8, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11520, @@ -12680,6 +17210,33 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2072_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "100% penetration", + "rate": 0.75, + "pow": 1, + "targets": 1, + "penetration": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.1, + "targets": 3, + "selfSpdScaling": 0.001125, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13144, @@ -12734,6 +17291,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3133_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.65, + "pow": 0.9, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "70% penetration", + "rate": 0.7, + "pow": 0.95, + "targets": 1, + "penetration": 0.7, + "selfSpdScaling": 0.00075, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11607, @@ -12788,6 +17369,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3045_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12250, @@ -12882,6 +17483,32 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1.1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "selfSpdScaling": 0.001125, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.0015, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12952, @@ -12935,6 +17562,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2087_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 0.9, + "targets": 1, + "selfDefScaling": 0.8, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "60% penetration", + "rate": 0.5, + "pow": 0.9, + "targets": 3, + "penetration": 0.6, + "selfDefScaling": 1.3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12452, @@ -12989,6 +17640,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3073_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12694, @@ -13041,6 +17715,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1125_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12898, @@ -13095,6 +17789,35 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3125_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfAtkScaling": 0.65 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1.2, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11607, @@ -13147,6 +17870,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2110_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13288, @@ -13220,7 +17963,30 @@ "image": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/question_circle.png", "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1112_l.png" }, - "ex_equip": [], + "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13525, @@ -13274,6 +18040,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1035_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.05, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12819, @@ -13328,6 +18116,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3005_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.5, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 0.95, + "targets": 1, + "selfDefScaling": 0.7, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12139, @@ -13380,6 +18190,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1115_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13525, @@ -13454,6 +18284,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1118_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.9, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "selfSpdScaling": 0.00075, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12898, @@ -13508,6 +18360,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1001_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.04, + "increasedValue": 0.1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.04, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12124, @@ -13605,6 +18483,26 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 0.95, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13730, @@ -13697,6 +18595,41 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15716, @@ -13749,6 +18682,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1114_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.95, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16221, @@ -13801,6 +18757,27 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2074_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.3, + "targets": 1, + "penetration": 0.5, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13126, @@ -13855,6 +18832,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3075_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14181, @@ -13909,6 +18906,35 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4051_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.95, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfAtkScaling": 0.78 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11614, @@ -13985,6 +19011,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4013_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.001125, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 10214, @@ -14061,6 +19109,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3034_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11788, @@ -14115,6 +19183,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3062_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.8, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11248, @@ -14167,6 +19255,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1121_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.65, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13440, @@ -14260,6 +19371,37 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.9, + "targets": 1, + "selfHpScaling": 0.05, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.07, + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14786, @@ -14312,6 +19454,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1136_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.15, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 2, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13285, @@ -14379,6 +19541,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12468, @@ -14431,6 +19616,47 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1102_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.0775 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.25 + }, + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16093, @@ -14526,6 +19752,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.85, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12741, @@ -14580,6 +19829,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3013_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.001125, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 10214, @@ -14678,6 +19949,33 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.7, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfDefScaling": 1 + } + ] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12975, @@ -14730,6 +20028,31 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1135_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 0.8, + "pow": 1, + "targets": 1, + "penetration": 0.5, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 0.9, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13169, @@ -14782,6 +20105,33 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1022_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.81, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.07, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.35 + } + ] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16093, @@ -14834,6 +20184,31 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2015_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 1.3, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "note": "no missing health", + "rate": 0.5, + "pow": 1, + "targets": 1, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13970, @@ -14888,6 +20263,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4144_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1.3, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "penetration": 0.5, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11477, @@ -14963,6 +20362,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1020_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12530, @@ -15015,6 +20434,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c5071_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "cdmgIncrease": 0.2, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13288, @@ -15109,6 +20552,35 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["normal", "miss"], + "rate": 0.95, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfAtkScaling": 0.25 + } + ] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "rate": 1.5, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "bonusMaxAtkPercent": 30, "bonusMaxDefPercent": 0, @@ -15189,6 +20661,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4142_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 1.05, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11477, @@ -15313,6 +20808,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1.05, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13166, @@ -15365,6 +20883,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1038_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 2, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13275, @@ -15419,6 +20960,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4005_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "selfDefScaling": 0.5, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 0.95, + "targets": 1, + "selfDefScaling": 0.7, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12139, @@ -15536,6 +21099,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.8, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12456, @@ -15602,6 +21188,35 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.1 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15694, @@ -15656,6 +21271,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4052_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 0.95, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12313, @@ -15731,6 +21366,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2017_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15120, @@ -15797,6 +21458,33 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.75, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.09, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.18 + } + ] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15706, @@ -15892,6 +21580,31 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.25, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "30% penetration", + "rate": 1.7, + "pow": 0.8, + "penetration": 0.3, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13624, @@ -15945,6 +21658,27 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1004_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.9, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 1.05, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12121, @@ -15997,6 +21731,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2048_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1.3, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13525, @@ -16049,52 +21806,33 @@ "image": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/question_circle.png", "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2062_l.png" }, - "ex_equip": [ - { - "_id": "exc100301", - "id": "exc100301", - "name": "Valkyrie Wing", - "description": "A mysterious circlet that symbolizes strength and beauty, and is the source of Rose's Fighting Spirit.", - "unit": "c1003", - "role": "knight", - "rarity": 5, - "stat": { - "type": "speed", - "value": 5 - }, - "skills": [ - { - "skill": 1, - "description": "Activates each effect regardless of current Health when using Sequential Cutter.", - "skill_description": "Attacks with a sword, with a {{variable}} chance to provoke for 1 turn, before increasing Defense of the caster for 1 turn. Damage dealt increases proportional to the caster's Defense.", - "values": [ - 25, - 2 - ], - "_id": 0 - }, - { - "skill": 2, - "description": "Applies the same effect to the caster when using Shield of Light.", - "skill_description": "Covers an ally and the caster with the Shield of Light, dispelling two debuffs and granting a barrier for 2 turns before increasing Combat Readiness by {{variable}}. Barrier strength is proportional to the caster's Defense.", - "values": [ - 5 - ], - "_id": 1 - }, + "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ { - "skill": 3, - "description": "Decreases skill cooldown of Goddess of Victory by 1 turn.", - "skill_description": null, - "values": [], - "_id": 2 + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.24 } - ], - "assets": { - "icon": "https://assets.epicsevendb.com/_source/item/icon_eq_exclusive_c1003.png" - } + ] + }, + "S3": { + "hitTypes": [], + "options": [] } - ], + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14749, @@ -16147,11 +21885,34 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1092_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { - "cp": 13380, + "cp": 13219, "atk": 945, - "hp": 4414, + "hp": 4253, "spd": 119, "def": 446, "chc": 0.19, @@ -16161,9 +21922,9 @@ "efr": 0 }, "lv60SixStarFullyAwakened": { - "cp": 17246, + "cp": 17044, "atk": 1177, - "hp": 5542, + "hp": 5340, "spd": 119, "def": 553, "chc": 0.27, @@ -16199,6 +21960,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2111_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 0.8, + "pow": 1.3, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13970, @@ -16253,6 +22038,41 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3104_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.07 + } + ] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.18 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 14246, @@ -16305,6 +22125,31 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2038_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "100% penetration", + "rate": 1.5, + "pow": 1, + "targets": 1, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13275, @@ -16357,6 +22202,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2050_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 2, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13525, @@ -16409,6 +22274,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2103_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 1.3, + "pow": 0.9, + "penetration": 0.35, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 16901, @@ -16461,6 +22348,31 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1034_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "100% penetration", + "rate": 0.95, + "pow": 1, + "targets": 3, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13624, @@ -16513,6 +22425,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c5009_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13243, @@ -16589,6 +22521,20 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4012_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": [], + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11477, @@ -16663,6 +22609,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c5024_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13285, @@ -16738,6 +22704,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1065_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.4, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 0.8, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12203, @@ -16792,6 +22781,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3155_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1.1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12152, @@ -16846,6 +22855,30 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3015_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 0.7, + "pow": 1, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.8, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11607, @@ -16898,6 +22931,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2088_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13929, @@ -16950,6 +23003,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1127_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.98, + "pow": 0.9, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 1.2, + "pow": 1.3, + "targets": 1, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13569, @@ -17004,6 +23083,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3152_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11978, @@ -17058,6 +23157,35 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3154_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.7 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11710, @@ -17110,6 +23238,32 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1067_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.75, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.25 + } + ] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 15700, @@ -17164,6 +23318,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3032_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11788, @@ -17218,6 +23392,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3002_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.025, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.05, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12037, @@ -17271,6 +23467,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2065_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.05, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12203, @@ -17341,6 +23557,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1.05, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13929, @@ -17395,6 +23634,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3021_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11377, @@ -17447,6 +23706,27 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2082_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.6, + "pow": 1, + "targets": 1, + "selfSpdScaling": 0.0015, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13302, @@ -17546,6 +23826,33 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.04, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3":{ + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12870, @@ -17598,6 +23905,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c2023_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13275, @@ -17693,6 +24023,37 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.04, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.20 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 0.95, + "targets": 3, + "selfHpScaling": 0.1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13403, @@ -17747,6 +24108,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4004_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.05, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 0.95, + "targets": 1, + "selfHpScaling": 0.15, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12124, @@ -17823,6 +24206,21 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4143_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "TODO": "find multis", + "hitTypes": [], + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11477, @@ -17899,6 +24297,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4103_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11520, @@ -18019,6 +24437,31 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.95, + "targets": 2, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.85, + "pow": 1, + "targets": 3, + "selfSpdScaling": 0.1125, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13126, @@ -18071,6 +24514,35 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1074_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 heal", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.15 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13275, @@ -18163,6 +24635,26 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.05, + "pow": 0.9, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13302, @@ -18217,6 +24709,26 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3065_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.8, + "pow": 0.9, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11667, @@ -18317,6 +24829,29 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.2, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.3, + "pow": 0.9, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 2, + "pow": 0.8, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12475, @@ -18415,6 +24950,30 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1.05, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "targets": 1, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12452, @@ -18468,6 +25027,20 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/m0171_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": [], + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": [], + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12452, @@ -18522,6 +25095,34 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c3134_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.8, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "options": [] + }, + "S3": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S3 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.16 + } + ] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 11779, @@ -18616,6 +25217,31 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.9, + "pow": 1, + "targets": 3, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "70% penetration", + "rate": 2, + "pow": 0.95, + "penetration": 0.7, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13624, @@ -18668,6 +25294,38 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1131_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.35 + } + ] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "note": "no missing health", + "rate": 0.5, + "pow": 1, + "targets": 1, + "penetration": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13591, @@ -18764,6 +25422,27 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.6, + "pow": 0.8, + "targets": 3, + "selfSpdScaling": 0.00075, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.8, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13356, @@ -18856,6 +25535,35 @@ } } ], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": [], + "rate": 0, + "pow": 0, + "options": [ + { + "name": "S2 barrier", + "rate": 0, + "pow": 0, + "selfHpScaling": 0.2 + } + ] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.9, + "pow": 1, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13380, @@ -18910,6 +25618,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c4071_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 1.05, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 12152, @@ -18984,6 +25715,28 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1083_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 1, + "selfHpScaling": 0.1, + "options": [] + }, + "S2": { + "hitTypes": [], + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.5, + "pow": 1, + "targets": 3, + "selfHpScaling": 0.12, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13970, @@ -19037,6 +25790,29 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1010_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.05, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1.5, + "pow": 0.95, + "targets": 1, + "options": [] + }, + "S3": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 1, + "pow": 1, + "targets": 3, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 13209, @@ -19089,6 +25865,31 @@ "thumbnail": "https://raw.githubusercontent.com/fribbels/Fribbels-Epic-7-Optimizer/main/data/cachedimages/c1133_l.png" }, "ex_equip": [], + "skills": { + "S1": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "rate": 0.7, + "pow": 1, + "targets": 1, + "options": [] + }, + "S2": { + "hitTypes": ["crit", "crushing", "normal", "miss"], + "note": "S1 proc", + "rate": 1, + "pow": 1, + "targets": 1, + "penetration": 0.5, + "options": [] + }, + "S3": { + "hitTypes": ["normal", "miss"], + "rate": 0, + "pow": 0, + "targets": 1, + "options": [] + } + }, "calculatedStatus": { "lv50FiveStarFullyAwakened": { "cp": 17217, diff --git a/data/jar/backend.jar b/data/jar/backend.jar index ae7ab23d..78c28c85 100644 Binary files a/data/jar/backend.jar and b/data/jar/backend.jar differ diff --git a/data/locales/ru/gridlocale.js b/data/locales/ru/gridlocale.js new file mode 100644 index 00000000..341b5266 --- /dev/null +++ b/data/locales/ru/gridlocale.js @@ -0,0 +1,269 @@ +// Example locale file for English, give this to your locale team to translate + +global.AG_GRID_LOCALE_RU = { + // Set Filter + selectAll: '(Select All)', + selectAllSearchResults: '(Select All Search Results)', + searchOoo: 'Search...', + blanks: '(Blanks)', + noMatches: 'No matches', + + // Number Filter & Text Filter + filterOoo: 'Filter...', + equals: 'Equals', + notEqual: 'Not equal', + empty: 'Choose One', + + // Number Filter + lessThan: 'Less than', + greaterThan: 'Greater than', + lessThanOrEqual: 'Less than or equal', + greaterThanOrEqual: 'Greater than or equal', + inRange: 'In range', + inRangeStart: 'to', + inRangeEnd: 'from', + + // Text Filter + contains: 'Contains', + notContains: 'Not contains', + startsWith: 'Starts with', + endsWith: 'Ends with', + + // Date Filter + dateFormatOoo: 'yyyy-mm-dd', + + // Filter Conditions + andCondition: 'AND', + orCondition: 'OR', + + // Filter Buttons + applyFilter: 'Apply', + resetFilter: 'Reset', + clearFilter: 'Clear', + cancelFilter: 'Cancel', + + // Filter Titles + textFilter: 'Text Filter', + numberFilter: 'Number Filter', + dateFilter: 'Date Filter', + setFilter: 'Set Filter', + + // Side Bar + columns: 'Columns', + filters: 'Filters', + + // columns tool panel + pivotMode: 'Pivot Mode', + groups: 'Row Groups', + rowGroupColumnsEmptyMessage: 'Drag here to set row groups', + values: 'Values', + valueColumnsEmptyMessage: 'Drag here to aggregate', + pivots: 'Column Labels', + pivotColumnsEmptyMessage: 'Drag here to set column labels', + + // Header of the Default Group Column + group: 'Group', + + // Other + loadingOoo: 'Loading...', + noRowsToShow: 'Нет данных', + enabled: 'Enabled', + + // Menu + pinColumn: 'Pin Column', + pinLeft: 'Pin Left', + pinRight: 'Pin Right', + noPin: 'No Pin', + valueAggregation: 'Value Aggregation', + autosizeThiscolumn: 'Autosize This Column', + autosizeAllColumns: 'Autosize All Columns', + groupBy: 'Group by', + ungroupBy: 'Un-Group by', + resetColumns: 'Reset Columns', + expandAll: 'Expand All', + collapseAll: 'Close All', + copy: 'Copy', + ctrlC: 'Ctrl+C', + copyWithHeaders: 'Copy With Headers', + paste: 'Paste', + ctrlV: 'Ctrl+V', + export: 'Export', + csvExport: 'CSV Export', + excelExport: 'Excel Export (.xlsx)', + excelXmlExport: 'Excel Export (.xml)', + + // Enterprise Menu Aggregation and Status Bar + sum: 'Sum', + min: 'Min', + max: 'Max', + none: 'None', + count: 'Count', + avg: 'Average', + filteredRows: 'Filtered', + selectedRows: 'Selected', + totalRows: 'Total Rows', + totalAndFilteredRows: 'Rows', + more: 'More', + to: 'to', + of: 'of', + page: 'Page', + nextPage: 'Next Page', + lastPage: 'Last Page', + firstPage: 'First Page', + previousPage: 'Previous Page', + + // Enterprise Menu (Charts) + pivotChartAndPivotMode: 'Pivot Chart & Pivot Mode', + pivotChart: 'Pivot Chart', + chartRange: 'Chart Range', + + columnChart: 'Column', + groupedColumn: 'Grouped', + stackedColumn: 'Stacked', + normalizedColumn: '100% Stacked', + + barChart: 'Bar', + groupedBar: 'Grouped', + stackedBar: 'Stacked', + normalizedBar: '100% Stacked', + + pieChart: 'Pie', + pie: 'Pie', + doughnut: 'Doughnut', + + line: 'Line', + + xyChart: 'X Y (Scatter)', + scatter: 'Scatter', + bubble: 'Bubble', + + areaChart: 'Area', + area: 'Area', + stackedArea: 'Stacked', + normalizedArea: '100% Stacked', + + histogramChart: 'Histogram', + + // Charts + pivotChartTitle: 'Pivot Chart', + rangeChartTitle: 'Range Chart', + settings: 'Settings', + data: 'Data', + format: 'Format', + categories: 'Categories', + defaultCategory: '(None)', + series: 'Series', + xyValues: 'X Y Values', + paired: 'Paired Mode', + axis: 'Axis', + navigator: 'Navigator', + color: 'Color', + thickness: 'Thickness', + xType: 'X Type', + automatic: 'Automatic', + category: 'Category', + number: 'Number', + time: 'Time', + xRotation: 'X Rotation', + yRotation: 'Y Rotation', + ticks: 'Ticks', + width: 'Width', + height: 'Height', + length: 'Length', + padding: 'Padding', + spacing: 'Spacing', + chart: 'Chart', + title: 'Title', + titlePlaceholder: 'Chart title - double click to edit', + background: 'Background', + font: 'Font', + top: 'Top', + right: 'Right', + bottom: 'Bottom', + left: 'Left', + labels: 'Labels', + size: 'Size', + minSize: 'Minimum Size', + maxSize: 'Maximum Size', + legend: 'Legend', + position: 'Position', + markerSize: 'Marker Size', + markerStroke: 'Marker Stroke', + markerPadding: 'Marker Padding', + itemSpacing: 'Item Spacing', + itemPaddingX: 'Item Padding X', + itemPaddingY: 'Item Padding Y', + layoutHorizontalSpacing: 'Horizontal Spacing', + layoutVerticalSpacing: 'Vertical Spacing', + strokeWidth: 'Stroke Width', + offset: 'Offset', + offsets: 'Offsets', + tooltips: 'Tooltips', + callout: 'Callout', + markers: 'Markers', + shadow: 'Shadow', + blur: 'Blur', + xOffset: 'X Offset', + yOffset: 'Y Offset', + lineWidth: 'Line Width', + normal: 'Normal', + bold: 'Bold', + italic: 'Italic', + boldItalic: 'Bold Italic', + predefined: 'Predefined', + fillOpacity: 'Fill Opacity', + strokeOpacity: 'Line Opacity', + histogramBinCount: 'Bin count', + columnGroup: 'Column', + barGroup: 'Bar', + pieGroup: 'Pie', + lineGroup: 'Line', + scatterGroup: 'X Y (Scatter)', + areaGroup: 'Area', + histogramGroup: 'Histogram', + groupedColumnTooltip: 'Grouped', + stackedColumnTooltip: 'Stacked', + normalizedColumnTooltip: '100% Stacked', + groupedBarTooltip: 'Grouped', + stackedBarTooltip: 'Stacked', + normalizedBarTooltip: '100% Stacked', + pieTooltip: 'Pie', + doughnutTooltip: 'Doughnut', + lineTooltip: 'Line', + groupedAreaTooltip: 'Area', + stackedAreaTooltip: 'Stacked', + normalizedAreaTooltip: '100% Stacked', + scatterTooltip: 'Scatter', + bubbleTooltip: 'Bubble', + histogramTooltip: 'Histogram', + noDataToChart: 'No data available to be charted.', + pivotChartRequiresPivotMode: 'Pivot Chart requires Pivot Mode enabled.', + chartSettingsToolbarTooltip: 'Menu', + chartLinkToolbarTooltip: 'Linked to Grid', + chartUnlinkToolbarTooltip: 'Unlinked from Grid', + chartDownloadToolbarTooltip: 'Download Chart', + + // ARIA + ariaHidden: 'hidden', + ariaVisible: 'visible', + ariaChecked: 'checked', + ariaUnchecked: 'unchecked', + ariaIndeterminate:'indeterminate', + ariaColumnSelectAll: 'Toggle Select All Columns', + ariaInputEditor: 'Input Editor', + ariaDateFilterInput: 'Date Filter Input', + ariaFilterInput: 'Filter Input', + ariaFilterColumnsInput: 'Filter Columns Input', + ariaFilterValue: 'Filter Value', + ariaFilterFromValue: 'Filter from value', + ariaFilterToValue: 'Filter to value', + ariaFilteringOperator: 'Filtering Operator', + ariaColumnToggleVisibility: 'column toggle visibility', + ariaColumnGroupToggleVisibility: 'column group toggle visibility', + ariaRowSelect: 'Press SPACE to select this row', + ariaRowDeselect: 'Press SPACE to deselect this row', + ariaRowToggleSelection: 'Press Space to toggle row selection', + ariaRowSelectAll: 'Press Space to toggle all rows selection', + ariaSearch: 'Search', + ariaSearchFilterValues: 'Search filter values' +} diff --git a/data/locales/ru/translation.json b/data/locales/ru/translation.json new file mode 100644 index 00000000..68bebdb7 --- /dev/null +++ b/data/locales/ru/translation.json @@ -0,0 +1,1102 @@ +{ + "Optimizer": "Оптимизатор", + "Ocr Debugger": "Ocr Debugger", + "Subprocess Debugger": "Subprocess Debugger", + "Clear language cache": "Clear language cache", + "Gear": "Гир", + "Heroes": "Герои", + "Hero": "Герой", + "Start": "Начать", + "Filter": "Отфильтровать", + "Cancel": "Отмена", + "Reset filters": "Сбросить фильтры", + "Import": "Импрот", + "Importer": "Импрот", + "Stats": "Статы", + "Disabled": "Disabled", + "At least 1 stat": "At least 1 stat", + "At least 2 stat": "At least 2 stat", + "At least 3 stat": "At least 3 stat", + "All 4 stats": "Все 4 стата", + "Options": "Опции", + "Use reforged stats": "Учитывать reforge", + "Only maxed gear": "Only maxed gear", + "Locked items": "Заблок. гир", + "Equipped items": "Экип. гир", + "Keep current": "Оставить экип.", + "Exclude equipped": "Исключить гир", + "Stat filters": "Стат фильтр", + "Substat priority (clear)": "Приоритет субстатов (сброс)", + "Atk": "Atk", + "Hp": "Hp", + "Def": "Def", + "Spd": "Spd", + "CRate": "CRate", + "Cr": "Cr", + "CDmg": "CDmg", + "Cd": "Cd", + "Eff": "Eff", + "Res": "Res", + "Rating filters": "Рейт.фильтр", + "Cp": "Cp", + "HpS": "HpS", + "Ehp": "Ehp", + "EhpS": "EhpS", + "Dmg": "Dmg", + "DmgS": "DmgS", + "Mcd": "Mcd", + "McdS": "McdS", + "DmgH": "DmgH", + "Score": "Score", + "Upg": "Upg", + "Top %": "Топ %", + "Accessory main stats": "Фильтр Мейнстатов", + "Crit Chance": "Crit Chance", + "Crit Damage": "Crit Damage", + "Attack %": "Attack %", + "Attack": "Attack", + "Health %": "Health %", + "Health": "Health", + "Defense %": "Defense %", + "Defense": "Defense", + "Effectiveness": "Effectiveness", + "Effect Resistance": "Effect Resistance", + "CriticalHitChancePercent": "CriticalHitChancePercent", + "CriticalHitDamagePercent": "CriticalHitDamagePercent", + "AttackPercent": "AttackPercent", + "HealthPercent": "HealthPercent", + "DefensePercent": "DefensePercent", + "EffectivenessPercent": "EffectivenessPercent", + "EffectResistancePercent": "EffectResistancePercent", + "Effect Resist": "Effect Resist", + "Speed": "Speed", + "% Crit rate": "% Crit rate", + "% Attack": "% Attack", + "% Health": "% Health", + "% Defense": "% Defense", + "% Eff": "% Eff", + "% Res": "% Res", + "Speed ": "Speed ", + "Sets": "Сеты", + "Set": "Set", + "4 Piece": "4 Элемента", + "Counter": "Counter", + "Destruction": "Destruction", + "Injury": "Injury", + "Lifesteal": "Lifesteal", + "Rage": "Rage", + "Revenge": "Revenge", + "Necklace": "Некля", + "Ring": "Кольцо", + "Boots": "Ботинок", + "4 or 2 piece sets": "4 или 2 элемента сета", + "2 piece sets": "2 элемента сета", + "2 Piece": "2 Элемента", + "Critical": "Critical", + "Hit": "Hit", + "Immunity": "Immunity", + "Penetration": "Penetration", + "Resist": "Resist", + "Unity": "Unity", + "Exclude": "Исключение", + "Exclude sets": "Исключить сет", + "Force": "Force", + "Filter/Search details": "Доступно/Подобрано", + "Filtered weapons": "Доступно мечей", + "Filtered helmets": "Доступно шлемов", + "Filtered armors": "Доступно брони", + "Filtered necklaces": "Доступно неклей", + "Filtered rings": "Доступно колец", + "Filtered boots": "Доступно ботинков", + "Permutations": "Комбинации", + "Results": "Подобрано", + "No matches found": "Совпадений не найдено", + "Searched": "Проверено", + "Actions": "Действия", + "Equip": "Экипировать", + "Unequip": "Снять", + "Lock": "Заблокировать", + "Unlock": "Разблокировать", + "Select All": "Выбрать все", + "All selected": "All selected", + "[Select all]": "[Выбрать все]", + "selected": "selected", + "Deselect All": "Отменить выбор", + "Save Build": "Сохранить Билд", + "Remove Build": "Удалить Билд", + "Build name": "Build name", + "Folder:": "Folder:", + "Left:": "Left:", + "Top:": "Top:", + "Width:": "Width:", + "Height:": "Height:", + "Submit": "Submit", + "Submit Number": "Submit Number", + "Submit Text": "Submit Text", + "File Scan": "File Scan", + "Main Stat name": "Main Stat name", + "Main Stat numbers": "Main Stat numbers", + "Sub Stat name": "Sub Stat name", + "Sub Stat numbers": "Sub Stat numbers", + "sets": "sets", + "atk": "atk", + "hp": "hp", + "def": "def", + "spd": "spd", + "cr": "cr", + "cd": "cd", + "eff": "eff", + "res": "res", + "cp": "cp", + "hps": "hps", + "ehp": "ehp", + "ehps": "ehps", + "dmg": "dmg", + "dmgs": "dmgs", + "mcd": "mcd", + "mcds": "mcds", + "dmgh": "dmgh", + "score": "score", + "upg": "upg", + "Cp -": "Cp -", + "HpS -": "HpS -", + "Ehp -": "Ehp -", + "EhpS -": "EhpS -", + "Dmg -": "Dmg -", + "DmgS -": "DmgS -", + "Mcd -": "Mcd -", + "McdS -": "McdS -", + "DmgH -": "DmgH -", + "Score -": "Score -", + "Upg -": "Upg -", + "actions": "actions", + "to": "to", + "of": "of", + "Page": "Page", + "All": "All", + "Contains": "Contains", + "Not contains": "Not contains", + "Equals": "Equals", + "Not equal": "Not equal", + "Starts with": "Starts with", + "Ends with": "Ends with", + "Filter...": "Filter...", + "Less than": "Less than", + "Less than or equals": "Less than or equals", + "Greater than": "Greater than", + "Greater than or equals": "Greater than or equals", + "In range": "In range", + "Jimp": "Jimp", + "Full scan": "Full scan", + "Lib": "Lib", + "Debug1": "Debug1", + "Gear table": "Гиртейбл", + "Selected:": "Selected:", + "No Rows To Show": "Нет данных", + "Rank": "Редкость", + "Main": "Main", + "Value": "Value", + "Atk%": "Atk%", + "Hp%": "Hp%", + "Def%": "Def%", + "dScore": "dScore", + "sScore": "sScore", + "cScore": "cScore", + "Equipped": "Экипированно", + "Locked": "Locked", + "Equip / Edit Item": "Изменить", + "Reforge Item": "Выполнить Reforge", + "Add New Item": "Добавить", + "Duplicate Item": "Дублировать", + "Duplicates": "Дубликаты", + "Duplicate": "Duplicate", + "Remove Items": "Удалить", + "Unequip Items": "Снять", + "Lock Items": "Заблокировать", + "Unlock Items": "Разблокировать", + "Filters": "Filters", + "clear": "clear", + "(clear)": "(сброс)", + "Clear": "Сброс", + "Main stats": "Мейнстаты", + "Sub stats": "Субстаты", + "Level": "Уровень", + "Enhance": "Enhance", + "Other": "Другое", + "Clear all": "Очистить", + "icon": "icon", + "elem": "elem", + "class": "class", + "name": "name", + "Add New Hero": "Добавить Героя", + "Add Bonus Stats": "+ Арт/ЕЕ/Импринт", + "Remove Hero": "Удалить Героя", + "Equip Build": "Одеть Билд", + "Rename Build": "Название Билда", + "Save As Build": "Сохранить в Билд", + "None": "Нет", + "Artifact": "Артефакт", + "Imprint": "Импринт", + "EE": "EE", + "Crit Rate": "Crit Rate", + "Crit Dmg": "Crit Dmg", + "OK": "OK", + "Crit rate": "Crit rate", + "Dual Attack": "Dual Attack", + "Add any other stats not included above": "Add any other stats not included above", + "Loading gear automatically from the game": "Loading gear automatically from the game", + "1. Install requirements from the instructions on Github
2. Leave your emulator open, and close Epic 7
3. Click the Start scanning button below
4. Open Epic 7, and load into the lobby
5. Click the Stop scanning button below
6. Wait up to 30 secs, then once the data appears, click Export to save it to a 'gear.txt'
7. Import the 'gear.txt' with the Merge option
8. If the message tells you to, use the Level = 0 filter to manually fix any level 0 items on the Gear tab
": "1. Устанвоите софт с: instructions on Github
2. Оставьте эмулятор Андроида открытым, закройте Epic 7
3. Нажмите на Начать сканирование
4. Откройте Epic 7, дождитесь загрузки до лобби (это там где сидят герои)
5. Нажмите Остановить сканирование
6. Подождите номного пока появятся данные, затем, нажмитеЭкспорт для сохранения данных сканирования в 'gear.txt'
7. Импортируйте 'gear.txt' кнопкой Импорт данных 8. If the message tells you to, use the Level = 0 filter to manually fix any level 0 items on the Gear tab
", + "Click": "Click", + "Start scanning": "Начать сканирование", + "Stop scanning": "Остановить сканирование", + "Export": "Экспорт", + "+3 and up": "+3 и более", + "+6 and up": "+6 и более", + "+9 and up": "+9 и более", + "+12 and up": "+12 и более", + "Importing gear data": "Importing gear data", + "Use merge to update all your gear after using the scanner or screenshot tool.": "Используйте Импорт данных, чтобы обновить все свое снаряжение после использования сканирования или импорта по скриншотам.", + "Use add only if you're using screenshots and want to update a small number of gears.": "Use add only if you're using screenshots and want to update a small number of gears.", + "Use": "Use", + "replace": "replace", + "add": "add", + "merge": "merge", + "Replace data": "Replace data", + "Add new data": "Add new data", + "Merge data": "Импорт данных", + "Save data": "Сохранить данные", + "Load data": "Загрузить данные", + "Choose folder": "Choose folder", + "Waiting for file..": "Ожидание файла...", + "Waiting for folder..": "Ожидание папки...", + "Save/Load all optimizer data": "Save/Load all optimizer data", + "You can load/save your hero + gear configuration here.": "Тут вы можете сохранить/загрузить ваших героев + гир.", + "Creating gear data from screenshots": "Creating gear data from screenshots", + "Hit 'Choose Folder', navigate into the folder where your screenshots are located, then hit 'Submit'. (The folder should show as empty, just select it)": "Hit 'Choose Folder', navigate into the folder where your screenshots are located, then hit 'Submit'. (The folder should show as empty, just select it)", + "Once results are printed, hit 'Export'. This will output a 'gear.txt' in the folder where you installed this app.": "Once results are printed, hit 'Export'. This will output a 'gear.txt' in the folder where you installed this app.", + "Import gear from Zarroc optimizer": "Импортировать из Zarroc оптимизатора", + "Select the Zarroc optimizer file here.": "Select the Zarroc optimizer file here.", + "Import Zarroc data": "Import Zarroc data", + "Settings": "Настройки", + "Automatically unlock equipment after unequipping": "Автоматически разблокировать гир после снятия", + "Use rage set bonus for damage optimization": "Используйте бонус сета RAGE для оптимизации урона", + "Maximum optimization results (Recommended: 5,000,000, Min 10k, Max 100m)": "Максимум проверенных комбинаций (Рекомендуется: 5,000,000 , Min 10k , Max 100m)", + "Change saves folder": "Изменить папку сохранени", + "Select default folder": "Select default folder", + "Choose the desired main stats for accessories. Multiple options can be selected per slot.": "Выберете мейнстаты для каждого предмета. Можно выбрать несолько вариантов для каждого слота.", + "Choose the desired gear sets. Multiple options can be selected per slot. The first slot must be either only 4 piece or 2 piece sets.": "Выберите необходимые сеты. Для каждого слота можно выбрать несколько вариантов. Первый слот должен состоять либо только из 4 элементов, либо из 2 элементов..", + "Choose any sets you don't want included in the search.": "Выберете сеты которые хотите исклчюить из поиска.", + "Select substat filters to filter results by. Left column is min (inclusive) and right column is max (inclusive).": "Фильтрация гира по итоговым статам героя, слева минимум (включительно), справа максимум (включительно).", + "Select rating filters to filter results by. Ratings are stats that aren't seen in the game, but are useful for comparing builds. Left column is min (inclusive) and right column is max (inclusive).": "Рейтинговые фильтры для фильтрации результатов. Рейтинги — это статистика, которая не отображается в игре, но полезна для сравнения билдов. Слева минимум (включительно), справа максимум (включительно)»..", + "Cp - Combat power, as you would find it ingame, but without factoring in skill enhances. Useful for workd boss units.": "Cp - Combat power, так же как в игре (без учета прокачки скилов).", + "HpS - Hp * Speed rating, for comparing fast/health builds, disregaring defense. Example health scaling units: Krau, Fceci.": "HpS - Hp * Speed рейтинг, показывает соотношение HP и Speed.", + "Ehp - Effective Hp, for comparing how much damage a unit can take. Formula: HP * (Defense/300 + 1).": "Ehp - Эфф. Hp, показывает сколько урона может выдержать герой.", + "EhpS - Effective Hp * Speed rating, for comparing fast/tanky builds.": "EhpS - Ehp * Speed рейтинг, показывает соотношение Ehp и Speed.", + "Dmg - Average damage rating, measures how much damage your unit will deal on average, factoring in crit chance & damage.": "Dmg - показывает сколько урона в среднем нанесет ваш герой, с учетом шанса критического удара и урона.", + "DmgS - Average damage * Speed rating, measures average damage vs speed.": "DmgS - Dmg * Speed рейтинг, показывает соотношение Dmg и Speed.", + "Mcd - Max crit damage rating, measures damage at 100% crit chance. Example units: Arby, JKise.": "Mcd - Измеряет рейтинг критического урона при 100% шансе крита.", + "McdS - Max crit damage * Speed rating, measures damage at 100% crit chance vs speed.": "McdS - Mcd * Speed рейтинг, показывает соотношение Mcd и Speed.", + "DmgH - Dmg * Hp rating, average damage rating, scaled by your units health. Useful for HP scaling bruisers.": "DmgH - Dmg * Hp рейтинг, показывает урон героев имеющих скейл от HP.", + "Upg - Number items to upgrade - including reforges and enhances.": "Upg - Количество эквпипа в билде нуждающегося в reforge и enhance.", + "Score - Sum of gear score of all 6 pieces.": "Score - Сумма score гира всех 6 элементов в билде", + "This is the most useful filter but please read before using it. Using this wrong can exclude good results from the search.": "Это самый полезный фильтр, но, пожалуйста, прочтите это перед использованием. Неправильное использование может исключить из поиска хорошие результаты.", + "Assign a priority to each substat type from -1 to 3. This will go through every gear, and calculates the # of max rolls of each stat. The # of rolls is then multiplied by the stat priority you chose. It adds up all the stat scores for a gear, and sorts your gear by their highest substat score.": "Назначьте приоритет каждому стату от -1 до 3. Процесс будет проходить через каждый гир и вычислять количество максимальных проков каждого субстата. Затем количество проков умножается на выбранный вами приоритет статистики. Он суммирует все показатели субстат для гира и сортирует ваш гир по наивысшему значению субстатов.", + "After that, it chooses only the Top X% of scored gears to use for the search.For example, if you select Atk: 3 / Cr: 3 / Cd: 3 / Top 40%, this will use only the best 40% of your gears sorted by Atk / Cr / Cd substats.": " После этого он выбирает только X% лучшего гира для поиска. Например, если вы выберете Atk: 3 / Cr: 3 / Cd: 3 / Топ 40%, будут использоваться только лучшие 40% гира а ваш гир отсортирован по субстатм Atk / Cr / Cd.", + "This filter does nothing when Top X% is 100. I find 40-50% to be a good range to start with, and adjust the Top X% lower/higher based on your own gear and the results you get. Lowering the percent narrows down your best gears to make the search faster, but going too low will exclude possible good builds and will be less optimal.": "Этот фильтр ничего не делает, когда Топ X% равен 100. Я считаю, что 40-50% — это хороший диапазон для начала, и я корректирую Топ X% ниже/выше в зависимости от моего собственного гира и результатов, которые я получаю. Снижение процента уменьшает список лучшего гира, чтобы ускорить поиск, но слишком низкое значение исключает возможные хорошие билды и будет менее оптимальным.", + "This works best when accessory stats and set options are selected.": "Это хорошо работает с другими фильтрами и ускоряет подбор гира.", + "Select the hero you want to optimize.": "Выберете героя для оптимизации.", + "Start - Start a search using the current settings.": "Начать - Начать поиск с текущими фильтрами.", + "Filter - Keep the current optimization results, but re-apply the stat and rating filters. Useful for narrowing down a search.": "Отфильтровать - Применить фильтрацию повторно, полезно для сужения поиска.", + "Cancel - Attempts to cancel an ongoing search. This won't always cancel immediately, if the process is busy.": "Стоп - Остановить поиск, может не сразу сработать во время поиска.", + "Reset filters - Resets all optimization filters to their default values.": "Сбросить фильтры - Сбросить все фильтры до состояния по умолчанию.", + "The left shows your unit's current stats. The middle shows the stats after the stat change. Right side shows the difference.": "Статы это характеристики героя. Слева показаны текущие статы. В центре показаны статы согласно выбранной конфигурации. Справа показана разница.", + "Use reforged stats - Predict the reforged stats on +15 level 85 gear to use in the search. Warning: the substat prediction is not always accurate.": "Учитывать reforge - Определяет reforged статы на +15 прокачке 85 уровня зквипа для для использования в поиске. Внимание: определение статов не всегда точное.", + "Only maxed gear - Search only for builds that contain all +15 and reforged gear.": "Only maxed gear - Search only for builds that contain all +15 and reforged gear.", + "Locked items - Allow locked items in the search.": "Заблок. гир - Учитывать заблокированный гир в поиске.", + "Equipped items - Allow items equipped by other heroes in the search.": "Экип. гир - Учитывать в поиске гир одетый на дргуих героях.", + "Keep current - Keep any existing gears on the unit, and search only for the missing gear pieces.": "Оставить экип. - Учитывает при поиске уже одетый гир и подбирает его только в пустые слоты снаряжения.", + "Exclude equipped - Ignores the dropdown selected units' currently equipped gear in optimization. Only works when 'Equipped items' is checked.": "Исключить гир - Не учитывает снаряжение ВЫБРАНЫХ в выпадающем списке героев. Работает только с 'Экип. гир'.", + "Shows how many pieces of gear will be used in the search, after filters are applied.": "Показывает, сколько гира будет использовано при поиске после применения фильтров.", + "If you notice for example, you only have 2 rings being used, try expanding your filters to use more ring options. Or if you see too much gear being used, reduce your Top % filter to be more selective.": "Например, если вы заметили, что у вас используются только 2 кольца, попробуйте расширить фильтры, чтобы использовать больше колец. Или, если вы видите, что используется слишком много гира, уменьшите фильтр Топ%, чтобы он был более избирательным.", + "Permutations - Number of permutations of the filtered gear that need to be searched. Make this number lower to make searches faster, but you will be searching less options.": "Комбинации - количество комбинаций которые будут просканированы, уменьшайте это чисто путем изменеия фильтров для ускорения процесса поиска.", + "Searched - Number permutations already searched.": "Проверено - количество комбинаций которые были просканированы.", + "Results - Number of search results that satisfy the stat filters. There is a maximum of 5,000,000 results before the search stops (for memory limitations).": "Подобрано - количество комбинаций соответствующее установленным фильтрам.", + "Lock/Unlock Items - Locks/Unlocks the current selected gears that you want to be excluded from other searches.": "Заблокировать/Разблокировать - Блокирует/Разблокировывает текущий выбраный гир который вы хотите исклчюить из поиска", + "Select/Deselect All - Select/Deselects all the items. You can manually check/uncheck each checkbox as well.": "Выбрать все/Отменить выбор - Выбирает/Отменяет выбор гира. Вы так же можете проставить выбор вручную.", + "Save/Remove Build - Saves/Removes the currently selected row as a build. This will mark it with a star, and the build will be visible on the Heroes tab.": "Сохранить/Удалить Билд - Сохраняет/Удаляет текущий выбраный билд. Это пометит билд звездочкой, и он будет виден на вкладке «Герои».", + "View and edit gears here. Multiple gears can be selected with Ctrl + click or Shift + click. The number of selected gear can be found in the top right corner.": "Просмотр и редактирование гира здесь. Несколько предметов можно выбрать с помощью Ctrl + клик или Shift + клик. Колличество выбранного гира можно найти в правом верхнем углу.", + "Score - Gear score. This score measures how well your gear rolled, scaled by the max roll for 85 gear (assuming 4 for speed). Similar to WSS, except flat stats rolls are included. Flat stats account to percentage equivalent was determined using the average stats of 5* units divided by the average flat roll. By this metric, a single flat roll corresponds to ~3.5 Atk %, ~5.0 Def %, ~3.1 Hp %.": "Score - оценка гира. Эта оценка отображает насколько хорошо были получены проки, масштабируется максимальным проком для 85 уровня гира (например 4 скорости). Аналогичен WSS, за исключением того, что включены флат проки статов. Отношение флат стат к процентному эквиваленту было определено с использованием средних стат 5* units, делённых на средний флат прок. По этим подсчетам один флат прок соответствует ~3.5% Atk, ~5.0% Def, ~3.1% Hp.", + "dScore - DPS Score. This is the Score formula but only counting Attack/%, Crit Chance, Crit Damage, and Speed.": "dScore - DPS Score. Это формула подсчета очков, но она учитывает только Attack/%, Crit Chance, Crit Damage, и Speed", + "sScore - Support Score. This is the Score formula but only counting Hp/%, Defense/%, Effect Resist, and Speed.": "sScore - Support Score. Это формула подсчета очков, но она учитывает только Hp/%, Defense/%, Effect Resist, и Speed.", + "cScore - Combat Score. This is the Score formula excluding Effectiveness and Effect Resist.": "cScore - Combat Score. Это формула подсчета очков, но она НЕ учитывает Effectiveness и Effect Resist.", + "Edit Selected Item - Change an items stats, levels, or equip it onto someone.": "Изменить - Изменить статы гира, уровень, или экипировать его на кого-то.", + "Reforge Item - Only works on +15 level 85 gears, predicts the item's reforged stats and generates the edited version.": "Выполнить Reforge - Работает только с гиром 85 уровня прокаченного до +15, прибавляет гиру статы как после Reforge.", + "Add New Item - Create a new item and fill in its stats.": "Добавить - Добавить новый предмет.", + "Duplicate Item - Create a copy of the selected item and lets you change its stats.": "Дублировать - Дублировать выбраный предмет.", + "Remove Items - Unequips and then deletes the items. Multiple selection enabled.": "Удалить - Снять и удалить выбраный предмет.", + "Unequip Items - Unequips the items from their units. Multiple selection enabled.": "Снять - Снять выбраный предмет с героя.", + "Lock/Unlock Items - Locks/Unlocks the items that you want to be excluded from searches.": "Заблокировать/Разблокировать - Блокирует/Разблокировывает выбраный предмет который вы хотите исключить из поиска.", + "Select filters to filter the gear table by. Only one filter allowed per section for now.": "Выберите фильтры для сортировки гиртейбла.", + "Use the Duplicates filter to find gear with the same stats, and remove if they were mistakenly added.": "Используйте фильтр «Дубликаты», чтобы найти гир с одинаковыми статами и удалить, если он был добавлен по ошибке.", + "Start a search using the current settings.": "Start a search using the current settings.", + "Info": "Инфо", + "No stat priority selected. For best results, use the stat priority filter.": "No stat priority selected. For best results, use the stat priority filter.", + "No sets were selected. For best results, select at least one set.": "No sets were selected. For best results, select at least one set.", + "No accessory main stats were selected. For best results, use the main stat filter to narrow down the search.": "No accessory main stats were selected. For best results, use the main stat filter to narrow down the search.", + "Score = Attack %
": "Score = Attack %
", + "+ Defense %
": "+ Defense %
", + "+ Hp %
": "+ Hp %
", + "+ Effectiveness
": "+ Effectiveness
", + "+ Effect Resistance
": "+ Effect Resistance
", + "+ Speed * (8/4)
": "+ Speed * (8/4)
", + "+ Crit Damage * (8/7)
": "+ Crit Damage * (8/7)
", + "+ Crit Chance * (8/5)
": "+ Crit Chance * (8/5)
", + "+ Flat Attack * 3.46 / 39
": "+ Flat Attack * 3.46 / 39
", + "+ Flat Defense * 4.99 / 31
": "+ Flat Defense * 4.99 / 31
", + "+ Flat Hp * 3.09 / 174
": "+ Flat Hp * 3.09 / 174
", + "Loading...": "Loading...", + "Nobody": "Никто", + "Type": "Тип", + "Weapon": "", + "Helmet": "Шлем", + "Armor": "Броня", + "Reforge": "Reforge", + "Hunt": "Hunt", + "Conversion": "Conversion", + "Epic": "Epic", + "Heroic": "Heroic", + "Rare": "Rare", + "Good": "Good", + "Normal": "Normal", + "Main Stat": "Мейнстат", + "Substat 1": "Субстат 1", + "Substat 2": "Субстат 2", + "Substat 3": "Субстат 3", + "Substat 4": "Субстат 4", + "Success": "Success", + "Warning": "Warning", + "Alert": "Alert", + "Select one item to duplicate.": "Select one item to duplicate.", + "Select one item to edit.": "Select one item to edit.", + "Select one item to reforge.": "Select one item to reforge.", + "Select a build to edit.": "Select a build to edit.", + "Nothing to export yet, please follow the steps to import gear": "Nothing to export yet, please follow the steps to import gear", + "Edited item": "Edited item", + "Invalid filename": "Invalid filename", + "AND": "AND", + "OR": "OR", + "yes": "да", + "Yes": "Да", + "no": "нет", + "Hero needs a 6 item build before it can be saved": "Hero needs a 6 item build before it can be saved", + "Error": "Ошибка", + "Failed reading items, please try again. Unable to read items.": "Failed reading items, please try again. Unable to read items.", + "Failed reading items, please try again. No items were found.": "Failed reading items, please try again. No items were found.", + "Failed reading items, please try again. ": "Failed reading items, please try again. ", + "Item reading failed, please try again.": "Item reading failed, please try again.", + "

There were ": "

There were ", + " items with issues.
Use the Level=0 filter to fix them on the Heroes Tab.": "
items with issues.
Use the Level=0 filter to fix them on the Heroes Tab.", + "Finished scanning ": "Finished scanning ", + " items.": " items.", + "Unable to start python script ": "Unable to start python script ", + "Started scanning...": "Started scanning...", + "No scan was started": "No scan was started", + "Reading items, this may take up to 30 seconds...\nData will appear here after it is done.": "Reading items, this may take up to 30 seconds...\nData will appear here after it is done.", + "Failed to start scanning, make sure you have Python and pcap installed.": "Failed to start scanning, make sure you have Python and pcap installed.", + "Please make sure Type / Set / Rank / Level / Enhance / Main stat are not empty": "Пожалуйста, убедитесь, что тип / сет / редкость / уровень / enhance / мейнстат не пусты.", + "Please make sure +15 items have 4 substats": "Please make sure +15 items have 4 substats", + "Item enhance can only be 0 - 15": "Item enhance can only be 0 - 15", + "No": "Нет", + "Locked 0 item(s).": "Locked 0 item(s).", + "Unlocked 0 item(s).": "Unlocked 0 item(s).", + "Removed 0 item(s).": "Removed 0 item(s).", + "Stat priority was selected but the filter is set to Top 100%. The stat priority filter is only useful when the % is not 100.": "Stat priority was selected but the filter is set to Top 100%. The stat priority filter is only useful when the % is not 100.", + "Your minimum defense filter is over 10,000, did you mean HP?": "Your minimum defense filter is over 10,000, did you mean HP?", + "New saves folder": "New saves folder", + "Top % was selected but no stat priorities are assigned. Assign stat priorities otherwise the filter will not work.": "Top % was selected but no stat priorities are assigned. Assign stat priorities otherwise the filter will not work.", + "Over 5 billion permutations selected. For faster results, try applying stricter filters or using a lower Top N%.": "Over 5 billion permutations selected. For faster results, try applying stricter filters or using a lower Top N%.", + "Search terminated after the result limit was exceeded, the full results are not shown. Please apply more filters to narrow your search.": "Search terminated after the result limit was exceeded, the full results are not shown. Please apply more filters to narrow your search.", + "Invalid sets, the first set filter must be either all 4 piece or all 2 piece sets.": "Invalid sets, the first set filter must be either all 4 piece or all 2 piece sets.", + "Failed to read a screenshot: Error: Could not find MIME for Buffer ": "Failed to read a screenshot: Error: Could not find MIME for Buffer ", + "Failed to read a screenshot: Could not read stats from screenshot. Make sure your screenshots are 1600x900, English, and with High Quality Support enabled.": "Failed to read a screenshot: Could not read stats from screenshot. Make sure your screenshots are 1600x900, English, and with High Quality Support enabled.", + "Failed to read a screenshot: Error: Unsupported MIME type: application/x-rar-compressed": "Failed to read a screenshot: Error: Unsupported MIME type: application/x-rar-compressed", + "Finished reading screenshots": "Finished reading screenshots", + "Screenshot reading in progress, please wait": "Screenshot reading in progress, please wait", + "Item reading in progress, please wait": "Item reading in progress, please wait", + "Parsing data..": "Parsing data..", + "Unable to write file": "Unable to write file", + "Imported": "Imported", + "Loaded": "Loaded", + "Merged": "Merged", + "Appended": "Appended", + "Finished reading": "Finished reading", + "screenshots.": "screenshots.", + "screenshots succeded": "screenshots succeded", + "failed": "failed", + "Failed files are:": "Failed files are:", + "Reading data from": "Reading data from", + "heroes and": "heroes and", + "items from": "items from", + "Exported data to": "Exported data to", + "OCR error ": "OCR error ", + "Reading screenshots in progress...\nSucceeded: ": "Reading screenshots in progress...\nSucceeded: ", + "\nFailed: ": "\nFailed: ", + "Failed to read a screenshot: Error: EISDIR: illegal operation on a directory, read": "Failed to read a screenshot: Error: EISDIR: illegal operation on a directory, read", + "Failed to read a screenshot: ": "Failed to read a screenshot: ", + "Error occurred while reading screenshots": "Error occurred while reading screenshots", + "Eaton's 20% total Health bonus from S2 is already automatically added.": "Eaton's 20% total Health bonus from S2 is already automatically added.", + "Gunther's 75% total Attack bonus from S2 is already automatically added.": "Gunther's 75% total Attack bonus from S2 is already automatically added.", + "Lena's 50% Crit Chance bonus from S2 is already automatically added.": "Lena's 50% Crit Chance bonus from S2 is already automatically added.", + "Apocalypse Ravi's 30% Crit Chance bonus from S2 is already automatically added.": "Apocalypse Ravi's 30% Crit Chance bonus from S2 is already automatically added.", + "New version available: ": "New version available: ", + "Modification": "Modification", + "Information": "Информация", + "rank": "ранг", + "Use hero priority": "Приоритет героя", + "Use substat mods": "Субстат мод", + "Prio": "Prio", + "prio": "prio", + "Conv": "Conv", + "Unequipped": "Не одето", + "Add Substat Mods": "Субстат Мод", + "Add Artifact/EE/Imprint bonus stats": "Добавить Артефакт/EE/Импринт (учитывается в статах)", + "Stars": "Stars", + "6 stars max awaken": "6 звезд и полное пробуждение", + "5 stars max awaken": "5 звезд и полное пробуждение", + "Add any other stats": "Add any other stats", + "Rank #": "Ранг #", + "Set Hero Rank": "Установить Ранг", + "Save / Load optimizer data": "Сохранить / Загрузить данные оптимизатора", + "Import gear automatically": "Импортировать гир автоматически", + "This importer will scan for only your gear. Instructions:": "Здесь вы можете импортировать ваше снаряжение. Инструкции:", + "Import heroes and gear automatically": "Импортировать героев и гир автоматически", + "This importer will scan for your gears and the heroes that they're equipped on. Your build in the optimizer will be replaced with your ingame build. Instructions:": "This importer will scan for your gears and the heroes that they're equipped on. Your build in the optimizer will be replaced with your ingame build. Instructions:", + "Only import optimizer heroes": "Импортировать только героев оптимизатора", + "Import all 6 star heroes": "Импортировать всех 6 звездочных героев", + "Import all 5+ star heroes": "Импортировать всех 5-6 звездочных героев", + "Import gear from screenshots": "Импорт гира по скриншотам", + "Erase all optimizer data": "Удалить все данные о гире и героях", + "NOTE: The screenshot tool has some issues importing data accurately since the item backgrounds were changed. The automatic importer is recommended.": "NOTE: The screenshot tool has some issues importing data accurately since the item backgrounds were changed. The automatic importer is recommended.", + "New Hero Optimizer Settings": "New Hero Optimizer Settings", + "Custom Dark Mode Colors": "Пользовательские цвета темного режима", + "General": "General", + "Grid": "Grid", + "Background color": "Background color", + "Text color": "Text color", + "Accent color": "Accent color", + "Textbox/Button color": "Textbox/Button color", + "Red color": "Red color", + "Neutral color": "Neutral color", + "Green color": "Green color", + "(reset)": "(reset)", + "Use merge to update all your gear with new screenshots.": "Use merge to update all your gear with new screenshots.", + "Use add only if you're using screenshots and want to update a small number of gears. Can cause duplicate gear if the screenshots include existing gear.": "Use add only if you're using screenshots and want to update a small number of gears. Can cause duplicate gear if the screenshots include existing gear.", + "Check for updates": "Check for updates", + "Cp - Combat power, as you would find it ingame, but without factoring in skill enhances. Useful for world boss units.": "Cp - Combat power, так же как в игре (без учета прокачки скилов).", + "Prio - Sum of priority score of all 6 pieces, calculated using the Substat Priority filter values.": "Prio - Sum of priority score of all 6 pieces, calculated using the Substat Priority filter values.", + "Upg - Number of items to upgrade - including reforges and enhances. When substat mods are enabled, modified gear is considered upgradable.": "Upg - Количество эквпипа в билде нуждающегося в улучшении (reforge и enhance). Когда субстат мод включен, замены статов с помощью modification stones так же считаются улучшением.", + "Conv - Number of conversion material reforges in the results.": "Conv - Количество эквпипа в билде нуждающегося в reforge за conversion material (созданый в Сonversion).", + "Substat modification priority": "Приоритет модифификации Субстатов", + "Limit Rolls": "Лимит Замен", + "Mod Grade": "Качество stones", + "Roll Quality": "Диапазон", + "Wanted Stats": "Ремод", + "Substat selections": "Выбор субстатов", + "Wanted substats": "Нужное:", + "Don't change": "Неизменяемое:", + "Unwanted substats": "Ненужное:", + "Lesser": "Обычные", + "Greater": "Редкие", + "Never replace wanted stats": "Не заменять субстат повтроно", + "Allow replacing wanted with wanted": "Заменять субстат повтроно", + "Choose the maximum number of rolls to replace. For example, limit rolls = 1 would only replace base stats that didn't get enhanced. It is generally not a good idea to replace more than 2 rolls, and the higher this number is, the more permutations will be generated.": "Choose the maximum number of rolls to replace. For example, limit rolls = 1 would only replace base stats that didn't get enhanced. It is generally not a good idea to replace more than 2 rolls, and the higher this number is, the more permutations will be generated.", + "Choose whether to use Greater or Lesser gem stats.": "Choose whether to use Greater or Lesser gem stats.", + "Choose the modified substat's roll value, from min roll to max roll. The actual value ingame will be random. Values will be rounded to the nearest whole number.": "Choose the modified substat's roll value, from min roll to max roll. The actual value ingame will be random. Values will be rounded to the nearest whole number.", + "Choose whether wanted stats should be allowed to be replaced with wanted stats when optimizing. For example, when allowed, a min speed roll could be replaced by a max speed roll. When not allowed, the speed will be left unmodified.": "Choose whether wanted stats should be allowed to be replaced with wanted stats when optimizing. For example, when allowed, a min speed roll could be replaced by a max speed roll. When not allowed, the speed will be left unmodified.", + "Choose the substats that you want to modify for. Substats in the unwanted column will be replaced by substats in wanted column.": "Choose the substats that you want to modify for. Substats in the unwanted column will be replaced by substats in wanted column.", + "Choose the substats to not modify. Substats in this column will not get replaced, and will also not be selected for.": "Choose the substats to not modify. Substats in this column will not get replaced, and will also not be selected for.", + "Choose the substats that you want to discard when modifying. Substats in the unwanted column will be replaced by substats in wanted column.": "Choose the substats that you want to discard when modifying. Substats in the unwanted column will be replaced by substats in wanted column.", + "Use hero priority - Only use gear from lower priority heroes. Hero priority is defined by the unfiltered/unsorted order of heroes on the Hero tab. When enabled, your hero will only take gear from heroes that are below them on the list.": "Приоритет героя - Используйте гир только от героев с более низким приоритетом. Приоритет героя определяется с нефильтрованным/несортированным порядком героев на вкладке «Герои», для установки приоритета взаимодействуйте со столбиком «Ранг». Если эта опция включена, ваш герой будет брать гир только у героев, которые находятся ниже его по приоритету.", + "Use substat mods - Run the optimization using substat modification stones. Each hero's optimization settings must first be selected on the heroes tab before this can be used.": "Субстат мод - Запустите оптимизацию, используя modification stones субстатов. Настройте субстат мод для выбраного героя/героев на вкладке «Герои» кнопкой «Субстат мод», прежде чем использовать эту опцию.", + "Senya's 30% total Attack bonus from S2 is already automatically added.": "Senya's 30% total Attack bonus from S2 is already automatically added.", + "Current version": "Current version", + "Links": "Links", + "Join the optimizer Discord server for tech support, suggestions, and announcements.": "Join the optimizer Discord server for tech support, suggestions, and announcements.", + "Instructions and guides can be found on the GitHub page, along with new version downloads.": "Instructions and guides can be found on the GitHub page, along with new version downloads.", + "Support the optimizer and future updates!": "Support the optimizer and future updates!", + "Thank you": "Thank you", + "A special thank you to the wonderful people that have contributed and helped make the optimizer possible:": "A special thank you to the wonderful people that have contributed and helped make the optimizer possible:", + "I want to thank the entire community for all the love and support that you've shown for the optimizer. This project has been a bunch of fun to build, and I hope you find it just as enjoyable to optimize and gear your favorite characters. Please feel free to reach out to me on the Discord server for setup help, ideas and suggestions, signing up as beta tester, or just come by to chat!": "I want to thank the entire community for all the love and support that you've shown for the optimizer. This project has been a bunch of fun to build, and I hope you find it just as enjoyable to optimize and gear your favorite characters. Please feel free to reach out to me on the Discord server for setup help, ideas and suggestions, signing up as beta tester, or just come by to chat!", + "Taokonn - for the user interface design and user experience research and guidance": "Taokonn - for the user interface design and user experience research and guidance", + "TriATK - for all your contributions to the codebase and making translations possible": "TriATK - for all your contributions to the codebase and making translations possible", + "Somax - for creating the dark mode and making the optimizer usable at night": "Somax - for creating the dark mode and making the optimizer usable at night", + "Translation team - for helping to make the optimizer accessible for multiple languages": "Translation team - for helping to make the optimizer accessible for multiple languages", + "Beta testers - for helping to find bugs and providing valuable feedback": "Beta testers - for helping to find bugs and providing valuable feedback", + "Use merge to update all your gear with new screenshots.": "Use merge to update all your gear with new screenshots.", + "Use add only if you're using screenshots and want to update a small number of gears. Can cause duplicate gear if the screenshots include existing gear.": "Use add only if you're using screenshots and want to update a small number of gears. Can cause duplicate gear if the screenshots include existing gear.", + "Install requirements from the instructions on Github": "Устанвоите софт отсюда: instructions on Github", + "Leave your emulator open, and close Epic 7": "Оставьте эмулятор Андроида открытым, закройте Epic 7", + "Click the Start scanning button below": "Нажмите кнопку Начать сканирование", + "Open Epic 7, and load into the lobby": "Откройте Epic 7, дождитесь загрузки до лобби (это там где сидят герои)", + "Click the Stop scanning button below": "Нажмите кнопку Остановить сканирование", + "Wait up to 30 secs, then once the data appears, click Export to save it to a 'gear.txt'": "Подождите номного пока появятся данные, затем, нажмите Экспорт для сохранения данных сканирования в 'gear.txt''", + "Import the 'gear.txt' with the Merge option": "Импортируйте 'gear.txt' кнопкой Импорт данных", + "If the message tells you to, use the Level = 0 filter to manually fix any level 0 items on the Gear tab": "Если видите сообщение об ошибке Level=0, то нужно будет вручную проставить уровень в Эквипе для таких предметов", + "Unable to save file. Please try disabling your antivirus, or add the app as an exception, then restarting the app in admin mode.": "Unable to save file. Please try disabling your antivirus, or add the app as an exception, then restarting the app in admin mode.", + "Nothing to export yet, please select a folder": "Nothing to export yet, please select a folder", + "Error occurred while parsing gear. Check that you have 64-bit version of Java 8 installed and try again.": "Error occurred while parsing gear. Check that you have 64-bit version of Java 8 installed and try again.", + "Java process failed. Please try restarting your app and check that you've installed the correct version of Java": "Java process failed. Please try restarting your app and check that you've installed the correct version of Java", + "Unable to load data from Epic7DB - ": "Unable to load data from Epic7DB - ", + "Cannot calculate reforged stats. Find the item and fix it: ": "Cannot calculate reforged stats. Find the item and fix it: ", + "Invalid save data": "Invalid save data", + "Unable to create the Documents/FribbelsOptimizerSaves folder. Try disabling running the app as admin and disabling your virus scan": "Unable to create the Documents/FribbelsOptimizerSaves folder. Try disabling running the app as admin and disabling your virus scan", + "Java subprocess errors": "Java subprocess errors", + "Failed to send string to subprocess": "Failed to send string to subprocess", + "Substat mods are enabled, but the hero's 'Keep' substat list is empty. Please use 'Add Substat Mods' button on the Heroes tab to adjust your mod preferences": "Substat mods are enabled, but the hero's 'Keep' substat list is empty. Please use 'Add Substat Mods' button on the Heroes tab to adjust your mod preferences", + "Invalid sets, fill in the set filters from top to bottom.": "Invalid sets, fill in the set filters from top to bottom.", + "Unexpected error while scanning items. Please check that you have Python and Wireshark installed correctly, then try again. Error: ": "Unexpected error while scanning items. Please check that you have Python and Wireshark installed correctly, then try again. Error: ", + "Update downloaded. It will be installed on restart. Restart app now?": "Update downloaded. It will be installed on restart. Restart app now?", + "Add new items to your existing items? This can cause duplicate items if screenshots include existing gear. Use this only for the screenshot importer. If you want to update your existing gear with new screenshots, use the Merge option instead.": "Add new items to your existing items? This can cause duplicate items if screenshots include existing gear. Use this only for the screenshot importer. If you want to update your existing gear with new screenshots, use the Merge option instead.", + "Are you sure you want to overwrite the optimizer's hero data with ingame hero data?": "Are you sure you want to overwrite the optimizer's hero data with ingame hero data?", + "Unable to detect java version": "Unable to detect java version", + "Only +15 level 85 gear can be reforged.": "Only +15 level 85 gear can be reforged.", + "Abyss lifesteal set (Gaveleet's) cannot be reforged": "Abyss lifesteal set (Gaveleet's) cannot be reforged", + "Optimization already in progress. Please cancel before starting a new search.": "Optimization already in progress. Please cancel before starting a new search.", + "Your hero does not have an artifact equipped, use the 'Add Bonus Stats' button on the Heroes page to add artifact stats": "Your hero does not have an artifact equipped, use the 'Add Bonus Stats' button on the Heroes page to add artifact stats", + "New version available, downloading now": "New version available, downloading now", + "No new updates found": "No new updates found", + "Checking for updates": "Checking for updates", + "Saved mod stats": "Saved mod stats", + "Saved bonus stats": "Saved bonus stats", + "Reforged item": "Reforged item", + "Added item": "Added item", + "Removed ": "Removed ", + "Locked ": "Locked ", + "Unequipped ": "Unequipped ", + "Unlocked ": "Unlocked ", + " item(s).": " item(s).", + "Unlocked item": "Unlocked item", + "Locked item": "Locked item", + "Disable mods": "Disable mods", + "Mods": "Mods", + "Erase data": "УДАЛИТЬ ВСЕ", + "Erase all heroes/gear/builds from optimizer?": "Удалить все?", + "Finished erasing data": "Удаление данных завершено ", + "HeroesArtifactsSection": "HeroesArtifactsSection", + "Alencia": "Alencia", + "Ambitious Tywin": "Ambitious Tywin", + "Apocalypse Ravi": "Apocalypse Ravi", + "Aramintha": "Aramintha", + "Arbiter Vildred": "Arbiter Vildred", + "Archdemon's Shadow": "Archdemon's Shadow", + "Baal & Sezan": "Baal & Sezan", + "Baiken": "Baiken", + "Basar": "Basar", + "Bellona": "Bellona", + "Blood Moon Haste": "Blood Moon Haste", + "Briar Witch Iseria": "Briar Witch Iseria", + "Cecilia": "Cecilia", + "Celine": "Celine", + "Cerise": "Cerise", + "Cermia": "Cermia", + "Charles": "Charles", + "Charlotte": "Charlotte", + "Chloe": "Chloe", + "Choux": "Choux", + "Dark Corvus": "Dark Corvus", + "Desert Jewel Basar": "Desert Jewel Basar", + "Designer Lilibet": "Designer Lilibet", + "Destina": "Destina", + "Diene": "Diene", + "Dizzy": "Dizzy", + "Eda": "Eda", + "Elena": "Elena", + "Elphelt": "Elphelt", + "Ervalen": "Ervalen", + "Fairytale Tenebria": "Fairytale Tenebria", + "Faithless Lidica": "Faithless Lidica", + "Fallen Cecilia": "Fallen Cecilia", + "Flan": "Flan", + "Haste": "Haste", + "Holiday Yufine": "Holiday Yufine", + "Iseria": "Iseria", + "Judge Kise": "Judge Kise", + "Kawerik": "Kawerik", + "Kayron": "Kayron", + "Ken": "Ken", + "Kise": "Kise", + "Krau": "Krau", + "Landy": "Landy", + "Last Rider Krau": "Last Rider Krau", + "Lidica": "Lidica", + "Lilias": "Lilias", + "Lilibet": "Lilibet", + "Little Queen Charlotte": "Little Queen Charlotte", + "Ludwig": "Ludwig", + "Luluca": "Luluca", + "Luna": "Luna", + "Maid Chloe": "Maid Chloe", + "Martial Artist Ken": "Martial Artist Ken", + "Melissa": "Melissa", + "Mort": "Mort", + "Mui": "Mui", + "Muse Rima": "Muse Rima", + "Operator Sigret": "Operator Sigret", + "Pavel": "Pavel", + "Politis": "Politis", + "Ravi": "Ravi", + "Ray": "Ray", + "Remnant Violet": "Remnant Violet", + "Roana": "Roana", + "Ruele of Light": "Ruele of Light", + "Sage Baal & Sezan": "Sage Baal & Sezan", + "Seaside Bellona": "Seaside Bellona", + "Sez": "Sez", + "Sigret": "Sigret", + "Silver Blade Aramintha": "Silver Blade Aramintha", + "Sol": "Sol", + "Specimen Sez": "Specimen Sez", + "Specter Tenebria": "Specter Tenebria", + "Tamarinne": "Tamarinne", + "Tenebria": "Tenebria", + "Top Model Luluca": "Top Model Luluca", + "Tywin": "Tywin", + "Vildred": "Vildred", + "Violet": "Violet", + "Vivian": "Vivian", + "Yufine": "Yufine", + "Yuna": "Yuna", + "Zeno": "Zeno", + "Achates": "Achates", + "Angelica": "Angelica", + "Armin": "Armin", + "Assassin Cartuja": "Assassin Cartuja", + "Assassin Cidd": "Assassin Cidd", + "Assassin Coli": "Assassin Coli", + "Auxiliary Lots": "Auxiliary Lots", + "Benevolent Romann": "Benevolent Romann", + "Blaze Dingo": "Blaze Dingo", + "Blood Blade Karin": "Blood Blade Karin", + "Cartuja": "Cartuja", + "Celestial Mercedes": "Celestial Mercedes", + "Challenger Dominiel": "Challenger Dominiel", + "Champion Zerato": "Champion Zerato", + "Cidd": "Cidd", + "Clarissa": "Clarissa", + "Coli": "Coli", + "Corvus": "Corvus", + "Crescent Moon Rin": "Crescent Moon Rin", + "Crimson Armin": "Crimson Armin", + "Crozet": "Crozet", + "Dingo": "Dingo", + "Dominiel": "Dominiel", + "Fighter Maya": "Fighter Maya", + "Free Spirit Tieria": "Free Spirit Tieria", + "Furious": "Furious", + "General Purrgis": "General Purrgis", + "Great Chief Khawana": "Great Chief Khawana", + "Guider Aither": "Guider Aither", + "Karin": "Karin", + "Khawana": "Khawana", + "Khawazu": "Khawazu", + "Kitty Clarissa": "Kitty Clarissa", + "Kizuna AI": "Kizuna AI", + "Leo": "Leo", + "Lots": "Lots", + "Lucy": "Lucy", + "Maya": "Maya", + "Mercedes": "Mercedes", + "Purrgis": "Purrgis", + "Rin": "Rin", + "Roaming Warrior Leo": "Roaming Warrior Leo", + "Romann": "Romann", + "Rose": "Rose", + "Schuri": "Schuri", + "Serila": "Serila", + "Shadow Rose": "Shadow Rose", + "Shooting Star Achates": "Shooting Star Achates", + "Silk": "Silk", + "Sinful Angelica": "Sinful Angelica", + "Surin": "Surin", + "Tempest Surin": "Tempest Surin", + "Troublemaker Crozet": "Troublemaker Crozet", + "Wanderer Silk": "Wanderer Silk", + "Watcher Schuri": "Watcher Schuri", + "Zerato": "Zerato", + "Adlay": "Adlay", + "Adventurer Ras": "Adventurer Ras", + "Ainos": "Ainos", + "Ains": "Ains", + "Aither": "Aither", + "Alexa": "Alexa", + "All-Rounder Wanda": "All-Rounder Wanda", + "Angelic Montmorancy": "Angelic Montmorancy", + "Arowell": "Arowell", + "Azalea": "Azalea", + "Bask": "Bask", + "Batisse": "Batisse", + "Butcher Corps Inquisitor": "Butcher Corps Inquisitor", + "Captain Rikoris": "Captain Rikoris", + "Carmainerose": "Carmainerose", + "Carrot": "Carrot", + "Celeste": "Celeste", + "Chaos Inquisitor": "Chaos Inquisitor", + "Chaos Sect Axe": "Chaos Sect Axe", + "Church of Ilryos Axe": "Church of Ilryos Axe", + "Commander Lorina": "Commander Lorina", + "Doll Maker Pearlhorizon": "Doll Maker Pearlhorizon", + "Doris": "Doris", + "Eaton": "Eaton", + "Elson": "Elson", + "Enott": "Enott", + "Falconer Kluri": "Falconer Kluri", + "Glenn": "Glenn", + "Gloomyrain": "Gloomyrain", + "Godmother": "Godmother", + "Gunther": "Gunther", + "Hataan": "Hataan", + "Hazel": "Hazel", + "Helga": "Helga", + "Hurado": "Hurado", + "Ian": "Ian", + "Jecht": "Jecht", + "Jena": "Jena", + "Judith": "Judith", + "Kikirat v2": "Kikirat v2", + "Kiris": "Kiris", + "Kluri": "Kluri", + "Lena": "Lena", + "Lorina": "Lorina", + "Magic Scholar Doris": "Magic Scholar Doris", + "Mascot Hazel": "Mascot Hazel", + "Mercenary Helga": "Mercenary Helga", + "Mirsa": "Mirsa", + "Mistychain": "Mistychain", + "Montmorancy": "Montmorancy", + "Mucacha": "Mucacha", + "Nemunas": "Nemunas", + "Otillie": "Otillie", + "Pearlhorizon": "Pearlhorizon", + "Pyllis": "Pyllis", + "Ras": "Ras", + "Requiemroar": "Requiemroar", + "Researcher Carrot": "Researcher Carrot", + "Righteous Thief Roozid": "Righteous Thief Roozid", + "Rikoris": "Rikoris", + "Rima": "Rima", + "Roozid": "Roozid", + "Sonia": "Sonia", + "Sven": "Sven", + "Taranor Guard": "Taranor Guard", + "Taranor Royal Guard": "Taranor Royal Guard", + "Tieria": "Tieria", + "Wanda": "Wanda", + "Zealot Carmainerose": "Zealot Carmainerose", + "Bomb Model Kanna": "Bomb Model Kanna", + "Ilynav": "Ilynav", + "Inferno Khawazu": "Inferno Khawazu", + "Mediator Kawerik": "Mediator Kawerik", + "Mighty Scout": "Mighty Scout", + "Senya": "Senya", + "Solitaria of the Snow": "Solitaria of the Snow", + "Wild Angara": "Wild Angara", + "Closer Charles": "Closer Charles", + "Camilla": "Camilla", + "Christy": "Christy", + "Helen": "Helen", + "Melany": "Melany", + "Penelope": "Penelope", + "Rem": "Rem", + "Ram": "Ram", + "Emilia": "Emilia", + "Summertime Iseria": "Summertime Iseria", + "Straze": "Straze", + "Angel of Light Angelica": "Angel of Light Angelica", + "Belian": "Belian", + "A Little Queen's Huge Crown": "A Little Queen's Huge Crown", + "Abyssal Crown": "Abyssal Crown", + "Alabastron": "Alabastron", + "Alencinox's Wrath": "Alencinox's Wrath", + "Alexa's Basket": "Alexa's Basket", + "Ancient Dragon's Legacy": "Ancient Dragon's Legacy", + "Bastion of Perlutia": "Bastion of Perlutia", + "Black Hand of the Goddess": "Black Hand of the Goddess", + "Blood-Seared Moon": "Blood-Seared Moon", + "Bloodstone": "Bloodstone", + "Bloody Rose": "Bloody Rose", + "Border Coin": "Border Coin", + "Celestine": "Celestine", + "Champion's Trophy": "Champion's Trophy", + "Chatty": "Chatty", + "Circus Fantasia": "Circus Fantasia", + "Cradle of Life": "Cradle of Life", + "Creation & Destruction": "Creation & Destruction", + "Crimson Moon of Nightmares": "Crimson Moon of Nightmares", + "Crown of Glory": "Crown of Glory", + "Cruel Mischief": "Cruel Mischief", + "Dignus Orb": "Dignus Orb", + "Doctor's Bag": "Doctor's Bag", + "Double-Edged Decrescent": "Double-Edged Decrescent", + "Draco Plate": "Draco Plate", + "Durandal": "Durandal", + "Dux Noctis": "Dux Noctis", + "Elbris Ritual Sword": "Elbris Ritual Sword", + "Etica's Scepter": "Etica's Scepter", + "Fairy Tale for a Nightmare": "Fairy Tale for a Nightmare", + "Guiding Light": "Guiding Light", + "Holy Sacrifice": "Holy Sacrifice", + "Idol's Cheer": "Idol's Cheer", + "Iron Fan": "Iron Fan", + "Junkyard Dog": "Junkyard Dog", + "Justice for All": "Justice for All", + "Knowledge Seed": "Knowledge Seed", + "Last Teatime": "Last Teatime", + "Manica of Control": "Manica of Control", + "Manifu": "Manifu", + "Merciless Glutton": "Merciless Glutton", + "Ms. Confille": "Ms. Confille", + "Necro & Undine": "Necro & Undine", + "Noble Oath": "Noble Oath", + "Otherworldly Machinery": "Otherworldly Machinery", + "Proof of Valor": "Proof of Valor", + "Reingar's Special Drink": "Reingar's Special Drink", + "Rhianna & Luciella": "Rhianna & Luciella", + "Rise of a Monarch": "Rise of a Monarch", + "Rod of Amaryllis": "Rod of Amaryllis", + "Samsara Prayer Beads": "Samsara Prayer Beads", + "Secret Art - Storm Sword": "Secret Art - Storm Sword", + "Shepherd of the Hollow": "Shepherd of the Hollow", + "Shimadra Staff": "Shimadra Staff", + "Sigurd Scythe": "Sigurd Scythe", + "Snow Crystal": "Snow Crystal", + "Song of Stars": "Song of Stars", + "Spirit's Breath": "Spirit's Breath", + "Star Piercer": "Star Piercer", + "Stella Harpa": "Stella Harpa", + "Sword of Ezera": "Sword of Ezera", + "Sword of Holy Light": "Sword of Holy Light", + "Sword of Judgment": "Sword of Judgment", + "Sword of Summer Twilight": "Sword of Summer Twilight", + "Time Matter": "Time Matter", + "Torn Sleeve": "Torn Sleeve", + "Touch of Rekos": "Touch of Rekos", + "Uberius's Tooth": "Uberius's Tooth", + "Unfading Memories": "Unfading Memories", + "Unseen Observer": "Unseen Observer", + "Violet Talisman": "Violet Talisman", + "Wall of Order": "Wall of Order", + "Wind Rider": "Wind Rider", + "Adamant Shield": "Adamant Shield", + "Ambrote": "Ambrote", + "Andre's Crossbow": "Andre's Crossbow", + "Aurius": "Aurius", + "Barthez's Orbuculum": "Barthez's Orbuculum", + "Bloody Warhammer": "Bloody Warhammer", + "Card of Small Miracles": "Card of Small Miracles", + "Celestial Spear": "Celestial Spear", + "Crimson Seed": "Crimson Seed", + "Dust Devil": "Dust Devil", + "El's Fist": "El's Fist", + "Elyha's Knife": "Elyha's Knife", + "Eternus": "Eternus", + "Flower Shower": "Flower Shower", + "Golden Cocoa Cookie": "Golden Cocoa Cookie", + "Hell Cutter": "Hell Cutter", + "Hilag Lance": "Hilag Lance", + "Iela Violin": "Iela Violin", + "Infinity Basket": "Infinity Basket", + "Kal'adra": "Kal'adra", + "Love Potion": "Love Potion", + "Magaraha's Tome": "Magaraha's Tome", + "Midnight Bloom": "Midnight Bloom", + "Moonlight Dreamblade": "Moonlight Dreamblade", + "New Year Cookies": "New Year Cookies", + "One Year of Gratitude": "One Year of Gratitude", + "Portrait of the Saviors": "Portrait of the Saviors", + "Radiant Forever": "Radiant Forever", + "Rainbow Scale": "Rainbow Scale", + "Rosa Hargana": "Rosa Hargana", + "Santa Muerte": "Santa Muerte", + "Sashe Ithanes": "Sashe Ithanes", + "Sepulcrum": "Sepulcrum", + "Shepherds of Chaos": "Shepherds of Chaos", + "Silver Rain": "Silver Rain", + "Sira-Ren": "Sira-Ren", + "Spooky Solayu Stories": "Spooky Solayu Stories", + "Steadfast Gatekeeper": "Steadfast Gatekeeper", + "Strak Gauntlet": "Strak Gauntlet", + "Succubus Mirror": "Succubus Mirror", + "Tagehel's Ancient Book": "Tagehel's Ancient Book", + "Tear of the Desert": "Tear of the Desert", + "To a New World": "To a New World", + "Water's Origin": "Water's Origin", + "Wondrous Potion Vial": "Wondrous Potion Vial", + "XVI. The Tower": "XVI. The Tower", + "Alsacian Spear": "Alsacian Spear", + "Ancient Sheath": "Ancient Sheath", + "Aqua Rose": "Aqua Rose", + "Ascending Axe": "Ascending Axe", + "Atma's Portal": "Atma's Portal", + "Butterfly Mandolin": "Butterfly Mandolin", + "Cursed Compass": "Cursed Compass", + "Daydream Joker": "Daydream Joker", + "Devil's Brand": "Devil's Brand", + "Egg of Delusion": "Egg of Delusion", + "Envoy's Pipe": "Envoy's Pipe", + "Exorcist's Tonfa": "Exorcist's Tonfa", + "Forest Totem": "Forest Totem", + "Goblin's Lamp": "Goblin's Lamp", + "Grail of Blood": "Grail of Blood", + "Labyrinth Cube": "Labyrinth Cube", + "Mighty Yaksha": "Mighty Yaksha", + "Oath Key": "Oath Key", + "Prophetic Candlestick": "Prophetic Candlestick", + "Ranon's Memorandum": "Ranon's Memorandum", + "Ruby Essence": "Ruby Essence", + "Sword of the Morning": "Sword of the Morning", + "Timeless Anchor": "Timeless Anchor", + "A Song for Everybody": "A Song for Everybody", + "A Symbol of Unity": "A Symbol of Unity", + "Biting Wind Star": "Biting Wind Star", + "Blessings of Camaraderie": "Blessings of Camaraderie", + "Bloodbead Dagger": "Bloodbead Dagger", + "Days of Destiny": "Days of Destiny", + "Deadly Sword": "Deadly Sword", + "Demon's Pistol": "Demon's Pistol", + "Dream Scroll": "Dream Scroll", + "Elf's Bow": "Elf's Bow", + "Enhanced Gauntlet": "Enhanced Gauntlet", + "Fairy's Grimoire": "Fairy's Grimoire", + "Firm Shield": "Firm Shield", + "Moonlight’s Vestige": "Moonlight’s Vestige", + "Resolute Soldier Series": "Resolute Soldier Series", + "Staff of Wisdom": "Staff of Wisdom", + "Super Duper Water Gun Shooter": "Super Duper Water Gun Shooter", + "Sword of the Sun": "Sword of the Sun", + "The Guardian Star’s Blessing": "The Guardian Star’s Blessing", + "Venus Orb": "Venus Orb", + "Victorious Flag": "Victorious Flag", + "Air-to-Surface Missile: MISHA": "Air-to-Surface Missile: MISHA", + "Azure Comet": "Azure Comet", + "Guardian Ice Crystals": "Guardian Ice Crystals", + "Guide to a Decision": "Guide to a Decision", + "Official Levulin Beach Volleyball": "Official Levulin Beach Volleyball", + "Severed Horn Wand": "Severed Horn Wand", + "Star of the Deep Sea": "Star of the Deep Sea", + "Spear of a New Dawn": "Spear of a New Dawn", + "Twilight Calamity": "Twilight Calamity", + "War Horn": "War Horn", + "Wings of Light and Shadow": "Wings of Light and Shadow", + "XIII. Death": "XIII. Death", + "XIV. Temperance": "XIV. Temperance", + "XVIII. The Moon": "XVIII. The Moon", + "Hit 'Choose Folder', navigate into the folder where your screenshots are located, then hit 'Submit'. (The folder should show as empty, just select it)": "Hit 'Choose Folder', navigate into the folder where your screenshots are located, then hit 'Submit'. (The folder should show as empty, just select it)", + "Ran": "Ran", + "Milim": "Milim", + "Rimuru": "Rimuru", + "Shuna": "Shuna", + "Spirit Eye Celine": "Spirit Eye Celine", + "Adin": "Adin", + "Shadow Knight Pyllis": "Shadow Knight Pyllis", + "Anti-Magic Mask": "Anti-Magic Mask", + "Bastion of Hope": "Bastion of Hope", + "Flawless Garments": "Flawless Garments", + "Sword of Winter Shadow": "Sword of Winter Shadow", + "Upgraded Dragon Knuckles": "Upgraded Dragon Knuckles", + "Magic for Friends": "Magic for Friends", + "Zahhak": "Zahhak", + "Pure White Trust": "Pure White Trust", + "Nostalgic Music Box": "Nostalgic Music Box", + "Conqueror Lilias": "Conqueror Lilias", + "Command Model Laika": "Command Model Laika", + "Glo-Wings 21": "Glo-Wings 21", + "Januta": "Januta", + "Orte": "Orte", + "Muwi": "Muwi", + "Yoonryoung": "Yoonryoung", + "Hasol": "Hasol", + "Peira": "Peira", + "Goblet of Oath": "Goblet of Oath", + "Lionheart Cermia": "Lionheart Cermia", + "III. The Empress": "III. The Empress", + "IV. The Emperor": "IV. The Emperor", + "Bad Cat Armin": "Bad Cat Armin", + "Hwayoung": "Hwayoung", + "Indestructible Gaiters": "Indestructible Gaiters", + "Vigilante Leader Glenn": "Vigilante Leader Glenn", + "Verdant Adin": "Verdant Adin", + "Pirate Captain Flan": "Pirate Captain Flan", + "Jack-O": "Jack-O", + "Jack-O's Symbol": "Jack-O's Symbol", + "Aria": "Aria", + "Scroll of Shadows": "Scroll of Shadows", + "Taeyou": "Taeyou", + "Spear of Purification": "Spear of Purification", + "Holy Flame Adin": "Holy Flame Adin", + "Yulha": "Yulha", + "Sphere of Sadism": "Sphere of Sadism", + "Blazing Full Moon Trophy": "Blazing Full Moon Trophy", + "Use penetration set bonus for damage optimization": "Используйте бонус сета PENETRATION для оптимизации урона", + "Target's defense for penetration set (Recommended: 1,500, Min 0, Max 10k)": "Defense цели для PENETRATION сета (Рекомендуется: 1,500 , Min 0 , Max 10k)", + "Click on the magnifying glass on an item to analyze it.": "Нажми на лупу под субстатами предмета чтоб увидеть анализ.", + "Enhancing": "Анализ", + "Multi-Optimizer": "Мульти-Оптимизатор", + "Guide": "Guide", + "Start all": "Выбрать все", + "Cancel all": "Отменить все", + "Remove all": "Удалить все", + "Deselect all": "Отменить выбор", + "Edit filters": "Фильтры", + "Save": "Сохранить", + "Deselect": "Отменить выбор", + "Remove": "Удалить", + "+0 and higher": "+0 и более", + "+3 and higher": "+3 и более", + "+6 and higher": "+6 и более", + "+9 and higher": "+9 и более", + "+12 and higher": "+12 и более", + "+15 only": "только +15", + "Substat priority": "Substat priority", + "Multi Optimizer Guide": "Multi Optimizer Guide", + "This tool is for building multiple heroes simultaneously, who share similar gear requirements.": "This tool is for building multiple heroes simultaneously, who share similar gear requirements.", + "Instructions": "Instructions", + "First, add all the heroes that you want to optimize.": "First, add all the heroes that you want to optimize.", + "Heroes must have filters to optimizer, click 'Edit filters' to change their stat and item filters.": "Heroes must have filters to optimizer, click 'Edit filters' to change their stat and item filters.", + "Lower your permutations as much as possible. Aim for < 5 million results total across all heroes.": "Lower your permutations as much as possible. Aim for < 5 million results total across all heroes.", + "Click 'Start all' to begin optimizing all selected heroes, then wait for results.": "Click 'Start all' to begin optimizing all selected heroes, then wait for results.", + "Once finished, select a row to filter out builds containing the row's items from other heroes.": "Once finished, select a row to filter out builds containing the row's items from other heroes.", + "Click 'Deselect' to clear the selected build, and un-filter the row's items from other heroes.": "Click 'Deselect' to clear the selected build, and un-filter the row's items from other heroes.", + "Details": "Details", + "This works best with 2-4 heroes, but there is no hard limit. More than 4 can be slow.": "This works best with 2-4 heroes, but there is no hard limit. More than 4 can be slow.", + "The hero priority filter has one difference: all units added into the multi-optimizer are allowed to use each other's equipped items.": "The hero priority filter has one difference: all units added into the multi-optimizer are allowed to use each other's equipped items.", + "If a new hero is added to the multi-optimizer while other heroes already have results, Hit 'Start all' again to refresh the existing builds.": "If a new hero is added to the multi-optimizer while other heroes already have results, Hit 'Start all' again to refresh the existing builds.", + "The java process has to store all the results across all heroes. If you notice the permutations progressing very slowly, you may have run out of memory. Hit 'Cancel all' and apply stricter filters.": "The java process has to store all the results across all heroes. If you notice the permutations progressing very slowly, you may have run out of memory. Hit 'Cancel all' and apply stricter filters.", + "noMod": "noMod", + "SCORE": "SCORE", + "Archetypes": "Archetypes", + "DPS": "DPS", + "Debuff": "Debuff", + "Res Support": "Res Support", + "Tank": "Tank", + "Bruiser": "Bruiser", + "Atk DPS": "Atk DPS", + "Nuke": "Nuke", + "Erase all optimizer hero and gear data": "Удалить все данные о гире и героях", + "Optionally, if you want to load your storage items, open the storage menu after loading in the lobby": "По желанию, если вы хотите загрузить предметы из хранилища, откройте меню хранилища после загрузки в лобби.", + "Languages": "Языки", + "Default settings for newly added heroes": "Настройки по умолчанию для добавляемых героев", + "Minimum possible stats": "Minimum possible stats", + "Rolled stats": "Rolled stats", + "Missing potential stats": "Missing potential stats", + "Add any other non item bonus stats": "Добавить другие статы", + "Select which items to import": "Выберите, какой гир импортировать", + "Select which heroes to import": "Выберите, каких героев импортировать", + "Only import heroes already in optimizer": "Only import heroes already in optimizer", + "+15 and up": "+15 and up", + "Eff Res": "Eff Res", + "GPU accelerated optimization (Disable this option if you notice errors or decreased performance)": "Оптимизация с ускорением графического процессора (отключите этот параметр, если заметите ошибки или снижение производительности)", + "DmgD": "DmgD", + "DmgD - Dmg * Def rating, average damage rating, scaled by your units defense. Useful for defense scaling bruisers.": "DmgD - Dmg * Def, рейтинг, показывает урон героев имеющих скейл от Def.", + "Torrent": "Torrent", + "Protection": "Protection" +} diff --git a/data/locales/ru/translation.missing.json b/data/locales/ru/translation.missing.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/data/locales/ru/translation.missing.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/data/py/scanner.py b/data/py/scanner.py index b93ff095..5d8c8f49 100644 --- a/data/py/scanner.py +++ b/data/py/scanner.py @@ -16,7 +16,6 @@ def try_buffer(currAck): for i in buffers: finalBuffer += i['data'] - hexStr = '' try: hexStr = finalBuffer.hex();