MediaWiki:Gadget-SvtNpGetTop5.js
注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Internet Explorer:按住Ctrl的同时单击刷新,或按Ctrl-F5
- Opera:前往菜单 → 历史(Mac为Opera → Preferences),或按Ctrl-Shift-Del,然后清除浏览数据 → 勾选“已缓存的图片和文件” → 清除数据。
/*
放弃移植
https://greasyfork.org/zh-CN/scripts/388555-fgo-wiki%E4%BB%8E%E8%80%85np%E8%8E%B7%E5%8F%96%E7%8E%87top5%E6%98%BE%E7%A4%BA-for-mooncell/code
var jQ1 = jQuery.noConflict();
var Global_wiki = {};
jQ1(function () {
'use strict';
var no = parseInt(jQ1(".wikitable.nomobile th:contains('No.')").text().replace("No.", ""));
if (isNaN(no)) {
console.log('【${no}】不是数字'.replace('${no}',no));
return;
}
var isOK = loadNpData(no);
if (!isOK) {
console.log("nps.json文件未更新");
return;
};
var optionsHtml = "<tr class='trCalcBox' data-show='0'><td colspan='12'><div class='calcBox'><ul><li>BUFF</li><li>NP获得提升(%):<input type='number' id='txtNpBuff' value='0'>蓝魔放(%):<input type='number' id='txtArtsBuff' value='0'>绿魔放(%):<input type='number' id='txtQuickBuff' value='0'><label for='ckSpecialSkill1'><input id='ckSpecialSkill1' type='checkbox'>第五势</label></li></ul><ul><li>首卡</li><li><label for='ckIsOverkill_first'><input id='ckIsOverkill_first' type='checkbox'>鞭尸</label></li><li><label for='ckIsCritical_first'><input id='ckIsCritical_first' type='checkbox'>暴击</label></li></ul><ul><li>次卡</li><li><label for='ckIsOverkill_second'><input id='ckIsOverkill_second' type='checkbox'>鞭尸</label></li><li><label for='ckIsCritical_second'><input id='ckIsCritical_second' type='checkbox'>暴击</label></li></ul><ul><li>尾卡</li><li><label for='ckIsOverkill_third'><input id='ckIsOverkill_third' type='checkbox'>鞭尸</label></li><li><label for='ckIsCritical_third'><input id='ckIsCritical_third' type='checkbox'>暴击</label></li></ul><ul><li>EX</li><li><label for='ckIsOverkill_ex'><input id='ckIsOverkill_ex' type='checkbox'>鞭尸</label></li></ul><ul class='treasureHit'><li>宝具Hit数:<input type='number' id='txtTreasureHit' value='0'><label for='ckIsOverkill_treasure'><input id='ckIsOverkill_treasure' type='checkbox'>鞭尸</label>宝具NP回收率(%):<span id='spanTreasureNP'>0</span><label for='ckIsIgnoreTreasure'><input id='ckIsIgnoreTreasure' type='checkbox'>忽略宝具组合</label></li></ul></div></td></tr>";
var cardBox = $(".wikitable.nomobile th:contains('配卡')").next();
var tmpNpObj = Global_wiki.tmpNpObj;
var npObj = {
no: no,
arts: {
hit: tmpNpObj.ah,
num: cardBox.find("img[src*=Arts]").length,
np: tmpNpObj.anp
},
buster: {
hit: tmpNpObj.bh,
num: cardBox.find("img[src*=Buster]").length,
np: tmpNpObj.bnp
},
quick: {
hit: tmpNpObj.qh,
num: cardBox.find("img[src*=Quick]").length,
np: tmpNpObj.qnp
},
ex: {
hit: tmpNpObj.exh,
np: tmpNpObj.exnp
},
treasure: {
hit: tmpNpObj.h,
np: tmpNpObj.np,
card: tmpNpObj.t
},
careerSkill: {
artsBuff: tmpNpObj.a,
quickBuff: tmpNpObj.q
}
};
Global_wiki.npObj = npObj;
var tempArr = ["宝"],
a = npObj.arts,
b = npObj.buster,
q = npObj.quick;
for (var i = 0; i < a.num; i++) {
tempArr.push("A");
}
for (var i = 0; i < b.num; i++) {
tempArr.push("B");
}
for (var i = 0; i < q.num; i++) {
tempArr.push("Q");
}
var tempArr1 = tempArr,
tempArr2 = tempArr.slice(0),
tempArr3 = tempArr.slice(0),
cardArr = [];
tempArr1.forEach(function (a1, i) {
//i≠j≠k
tempArr2.forEach(function (b1, j) {
tempArr3.forEach(function (q1, k) {
if (i != j && i != k && j != k) cardArr.push(a1 + b1 + q1);
});
});
});
//总共42或34种组合(去重后)
cardArr = Array.from(new Set(cardArr));
Global_wiki.cardArr = cardArr;
var npArr = [];
cardArr.forEach(function (res) {
// abq
npArr.push(calcCardNp(res));
});
npArr = npArr.sort(compare("totalNp"));
var parent = jQ1(".wikitable.nomobile th:contains('配卡')").parent().parent(),
head = jQ1("<tr><td colspan='8' style='background-color:#e6eaeb'>NP获取率TOP<span class='spanTopTimes'>5</span>(敌补正为<span class='spanEnemyCorrections'>1</span>)</td></tr>"),
contenHtml = "<tr><td colspan='8' class='calcResult'>",
img = jQ1('<i class="fa-calculator fas btnCalc" style="font-size: 16px;"></i>');
parent.append(head);
img.css("width", "27px");
head.children("td").append(img);
for (var i = 0; i < npArr.length; i++) {
var tnpObj = npArr[i],
cardStr = tnpObj.cardStr;
if (!cardStr.includes("宝")) cardStr = " " + cardStr;
if (i == 5) break;
contenHtml += getContentHtml(cardStr, tnpObj);
}
contenHtml += "</td></tr>";
head.after(contenHtml);
head.after(optionsHtml);
//设置默认值
jQ1("#txtTreasureHit").val(npObj.treasure.hit);
jQ1("#txtArtsBuff").val(npObj.careerSkill.artsBuff);
jQ1("#txtQuickBuff").val(npObj.careerSkill.quickBuff);
jQ1("#spanTreasureNP").text(calcTreasureNP(npObj.treasure.card));
//追加样式
jQ1(".trCalcBox").css({
"display": "none"
});
jQ1(".calcBox").css({
"height": "150px",
"margin": "0 auto",
"text-align": "left",
"padding": "10px 0 0 30px"
});
jQ1(".calcBox>ul,.calcBox input[type=checkbox]").css({
"list-style": "none",
"margin": "0",
"padding": "0"
});
jQ1(".calcBox input[type=number]").css({
"text-align": "center"
});
jQ1(".calcBox>ul:not(:nth-child(1))").css({
"float": "left",
"width": "125px"
});
jQ1(".calcBox>ul:last-child").css({
"clear": "both",
"width": "100%"
});
jQ1(".calcBox>ul>li:not(:nth-child(1))").css({
"padding-left": "30px"
});
jQ1(".calcBox input").css({
"vertical-align": "middle"
});
jQ1(".calcBox input[type=number]").css({
"width": "50px"
});
setFixWidth();
if (no != "153") { //武藏
jQ1(".calcBox label[for=ckSpecialSkill1]").hide();
}
//设置点击计算器图标事件
jQ1(".btnCalc").click(function () {
var show = jQ1(".trCalcBox").data("show");
if (show == "0") { //原本隐藏状态,现在要显示
jQ1(".trCalcBox").show();
jQ1(".spanTopTimes").html(" <input type='number' id='txtTopTimes' value='5'/>");
jQ1(".spanEnemyCorrections").html(" <input type='number' id='txtEnemyCorrections'value='1'/>");
jQ1("#txtTopTimes,#txtEnemyCorrections").bind("input propertychange",
function () {
reCalc();
});
jQ1("#txtTopTimes,#txtEnemyCorrections").css({
"color": "#000",
"width": "50px",
"text-align": "center"
});
var treasureHit = Global_wiki.npObj.treasure.hit;
jQ1("#txtTreasureHit").val(treasureHit);
} else { //原本显示状态,现在要隐藏
jQ1(".trCalcBox").hide();
jQ1("#txtNpBuff").val("0");
jQ1("#txtTreasureHit").val(Global_wiki.npObj.treasure.hit); //恢复宝具Hit数默认值
jQ1("#txtArtsBuff").val(Global_wiki.npObj.careerSkill.artsBuff); //恢复被动蓝卡BUFF
jQ1("#txtQuickBuff").val(Global_wiki.npObj.careerSkill.quickBuff); //恢复被动绿卡BUFF
jQ1(".calcBox input[type=checkbox]").prop("checked", false);
jQ1(".spanEnemyCorrections").html("1");
jQ1(".spanTopTimes").html("5");
reCalc();
}
jQ1(".trCalcBox").data("show", show == "0" ? "1" : "0");
});
//绑定【NP获得提升】、【蓝魔放】、【绿魔放】输入内容改变事件
jQ1(".calcBox input[type=number]").bind("input propertychange",
function () {
reCalc();
});
//绑定【第五势】勾选状态切换事件
jQ1("#ckSpecialSkill1").change(function () {
var checked = jQ1("#ckSpecialSkill1").prop("checked");
if (checked) {
Global_wiki.npObj.arts.hit *= 2;
Global_wiki.npObj.buster.hit *= 2;
Global_wiki.npObj.quick.hit *= 2;
Global_wiki.npObj.ex.hit *= 2;
} else {
Global_wiki.npObj.arts.hit = parseInt(jQ1(".ArtHit").text());
Global_wiki.npObj.buster.hit = parseInt(jQ1(".BusterHit").text());
Global_wiki.npObj.quick.hit = parseInt(jQ1(".QuickHit").text());
Global_wiki.npObj.ex.hit = parseInt(jQ1(".ExtraHit").text());
}
reCalc();
});
//绑定【鞭尸】、【暴击】、【忽略宝具组合】勾选状态切换事件
jQ1(".calcBox input[type=checkbox]:not(#ckSpecialSkill1)").change(function () {
reCalc();
});
});
function setFixWidth() {
jQ1(".fixWidth").css({
"display": "inline-block",
"width": "120px",
"text-align": "left"
});
}
function getContentHtml(cardStr, npObj) {
return "<span class='fixWidth'>${cardStr}+EX:</span> <span class='fixWidth'>首卡:${npObj.first}</span> <span class='fixWidth'>次卡:${npObj.second}</span> <span class='fixWidth'>尾卡:${npObj.third}</span><span class='fixWidth'> EX:${npObj.ex} </span><span class='fixWidth'>总计:${npObj.totalNp}</span><br>".replace('${cardStr}', cardStr).replace('${npObj.first}', npObj.first).replace('${npObj.second}', npObj.second).replace('${npObj.third}', npObj.third).replace('${npObj.ex}', npObj.ex).replace('${npObj.totalNp}',npObj.totalNp);
}
function reCalc() {
'use strict';
var cardArr = Global_wiki.cardArr;
var npArr = [];
cardArr.forEach(function (res) {
// abq
if (!(jQ1("#ckIsIgnoreTreasure").prop("checked") && res.includes("宝"))) {
var npObj = calcCardNp(res);
npArr.push(npObj);
}
});
npArr = npArr.sort(compare("totalNp"));
jQ1(".calcResult").empty();
var contenHtml = "";
for (var i = 0; i < npArr.length; i++) {
var npObj = npArr[i],
cardStr = npObj.cardStr;
if (!cardStr.includes("宝")) cardStr = " " + cardStr;
var topTimes = jQ1("#txtTopTimes").val();
topTimes = isNaN(topTimes) ? 5 : topTimes;
if (i == topTimes) break;
contenHtml += getContentHtml(cardStr, npObj);
}
var t = Global_wiki.npObj.treasure,
treasureNP = calcTreasureNP(t.card);
jQ1("#spanTreasureNP").text(treasureNP);
jQ1(".calcResult").html(contenHtml);
setFixWidth();
}
function loadNpData(no) {
'use strict';
var isOk = false;
jQ1.ajaxSettings.async = false; //同步执行
jQ1.getJSON('https://xianlechuanshuo.github.io/fgo/js/nps.json', {
rd: Math.random()
},
function (data, textStatus) {
if (textStatus == "success") {
for (var i = 0; i < data.length; i++) {
if (data[i].n == no) {
Global_wiki.tmpNpObj = data[i];
isOk = true;
break;
}
}
}
});
jQ1.ajaxSettings.async = true; //异步执行
return isOk;
}
function getIsOverkillAndisCritical(position) {
'use strict';
var ckIsOverkill_first = jQ1("#ckIsOverkill_first").prop("checked"),
ckIsCritical_first = jQ1("#ckIsCritical_first").prop("checked"),
ckIsOverkill_second = jQ1("#ckIsOverkill_second").prop("checked"),
ckIsCritical_second = jQ1("#ckIsCritical_second").prop("checked"),
ckIsOverkill_third = jQ1("#ckIsOverkill_third").prop("checked"),
ckIsCritical_third = jQ1("#ckIsCritical_third").prop("checked"),
ckIsOverkill_ex = jQ1("#ckIsOverkill_ex").prop("checked"),
isOverkill = 1,
isCritical = 1;
switch (position) {
case 1:
//1位
isOverkill = ckIsOverkill_first === true ? 1.5 : 1;
isCritical = ckIsCritical_first === true ? 2 : 1;
break;
case 2:
//2位
isOverkill = ckIsOverkill_second === true ? 1.5 : 1;
isCritical = ckIsCritical_second === true ? 2 : 1;
break;
case 3:
//3位
isOverkill = ckIsOverkill_third === true ? 1.5 : 1;
isCritical = ckIsCritical_third === true ? 2 : 1;
break;
case 4:
//四位EX
isOverkill = ckIsOverkill_ex === true ? 1.5 : 1;
break;
}
return {
isOverkill: isOverkill,
isCritical: isCritical
};
}
function calcTreasureNP(card) {
'use strict';
// NP获得量 = 基本NP获得率(baseNp) × [(卡片倍率 x (1 ± 卡片性能Buff)] × (1 + NP获得量Buff)
// × Overkill补正 × 攻击Hit数 × 敌补正(假设为1)
// console.log("calcTreasureNP card:"+card);
var cardObj = getTreasureDetials(card);
// console.log(cardObj);
var np = cardObj.baseNp * [cardObj.cardRate * (1 + cardObj.cardBuff)] * (1 + cardObj.npBuff) * cardObj.isOverkill * cardObj.hit * cardObj.enemyCorrections;
return Math.floor(np * 100) / 100;
}
function getTreasureDetials(card) {
var t = Global_wiki.npObj.treasure,
c = Global_wiki.npObj.careerSkill;
if (card == "宝") card = t.card;
var treasureHit = jQ1("#txtTreasureHit").length === 0 ? t.hit : parseInt(jQ1("#txtTreasureHit").val()),
artsBuff = jQ1("#txtArtsBuff").length === 0 ? c.artsBuff / 100 : parseFloat(jQ1("#txtArtsBuff").val()) / 100,
quickBuff = jQ1("#txtQuickBuff").length === 0 ? c.quickBuff / 100 : parseFloat(jQ1("#txtQuickBuff").val()) / 100,
cardBuff = 0,
npBuff = jQ1("#txtNpBuff").length === 0 ? 0 : parseFloat(jQ1("#txtNpBuff").val()) / 100,
isOverkill = jQ1("#ckIsOverkill_treasure").prop("checked") === true ? 1.5 : 1,
enemyCorrections = jQ1("#txtEnemyCorrections").length === 0 ? 1 : parseFloat(jQ1("#txtEnemyCorrections").val()),
cardRate = 0;
switch (card) {
case "A":
cardRate = 3;
cardBuff = artsBuff;
break;
case "B":
cardRate = 0;
break;
case "Q":
cardRate = 1;
cardBuff = quickBuff;
break;
}
return {
cardRate: cardRate,
baseNp: t.np,
hit: treasureHit,
cardBuff: cardBuff,
npBuff: npBuff,
isOverkill: isOverkill,
enemyCorrections: enemyCorrections
};
}
// 计算单卡NP
function calcSingleCardNp(firstCardReward, card, position) {
'use strict';
// NP获得量 = 基本NP获得率(baseNp) × [(首卡加成 + 卡片倍率 x (1 ± 卡片性能Buff)] × (1 + NP获得量Buff)
// × Critical补正 × Overkill补正 × 攻击Hit数 × 敌补正(假设为1)
var cardObj = getCardDetails(card, position);
var np = cardObj.baseNp * [firstCardReward + cardObj.cardRate * (1 + cardObj.cardBuff)] * (1 + cardObj.npBuff) * cardObj.isCritical * cardObj.isOverkill * cardObj.hit * cardObj.enemyCorrections;
return Math.floor(np * 100) / 100;
}
function getCardDetails(card, position) {
'use strict';
var cardRate = 0,
a = Global_wiki.npObj.arts,
b = Global_wiki.npObj.buster,
q = Global_wiki.npObj.quick,
e = Global_wiki.npObj.ex,
c = Global_wiki.npObj.careerSkill,
artsBuff = jQ1("#txtArtsBuff").length === 0 ? c.artsBuff / 100 : parseFloat(jQ1("#txtArtsBuff").val()) / 100,
quickBuff = jQ1("#txtQuickBuff").length === 0 ? c.quickBuff / 100 : parseFloat(jQ1("#txtQuickBuff").val()) / 100,
npBuff = jQ1("#txtNpBuff").length === 0 ? 0 : parseFloat(jQ1("#txtNpBuff").val()) / 100,
enemyCorrections = jQ1("#txtEnemyCorrections").length === 0 ? 1 : parseFloat(jQ1("#txtEnemyCorrections").val());
var temp = getIsOverkillAndisCritical(position);
switch (card) {
case "A":
switch (position) {
case 1:
//1位A卡
cardRate = 3;
break;
case 2:
//2位A卡
cardRate = 4.5;
break;
case 3:
//3位A卡
cardRate = 6;
break;
}
return {
cardRate: cardRate,
baseNp: a.np,
hit: a.hit,
cardBuff: artsBuff,
npBuff: npBuff,
isOverkill: temp.isOverkill,
isCritical: temp.isCritical,
enemyCorrections: enemyCorrections
};
case "B":
return {
cardRate:
0,
baseNp: b.np,
hit: b.hit,
cardBuff: 0,
npBuff: npBuff,
isOverkill: temp.isOverkill,
isCritical: temp.isCritical,
enemyCorrections: enemyCorrections
};
case "Q":
switch (position) {
case 1:
//1位Q卡
cardRate = 1;
break;
case 2:
//2位Q卡
cardRate = 1.5;
break;
case 3:
//3位Q卡
cardRate = 2;
break;
}
return {
cardRate: cardRate,
baseNp: q.np,
hit: q.hit,
cardBuff: quickBuff,
npBuff: npBuff,
isOverkill: temp.isOverkill,
isCritical: temp.isCritical,
enemyCorrections: enemyCorrections
};
case "EX":
return {
cardRate:
1,
baseNp: e.np,
hit: e.hit,
cardBuff: 0,
npBuff: npBuff,
isOverkill: temp.isOverkill,
isCritical: temp.isCritical,
enemyCorrections: enemyCorrections
};
}
}
//从大到小排序
function compare(property) {
'use strict';
return function (a, b) {
var value1 = a[property];
var value2 = b[property];
return value2 - value1;
};
}
function calcCardNp(cardStr) {
'use strict';
var first = cardStr[0],
second = cardStr[1],
third = cardStr[2],
firstCardReward = 0,
isCritical = 1,
isOverkill = 1,
enemyCorrections = 1,
ex = 0,
totalNp = 0,
t = Global_wiki.npObj.treasure,
artChainBuff = 0;
// console.log(t);
// console.log(`cardStr:${cardStr},first:${first},second:${second},third:${third}`);
if (first == "A" || (first == "宝" && t.card == "A")) { //首卡加成:1
firstCardReward = 1;
}
if (cardStr == "AAA") artChainBuff = 20;
var tmpSecond = second,
tempThird = third;
var treasureNP = calcTreasureNP("宝");
first = first == "宝" ? treasureNP : calcSingleCardNp(firstCardReward, first, 1);
second = second == "宝" ? treasureNP : calcSingleCardNp(firstCardReward, second, 2);
third = third == "宝" ? treasureNP : calcSingleCardNp(firstCardReward, third, 3);
//宝具放完NP就清光了_(:з」∠)_
if (tmpSecond == "宝") { //A宝A,第一位A的NP清零
first = 0;
} else if (tempThird == "宝") { //AA宝,第一位和第二位A的NP清零
first = 0;
second = 0;
}
ex = calcSingleCardNp(firstCardReward, "EX", 4);
// console.log(`cardStr:${cardStr},first:${first},second:${second},third:${third},artChainBuff:${artChainBuff}`);
totalNp = Math.floor((first + second + third + ex + artChainBuff) * 100) / 100;
return {
cardStr: cardStr,
first: first,
second: second,
third: third,
ex: ex,
totalNp: totalNp
};
}
*/