diff --git a/_docs/dps.js b/_docs/dps.js index 20a2451b..816a2f41 100644 --- a/_docs/dps.js +++ b/_docs/dps.js @@ -202,21 +202,23 @@ function load() {
- - +
- -
-
+
+ +
-
+
-
diff --git a/_docs/mastery.js b/_docs/mastery.js index 692217d3..8b846d87 100644 --- a/_docs/mastery.js +++ b/_docs/mastery.js @@ -1,16 +1,3 @@ -const ProfessionNames = { - "PIONEER": "先锋", - "WARRIOR": "近卫", - "SNIPER": "狙击", - "TANK": "重装", - "MEDIC": "医疗", - "SUPPORT": "辅助", - "CASTER": "术师", - "SPECIAL": "特种", -// "TOKEN": "召唤物", -// "TRAP": "装置", -}; - const DamageColors = ['black','blue','limegreen','gold','aqua']; const DefaultAttribute = { phase: 2, @@ -60,7 +47,8 @@ function init() { '../customdata/dps_specialtags.json', '../customdata/dps_options.json', '../customdata/leveling_cost.json', - '../resources/attributes.js' + '../resources/attributes.js', + '../customdata/green.json' ], load); } @@ -71,7 +59,8 @@ function queryArkPlanner(mats, callback, ...args) { owned: {}, extra_outc: true, exp_demand: false, - gold_demand: true + gold_demand: true, + exclude: ["main_07-13"] }; //console.log("query ArkPlanner ->", JSON.stringify(data, null, 2)); @@ -94,6 +83,7 @@ function buildVueModel() { let version = AKDATA.Data.version; // select char list + /* let charList = {}; let new_list = []; AKDATA.new_op.forEach(id => { @@ -110,10 +100,18 @@ function buildVueModel() { } charList[ProfessionNames[key]] = opts; }); + */ + // exclude list + var excludeList = []; + for (let id in AKDATA.Data.character_table) { + let data = AKDATA.Data.character_table[id]; + if (!data.phases || data.phases.length <= 2) + excludeList.push(id); + } return { version, - charList, + excludeList, charId: "-", chartKey: "dps", resultView: {}, @@ -122,6 +120,8 @@ function buildVueModel() { recom: {}, jobs: 0, test: "", + img_char: "/akdata/assets/images/char/char_504_rguard.png", + txt_char: "请选择" }; } @@ -172,24 +172,24 @@ function load() { // build html let html = ` -
-
+
+
干员
- +
- +
干员
-
+
升级收益(精2 1级~满级)
-
+
-
+
专精收益(以精2 1级 7级技能为基准计算) @@ -205,19 +205,21 @@ function load() {
-
+
-
专精材料( × ArkPlanner
+
精英化/专精材料(绿票算法)
-
+ +
-
理智消耗效率
+
提升率分布图
+
+
-
- +
`; + let $dps = $(html); + + $dps.find('.dps__row-select').append(` +
+ +
+ + +
+
+ `); + + pmBase.content.build({ + pages: [{ + content: $dps, + }] + }); + + // setup vue + window.model = buildVueModel(); + let vue_version = new Vue({ + el: '#vue_version', + data: { + version: window.model.version, + } + }); + window.vue_app = new Vue({ + el: '#vue_app', + data: window.model, + methods: { + changeChar: function(event) { + this.resultView = calculate(this.charId); + if (this.resultView.rhodes) { + $("#mats_table").text("集成战略临时干员"); + } else { + $("#mats_table").text("正在计算..."); + beginCalcMats(this.resultView); + } + this.updateLevelingTable(); + }, + debugPrint: function(obj) { + //console.log(JSON.stringify(obj, null, 2)); + return JSON.stringify(obj, null, 2); + }, + goto: function(event) { + window.open(`../character/#!/${this.charId}`, '_blank'); + }, + godps: function(event) { + window.open(`../dps/#${this.charId}`, '_blank'); + }, + updateMats: function(result) { + let matsView = {}; + let rv = this.resultView; + let pr = this.plannerResponse; + + /*let costResult = calculateCost(this.charId, pr, this.resultView); + //this.test = costResult; + updateCostPlot(costResult, this.chartKey); +*/ + for (var sk in rv.skill) { + matsView[sk] = {title: rv.skill[sk]}; + matsView[sk].list = []; + for (var lv in pr[sk]) { + var items = []; + for (var x in pr[sk][lv].mats) { + // items.push(` ${x} × ${pr[sk][lv].mats[x]}`); + items.push(AKDATA.getItemBadge("MATERIAL", itemCache[x].id, pr[sk][lv].mats[x])); + } + matsView[sk].list.push([ + `${lv} ${parseInt(lv)+1}`, + items, + pr[sk][lv].cost, + Math.round(pr[sk][lv].green), + // this.recom[sk][lv-7] + ]); + } + } + matsView["elite"] = {title: `精英化材料(不包含红票/龙门币)`}; + matsView["elite"].list = []; + var resp = pr[`${rv.id}_elite`]; + for (var lv in resp) { + var items = []; + for (var x in resp[lv].mats) { + // items.push(` ${x} × ${pr[sk][lv].mats[x]}`); + items.push(AKDATA.getItemBadge("MATERIAL", itemCache[x].id, resp[lv].mats[x])); + } + matsView["elite"].list.push([ + `${parseInt(lv)-1} ${lv}`, + items, + resp[lv].cost, + Math.round(resp[lv].green) + ]); + } + // this.test = matsView; + let matsHtml = ""; + for (var sk in matsView) { + matsHtml += pmBase.component.create({ + type: 'list', + card: true, + title: `${matsView[sk].title}`, + // header: ['等级', '素材', '等效理智', '推荐等级(测试)'], + header: ['等级', '素材', '等效理智', "等效绿票(测试)"], + list: matsView[sk].list + }); + } + $("#mats_table").html(matsHtml); + + }, + jobCallback: function() { + console.log("- all jobs finished"); + console.timeEnd("calcMats"); + this.updateMats(this.plannerResponse); + }, + updateLevelingTable: function () { + var db = AKDATA.Data.character_table[this.charId]; + var r = DefaultAttribute; $.extend(r, Stages["基准"]); + var ch0 = buildChar(this.charId, db.skills[0].skillId, r); + r.level = "max"; + var ch1 = buildChar(this.charId, db.skills[0].skillId, r); + var a0 = AKDATA.attributes.getCharAttributes(ch0), a1 = AKDATA.attributes.getCharAttributes(ch1); + + var gain = [(a1.maxHp - a0.maxHp)/a0.maxHp, (a1.atk - a0.atk)/a0.atk, (a1.def - a0.def)/a0.def]; + var result = gain.map(x => (x*100).toFixed(1) + "%"); + result.push(...LevelingCost[db.rarity + 1]); + //console.log(result); + //console.log(ch0, ch1); + //console.log(a0, a1); + + let html = pmBase.component.create({ + type: 'list', + card: false, + title: `升级属性提升(精二1级->满级)`, + header: ['HP', '攻击力', '防御力', '等效理智(按CE5/LS5计算)', '需要天数(按基建+自回体+月卡计算)'], + list: [result] + }); + $("#level_table").html(html); + } + }, + watch: { + resultView: function(_new, _old) { + let cv = buildChartView(_new, this.chartKey); + plot(cv); + }, + chartKey: function(_new, _old) { + let cv = buildChartView(this.resultView, _new); + updatePlot(cv); + }, + jobs: function(_new, _old) { + if (this.charId != "-" && this.jobs == 0) + this.jobCallback(); + }, + } + }); + +} + +function buildChar(charId, skillId, recipe) { + let char = { + charId, + skillId, + phase: recipe.phase, + favor: recipe.favor, + potentialRank: recipe.potential, + skillLevel: recipe.skillLevel, + options: recipe.options + }; + + let db = AKDATA.Data.character_table[charId]; + let skilldb = AKDATA.Data.skill_table[skillId]; + let maxLevel = db.phases[recipe.phase].maxLevel; + if (recipe.level == "max" || recipe.level > maxLevel) + char.level = maxLevel; + else + char.level = recipe.level; + char.name = db.name; + char.skillName = skilldb.levels[char.skillLevel].name; + //console.log(char); + var _opts = AKDATA.Data.dps_options.char[charId]; + if (checkSpecs(charId, "use_token_for_mastery") || checkSpecs(skillId, "use_token_for_mastery")) + char.options.token = true; + else char.options.token = false; + return char; +} + +function calculate(charId) { + let db = AKDATA.Data.character_table[charId]; + let itemdb = AKDATA.Data.item_table.items; + let recipe = DefaultAttribute; + let enemy = DefaultEnemy; + let stages = Stages; + let raidBuff = { atk: 0, atkpct: 0, ats: 0, cdr: 0, base_atk: 0, damage_scale: 0 }; + let result = {}, mats = {}; + + // calculate dps for each recipe case. + db.skills.forEach(skill => { + var entry = {}; + for (let st in stages) { + $.extend(recipe, stages[st]); + var ch = buildChar(charId, skill.skillId, recipe); + ch.dps = AKDATA.attributes.calculateDps(ch, enemy, raidBuff); + entry[st] = ch; + }; + result[skill.skillId] = entry; + + mats[skill.skillId] = skill.levelUpCostCond.map(x => x.levelUpCost); + }); + mats[1] = db.phases[1].evolveCost; + mats[2] = db.phases[2].evolveCost; + + // extract result, making it more readable + // name, skill, stage, damageType, avg, skill, skilldamage, cdr + let resultView = { + id: charId, + name: db.name, + skill: {}, + stages: stages, + dps: {}, + notes: {}, + mats: {} + }; + for (let k in result) { + resultView.skill[k] = result[k]["满潜"].skillName; + resultView.notes[k] = result[k]["满潜"].dps.note; + resultView.dps[k] = {}; + for (let st in stages) { + var entry = result[k][st].dps; + resultView.dps[k][st] = { + damageType: entry.skill.damageType, + spType: entry.skill.spType, + dps: entry.globalDps, + hps: entry.globalHps, + s_dps: entry.skill.dps, + s_hps: entry.skill.hps, + s_dmg: entry.skill.totalDamage, + s_heal: entry.skill.totalHeal, + s_ssp: entry.skill.dur.startSp, + }; + // console.log(k, st, entry.skill.dur.startSp); + }; + resultView.mats[k] = []; + mats[k].forEach(level => { + var i = {}; + if (level) { + level.forEach(x => { + var _n = itemdb[x.id].name.replace(" ", ""); + i[_n] = x.count; + itemCache[_n] = {id: x.id, name: _n, rarity: itemdb[x.id].rarity}; + }); + resultView.mats[k].push(i); + } + else resultView["rhodes"] = true; + }); + }; + + resultView.mats[`${charId}_elite`] = []; + for (let elite=1; elite<=2; elite+=1) { + if (mats[elite]) { + let m = {}; + mats[elite].forEach(x => { + let _nm = itemdb[x.id].name.replace(" ", ""); + if (_nm.includes("双芯片")) { + x.id -= 1; + _nm = itemdb[x.id].name.replace(" ", ""); + // m["采购凭证"] = x.count * 90; + x.count *= 2; + } + itemCache[_nm] = { id: x.id, name: _nm, rarity: itemdb[x.id].rarity }; + m[_nm] = x.count; + }); + resultView.mats[`${charId}_elite`].push(m); + } + } + + // console.log(window.vue_app.debugPrint(resultView.mats)); + return resultView; +} + +const HealKeys = { + dps: "hps", + s_dps: "s_hps", + s_dmg: "s_heal" +}; + +// calculate() -> resultView -> build(key) -> chartView -> plot() +function buildChartView(resultView, key) { + // rotate data for plot columns + let view = resultView; + let k = key; + let columns = [], groups = [], skill_names = [], notes = []; + var last = {}; + for (let stg in view.stages) { + var entry = [stg]; + for (let skill in view.skill) { + k = (view.dps[skill][stg].damageType == 2) ? HealKeys[key] : key; + var value = view.dps[skill][stg][k]; + if (skill in last) + entry.push((value - last[skill]).toFixed(2)); + else + entry.push(value.toFixed(2)); + last[skill] = value; + } + columns.push(entry); + groups.push(stg); + } + var x = 0.02, i = 0; + for (let skill in view.skill) { + skill_names.push(view.skill[skill]); + let line = view.notes[skill]; + + if (view.dps[skill]["满潜"].spType != 8) { + if (line != "") line += "\n"; + line += `启动技力 ${view.dps[skill]["基准"].s_ssp}s -> ${view.dps[skill]["满潜"].s_ssp}s`; + console.log(view.dps[skill]["满潜"].spType); + if (view.dps[skill]["满潜"].s_ssp <= 0) + line += " (落地点火)"; + } + notes.push({x: x, y: 20, content: line}); + x+=1; + } + // console.log(columns, groups, skill_names, notes); + + return { columns, groups, skill_names, notes }; +} + +function plot(chartView) { + if (!window.chart) window.chart = {}; + window.chart["chart"] = c3.generate({ + bindto: "#chart", + size: { height: 400 }, + data: { + type: "bar", + columns: [], + groups: [chartView.groups], + order: null, + }, + axis: { + rotated: true, + x: { + type: "category", + categories: chartView.skill_names + }, + y: { + tick: { fit: false }, + } + }, + bar: { + width: { ratio: 0.4 } + }, + stanford: { + texts: chartView.notes + }, + grid: { + y: { show: true } + }, + zoom: { enabled: false }, + color: { + pattern: [ "#cccccc", "#4169e1", "#ff7f50", "#ffd700", "#dc143c", "#ee82ee", "#e6e6fa" ] + } + }); + + window.chart["chart"].load({ columns: chartView.columns }); + setTimeout(function() { + $(".c3-chart-bar.c3-target-基准").css("opacity", 0.4); + }, 100); +} + +function updatePlot(chartView) { + window.chart["chart"].load({ columns: chartView.columns, groups: chartView.groups }); + setTimeout(function() { + $(".c3-chart-bar.c3-target-基准").css("opacity", 0.4); + }, 200); +} + +// use ajax post to invoke ArkPlanner +// use vue var as semaphore to cooperate requests +// when all request jobs are done (jobs == 0), the vue watch invokes jobDoneCallback() +function beginCalcMats(resultView) { + console.time("calcMats"); + window.vue_app.jobs = Object.keys(resultView.mats).length * 3 - 1; // semaphore + var delay = 300; + + for (var sk in resultView.mats) { + let level = 7; // 7->8 + if (sk.includes("elite")) level = 1; + resultView.mats[sk].forEach(m => { + if (Object.keys(m).length > 0) { + // arkplanner - 理智算法 + (function (_m, _s, _l) { // closure to bind args to setTimeout + setTimeout(function () { + queryArkPlanner(_m, matsCallback, {mats: _m, id: resultView.id, skill: _s, level: _l}); + }, delay); + }(m, sk, level)); + } + level += 1; delay += 300; + }); + } + } + +function matsCallback(result, kwargs) { + // 绿票算法 + var greenTable = AKDATA.Data.green; + var greenCost = [0, ...Object.keys(kwargs.mats)].reduce((sum, x) => sum + greenTable[x] * kwargs.mats[x]); + + if (!window.vue_app.plannerResponse[kwargs.skill]) + window.vue_app.plannerResponse[kwargs.skill] = {}; +// window.vue_app.plannerResponse[kwargs.skill][`${kwargs.level}`] = { mats: kwargs.mats, result: result }; + window.vue_app.plannerResponse[kwargs.skill][`${kwargs.level}`] = { mats: kwargs.mats, cost: result.cost, green: greenCost }; + + if (kwargs.id == window.vue_app.charId) // filter old (slow) calls + window.vue_app.jobs -= 1; +} +/* +function calculateCost(charId, masteryCost, resultView) { + let result = {}; + let db = AKDATA.Data.character_table[charId]; + let costdb = AKDATA.Data.leveling_cost; + var perLevelSanity = costdb.map((x, idx) => (idx==0) ? 0 : x - costdb[idx-1]); + + let recipe = DefaultAttribute; + let enemy = DefaultEnemy; + let stages = []; + let raidBuff = { atk: 0, atkpct: 0, ats: 0, cdr: 0, base_atk: 0, damage_scale: 0 }; + + var chartView = buildChartView(resultView, "s_dps"); + var i=0; + // calculate dps for each recipe case. + db.skills.forEach(skill => { + var entry = []; + stages = [...CostStages]; + // calculate efficiency. base: 0, level: 1, m1:2, m2:3, m3:4, skill:i+1 + var base = chartView.columns[0][i+1]; + var mc = masteryCost[skill.skillId]; + var perLevelGain = chartView.columns[1][i+1] / base / (db.rarity * 10 + 39); // per level dps gain rate + var mg = [2, 3, 4].map(x => chartView.columns[x][i+1] / base); // mastery dps gain rate + mg[1] += mg[0]; + mg[2] += mg[1]; // accumulate + + var perLevelEffInv = perLevelSanity.map(x => x / perLevelGain); // inverse of efficiency + var masteryEffInv = [mc[7].cost, mc[7].cost + mc[8].cost, mc[7].cost + mc[8].cost + mc[9].cost].map((x, idx) => x / mg[idx]); + var recom = masteryEffInv.map(x => perLevelEffInv.findIndex(y => y > x)).map(x => (x <= 0) ? (db.rarity*10+40) : x); + recom[2] = Math.min(80, recom[2]); + recom[1] = Math.min(recom[1]+5, recom[2]); // tweak result + recom[0] = Math.min(recom[0]+5, recom[1]); + // console.log(perLevelEffInv, masteryEffInv); + //console.log(recom); + window.vue_app.recom[skill.skillId] = recom; + + // set stages + var j=1; + for (var k=0; k<3; ++k) { + // if (k==0 || recom[k] > recom[k-1]) { + // stages.splice(j, 0, { level: recom[k], desc: `2${recom[k]}${k+7}` }); ++j; + // } + stages.splice(j, 0, { level: recom[k], skillLevel: k+7, desc: `2${recom[k]}${k+8}` }); ++j; + } + if (recom[2] < 60) + stages.splice(j, 0, {level: 60, desc: "26010"}); ++j; + + //console.log(stages); + // calculate stage dps + stages.forEach(st => { + var item = {}; + if (!(st.level == 80 && db.rarity < 5)) { + $.extend(recipe, st); + var ch = buildChar(charId, skill.skillId, recipe); + ch.dps = AKDATA.attributes.calculateDps(ch, enemy, raidBuff); + + item = { + desc: st.desc, + dps: ch.dps.globalDps, + hps: ch.dps.globalHps, + s_dps: ch.dps.skill.dps, + s_hps: ch.dps.skill.hps, + s_dmg: ch.dps.skill.totalDamage, + s_heal: ch.dps.skill.totalHeal, + levelingCost: costdb[ch.level - 1], + damageType: ch.dps.skill.damageType, + skillName: ch.skillName + }; + + let mcost = 0, slv = ch.skillLevel; + while (slv > 6) { + mcost += masteryCost[skill.skillId][slv].cost; + --slv; + } + item.masteryCost = mcost; + + entry.push(item); + } + }); + result[skill.skillId] = entry; + i+=1; + }); + return result; +} + +function updateCostPlot(result, chartKey) { + $("#cost_chart").html(""); + var idx = 1; + Object.keys(result).forEach(key => { + var idstr = `skill_${idx}`; + $("#cost_chart").append(` +
+

${result[key][0].skillName} - DPS提升与理智消耗

+
+
`); + var ck = chartKey; + if (result[key][0].damageType == 2) ck = HealKeys[chartKey]; + let x_arr = result[key].map(x => x.desc); + let dps_arr = result[key].map(x => x[ck]); + let cost_arr = result[key].map(x => x.masteryCost + x.levelingCost); + $(`#${idstr}`).append(window.vue_app.debugPrint({x_arr, dps_arr, cost_arr})); + window.chart[idstr] = c3.generate({ + bindto: `#${idstr}`, + size: { height: 400 }, + data: { + columns: [ + ["dps", ...dps_arr], + ["理智消耗", ...cost_arr] + ], + axes: { + dps: "y", + "理智消耗": "y2" + } + }, + axis: { + x: { + type: "category", + categories: x_arr, + }, + y: { + min: dps_arr[0], + padding: 0, + label: { text: chartKey, position: 'outer-middle' } + }, + y2: { + show: true, + min: 0, + // max: cost_arr[cost_arr.length-1], + padding: 0, + label: { text: "理智消耗", position: 'outer-middle' } + } + }, + tooltip: { + format: { value: function(value, ratio, id) { + if (id == "dps") return `${value.toFixed(1)} (${(value * 100 / dps_arr[dps_arr.length-1]).toFixed(1)}%)`; + else return Math.round(value); + } } + }, + grid: { + y: { show: true } + }, + zoom: { enabled: false }, + }); + + ++idx; + }); +} +*/ +pmBase.hook.on('init', init); diff --git a/_docs/whatsnew.md b/_docs/whatsnew.md index 8a78e477..a769fd4b 100644 --- a/_docs/whatsnew.md +++ b/_docs/whatsnew.md @@ -5,8 +5,12 @@ order: 4 category: 工具 icon: info-circle --- -## 21.05.27 +## 21.05.27-31 - [dps] 新版选人菜单测试 +- [dps] 切换类技能(银灰2,山2)统一按永续类计算 +- [mastery] 专精收益计算器改版。全面修改为无需后台工作的绿票算法 +- [mastery] 去除了部分图表,增加了精二材料计算和收益饼图 +- [fix] 修正异客3持续时间,凯尔希3增加误差说明 ## 21.05.02 2周年版本 - [update] 浊心斯卡蒂等 diff --git a/resources/akdata.css b/resources/akdata.css index f962dc6b..c4a55016 100644 --- a/resources/akdata.css +++ b/resources/akdata.css @@ -72,4 +72,10 @@ h5 { strong { font-weight: 600!important; -} \ No newline at end of file +} + +.img_char { + /* box-shadow: 3px 3px 7px -1px rgb(0 0 0 / 85%); */ + border-radius: 5px; +} + \ No newline at end of file diff --git a/resources/akdata.js b/resources/akdata.js index ecae978b..4d0b5e2c 100644 --- a/resources/akdata.js +++ b/resources/akdata.js @@ -46,7 +46,7 @@ window.AKDATA = { let path = `https://cdn.jsdelivr.net/gh/xulai1001/akdata@${window.AKDATA.akdata}/resources/gamedata/${paths[i].toLowerCase()}`; // custom json data: always use local copy - if (!paths[i].includes("excel")) // 本地调试开关 + // if (!paths[i].includes("excel")) // 本地调试开关 path = `../resources/gamedata/${paths[i].toLowerCase()}?_=${Math.round(Math.random()*1e8)}`; console.log(`Loading -> ${name}`); paths[i] = loadJSON(path, data => AKDATA.Data[name] = data); @@ -156,7 +156,7 @@ window.AKDATA = { // console.log(charPools); let html = ""; - Object.keys(charPools).forEach(k => { + ["新干员", ...Object.values(AKDATA.professionNames)].forEach(k => { let entry = `

${k}

`; charPools[k].sort((a, b) => b.rarity - a.rarity).forEach(x => { entry += `${x.name}`; diff --git a/resources/attributes.js b/resources/attributes.js index 0d99dfd9..eafcab5b 100644 --- a/resources/attributes.js +++ b/resources/attributes.js @@ -1343,12 +1343,7 @@ function calcDurations(isSkill, attackTime, attackSpeed, levelData, buffList, bu else log.writeNote(`技能前摇: ${t.toFixed(3)}s`); } // 技能类型 - if (checkSpecs(skillId, "toggle")) { - attackCount = Math.ceil(30 / attackTime); - duration = 30; - tags.push("toggle"); - log.writeNote("切换类技能 (以30s为参考计算)"); - } else if (levelData.description.includes("持续时间无限")) { + if (levelData.description.includes("持续时间无限") || checkSpecs(skillId, "toggle")) { if (skillId == "skchr_thorns_3" && !options.warmup) {} else if (skillId == "skchr_tuye_2") { log.writeNote("取技能时间=暖机时间"); @@ -1363,7 +1358,11 @@ function calcDurations(isSkill, attackTime, attackSpeed, levelData, buffList, bu } else { attackCount = Math.ceil(1800 / attackTime); duration = attackCount * attackTime; - tags.push("infinity"); log.writeNote("持续时间无限 (记为1800s)"); + if (checkSpecs(skillId, "toggle")) { + log.writeNote("切换类技能 (记为1800s)"); tags.push("toggle"); + } else { + log.writeNote("持续时间无限 (记为1800s)"); tags.push("infinity"); + } } } else if (spData.spType == 8) { if (levelData.duration <= 0 && blackboard.duration > 0) { @@ -1582,11 +1581,6 @@ function calcDurations(isSkill, attackTime, attackSpeed, levelData, buffList, bu attackCount = Math.ceil(attackDuration / attackTime); duration = attackDuration; log.write(`[特殊] ${displayNames["tachr_400_weedy_2"]}: 使用${m+1}个水炮, 充能sp=${m * 6 + c}`); - } else if (checkSpecs(skillId, "toggle")) { - attackCount = Math.ceil(30 / attackTime); - duration = 30; - tags.push("toggle"); - //log.writeNote("切换类技能 (以30s为参考计算)"); } break; // todo: cast time diff --git a/resources/customdata/dps_specialtags.json b/resources/customdata/dps_specialtags.json index 770380c3..d9633c5b 100644 --- a/resources/customdata/dps_specialtags.json +++ b/resources/customdata/dps_specialtags.json @@ -119,7 +119,7 @@ "skchr_kafka_2": { "reset_attack": true }, "skchr_kalts_1": { "token_damage_type": "0" }, "skchr_kalts_2": { "token_damage_type": "0", "use_token_for_mastery": true }, - "skchr_kalts_3": { "damage_type": 2, "token_damage_type": 3, "grad": true, "use_token_for_mastery": true }, + "skchr_kalts_3": { "damage_type": 2, "token_damage_type": 3, "grad": true, "use_token_for_mastery": true, "note": "每击伤害为估算平均值,实际会偏高" }, "skchr_kroos_1": { "sim": true }, "skchr_lava2_2": { "sec": true, "note": "不重叠部分伤害减半" }, "skchr_lionhd_2": { "reset_attack": "ogcd", "cast_time": 32 }, @@ -145,6 +145,7 @@ "skchr_nian_2": { "reflect": true }, "skchr_nightm_1": { "damage_type": 1 }, "skchr_pasngr_1": { "sim": true }, + "skchr_pasngr_3": { "cast_time": 120 }, "skchr_peacok_1": { "sim": true }, "skchr_peacok_2": { "cast_time": 45, "frame_corr": -15, "damage_type": "0" }, "skchr_phatom_2": { "grad": true }, diff --git a/resources/customdata/green.json b/resources/customdata/green.json new file mode 100644 index 00000000..e30d8da3 --- /dev/null +++ b/resources/customdata/green.json @@ -0,0 +1,98 @@ +{ + "源岩": 1.275, + "固源岩": 5.108, + "固源岩组": 25.000, + "提纯源岩": 94.724, + "代糖": 2.542, + "糖": 7.635, + "糖组": 30.000, + "糖聚块": 124.724, + "双酮": 2.958, + "酮凝集": 8.885, + "酮凝集组": 35.000, + "酮阵列": 124.724, + "异铁碎片": 2.958, + "异铁": 8.885, + "异铁组": 35.000, + "异铁块": 139.724, + "破损装置": 3.792, + "装置": 11.385, + "全新装置": 45.000, + "改量装置": 129.724, + "酯原料": 2.542, + "聚酸酯": 7.635, + "聚酸酯组": 30.000, + "聚酸酯块": 119.724, + "轻锰矿": 35.000, + "三水锰矿": 124.724, + "扭转醇": 30.000, + "白马醇": 99.724, + "RMA70-12": 45.000, + "RMA70-24": 124.724, + "研磨石": 40.000, + "五水研磨石": 114.724, + "聚合剂": 337.714, + "双极纳米片": 307.714, + "D32钢": 342.714, + "炽合金": 35.000, + "炽合金块": 114.724, + "凝胶": 40.000, + "聚合凝胶": 104.724, + "晶体元件": 30.000, + "晶体电路": 129.724, + "晶体电子单元": 432.438, + "基础作战记录": 0.625, + "初级作战记录": 1.250, + "中级作战记录": 3.125, + "高级作战记录": 6.250, + "小芯片": 0.000, + "芯片组": 0.000, + "胶水": 160.000, + "双芯片": 250.000, + "技巧概要·卷1": 1.500, + "技巧概要·卷2": 4.500, + "技巧概要·卷3": 13.500, + "赤金": 1.250, + "龙门币": 0.005, + "采购凭证": 1.700, + "红票": 1.700, + "招聘许可": 15.000, + "合成玉": 0.903, + "六星信物": 1224.000, + "五星信物": 306.000, + "芯片助剂": 160.000, + "先锋双芯片": 250.000, + "先锋芯片组": 45.000, + "先锋芯片": 22.500, + "近卫双芯片": 250.000, + "近卫芯片组": 45.000, + "近卫芯片": 22.500, + "重装双芯片": 250.000, + "重装芯片组": 45.000, + "重装芯片": 22.500, + "狙击双芯片": 250.000, + "狙击芯片组": 45.000, + "狙击芯片": 22.500, + "术师双芯片": 250.000, + "术师芯片组": 45.000, + "术师芯片": 22.500, + "医疗双芯片": 250.000, + "医疗芯片组": 45.000, + "医疗芯片": 22.500, + "辅助双芯片": 250.000, + "辅助芯片组": 45.000, + "辅助芯片": 22.500, + "特种双芯片": 250.000, + "特种芯片组": 45.000, + "特种芯片": 22.500, + "碳": 0.000, + "至纯源石": 162.500, + "十连寻访凭证": 5416.667, + "寻访凭证": 541.667, + "应急理智合剂": 75.000, + "应急理智顶液": 125.000, + "黄票": 80.000, + "绿票": 1.000, + "体力": 1.250, + "理智": 1.250 +} \ No newline at end of file