diff --git a/languages/en.css b/languages/en.css
index 26aaa1b5..39f3a79e 100644
--- a/languages/en.css
+++ b/languages/en.css
@@ -271,6 +271,43 @@
content: " sec";
}
+.dialog-hp-detail .dialog-title::before
+{
+ content: "HP Range Reduction Details";
+}
+.hp-range-table .hp-range th::before
+{
+ content: "HP Range";
+}
+.hp-range-table .reduce-scale .reduce-probability:before
+{
+ content: "Odds ";
+}
+.hp-range-table caption::before
+{
+ content: "All Attribute Enemy";
+}
+.hp-range-table[data-attr="0"] caption::before
+{
+ content: "Fire Attribute Enemy";
+}
+.hp-range-table[data-attr="1"] caption::before
+{
+ content: "Water Attribute Enemy";
+}
+.hp-range-table[data-attr="2"] caption::before
+{
+ content: "Wood Attribute Enemy";
+}
+.hp-range-table[data-attr="3"] caption::before
+{
+ content: "Light Attribute Enemy";
+}
+.hp-range-table[data-attr="4"] caption::before
+{
+ content: "Dark Attribute Enemy";
+}
+
.setting-box .row-mon-id .open-search::before{
content: "Simple Search";
}
diff --git a/languages/ja.css b/languages/ja.css
index 3afc1045..a6bc8c79 100644
--- a/languages/ja.css
+++ b/languages/ja.css
@@ -263,6 +263,43 @@
content: " 秒";
}
+.dialog-hp-detail .dialog-title::before
+{
+ content: "HP 範囲減傷の詳細";
+}
+.hp-range-table .hp-range th::before
+{
+ content: "HP 範囲";
+}
+.hp-range-table .reduce-scale .reduce-probability:before
+{
+ content: "確率 ";
+}
+.hp-range-table caption::before
+{
+ content: "すべての属性の敵";
+}
+.hp-range-table[data-attr="0"] caption::before
+{
+ content: "火属性の敵";
+}
+.hp-range-table[data-attr="1"] caption::before
+{
+ content: "水属性の敵";
+}
+.hp-range-table[data-attr="2"] caption::before
+{
+ content: "木属性の敵";
+}
+.hp-range-table[data-attr="3"] caption::before
+{
+ content: "光属性の敵";
+}
+.hp-range-table[data-attr="4"] caption::before
+{
+ content: "暗属性の敵";
+}
+
.setting-box .row-mon-id .open-search::before{
content: "簡単な検索";
}
diff --git a/languages/ko.css b/languages/ko.css
index 11df11ad..7faec88d 100644
--- a/languages/ko.css
+++ b/languages/ko.css
@@ -260,6 +260,43 @@
content: " 초";
}
+.dialog-hp-detail .dialog-title::before
+{
+ content: "HP 범위 손상 감소 세부 정보";
+}
+.hp-range-table .hp-range th::before
+{
+ content: "HP 범위";
+}
+.hp-range-table .reduce-scale .reduce-probability:before
+{
+ content: "확률 ";
+}
+.hp-range-table caption::before
+{
+ content: "모든 속성의 적";
+}
+.hp-range-table[data-attr="0"] caption::before
+{
+ content: "화재 속성의 적";
+}
+.hp-range-table[data-attr="1"] caption::before
+{
+ content: "물 속성의 적";
+}
+.hp-range-table[data-attr="2"] caption::before
+{
+ content: "나무 속성의 적";
+}
+.hp-range-table[data-attr="3"] caption::before
+{
+ content: "빛의 속성의 적";
+}
+.hp-range-table[data-attr="4"] caption::before
+{
+ content: "숨겨진 속성의 적";
+}
+
.setting-box .row-mon-id .open-search::before{
content: "간단한 검색";
}
diff --git a/languages/zh-CN.js b/languages/zh-CN.js
index c45482f2..7b7c161a 100644
--- a/languages/zh-CN.js
+++ b/languages/zh-CN.js
@@ -36,9 +36,9 @@ function findFullSkill(subSkill) {
}
//document.querySelector(".edit-box .row-mon-id .m-id").type = "number";
/* 快速搜索指定类型的技能
-var result = Skills.filter(s=>{const sk = s.params; return s.type == 156;}).map(findFullSkill);
-console.table(result);
+var result = Skills.filter(s=>{const sk = s.params; return [130,131].includes(s.type);}).map(findFullSkill);
showSearch(result.map(o=>o.card).filter(c=>c));
+console.table(result);
*/
//返回flag里值为true的数组,如[1,4,7]
diff --git a/languages/zh-TW.css b/languages/zh-TW.css
index 64949280..68f32682 100644
--- a/languages/zh-TW.css
+++ b/languages/zh-TW.css
@@ -266,6 +266,43 @@
content: " 秒";
}
+.dialog-hp-detail .dialog-title::before
+{
+ content: "HP 階段減傷詳情";
+}
+.hp-range-table .hp-range th::before
+{
+ content: "HP 範圍";
+}
+.hp-range-table .reduce-scale .reduce-probability:before
+{
+ content: "幾率 ";
+}
+.hp-range-table caption::before
+{
+ content: "全屬性敵人";
+}
+.hp-range-table[data-attr="0"] caption::before
+{
+ content: "火屬性敵人";
+}
+.hp-range-table[data-attr="1"] caption::before
+{
+ content: "水屬性敵人";
+}
+.hp-range-table[data-attr="2"] caption::before
+{
+ content: "木屬性敵人";
+}
+.hp-range-table[data-attr="3"] caption::before
+{
+ content: "光屬性敵人";
+}
+.hp-range-table[data-attr="4"] caption::before
+{
+ content: "暗屬性敵人";
+}
+
.setting-box .row-mon-id .open-search::before{
content: "簡易搜索";
}
diff --git a/languages/zh.css b/languages/zh.css
index 1447ec77..e9972c81 100644
--- a/languages/zh.css
+++ b/languages/zh.css
@@ -265,6 +265,43 @@
content: " 秒";
}
+.dialog-hp-detail .dialog-title::before
+{
+ content: "HP 階段減傷詳情";
+}
+.hp-range-table .hp-range th::before
+{
+ content: "HP 范围";
+}
+.hp-range-table .reduce-scale .reduce-probability:before
+{
+ content: "几率 ";
+}
+.hp-range-table caption::before
+{
+ content: "全属性敵人";
+}
+.hp-range-table[data-attr="0"] caption::before
+{
+ content: "火属性敵人";
+}
+.hp-range-table[data-attr="1"] caption::before
+{
+ content: "水属性敵人";
+}
+.hp-range-table[data-attr="2"] caption::before
+{
+ content: "木属性敵人";
+}
+.hp-range-table[data-attr="3"] caption::before
+{
+ content: "光属性敵人";
+}
+.hp-range-table[data-attr="4"] caption::before
+{
+ content: "暗属性敵人";
+}
+
.setting-box .row-mon-id .open-search::before{
content: "简易搜索";
}
diff --git a/multi.html b/multi.html
index fc35edcd..a53e8991 100644
--- a/multi.html
+++ b/multi.html
@@ -83,6 +83,7 @@ var formation = new Formation(teamsCount,5);
+
diff --git a/script-universal_function.js b/script-universal_function.js
index bacf4cf1..46445274 100644
--- a/script-universal_function.js
+++ b/script-universal_function.js
@@ -52,10 +52,20 @@ Number.prototype.prefixInteger = function(length, useGrouping = false) {
minimumIntegerDigits: length
});
}
- //大数字缩短长度,默认返回本地定义字符串
+//大数字缩短长度,默认返回本地定义字符串
Number.prototype.bigNumberToString = function() {
return this.toLocaleString();
}
+//将二进制flag转为数组
+function flags(num) {
+ const arr = [];
+ for (let i = 0; i < 32; i++) {
+ if (num & (1 << i)) {
+ arr.push(i);
+ }
+ }
+ return arr;
+}
//数组删除自己尾部的空元素
Array.prototype.DeleteLatter = function(item = null) {
@@ -553,15 +563,6 @@ function countTeamHp(memberArr, leader1id, leader2id, solo, noAwoken = false) {
//console.log('单个队伍血量:',mHpArr,mHpArr.reduce((p,c)=>p+c));
function memberHpMul(card, ls, memberArr, solo) {
- function flags(num) {
- const arr = [];
- for (let i = 0; i < 32; i++) {
- if (num & (1 << i)) {
- arr.push(i);
- }
- }
- return arr;
- }
function hpMul(parm, scale) {
if (scale == undefined || scale == 0) return 1;
@@ -842,8 +843,75 @@ function countMoveTime(team, leader1id, leader2id, teamIdx) {
return moveTime;
}
-//获取盾减伤比例
-function getReduceScale(leaderid, allAttr = false, noHPneed = false, noProbability = false) {
+//将盾减伤比例组叠加为一个减伤范围组
+function getReduceRange(reduceScales)
+{
+ class reduceRange{
+ constructor(obj)
+ {
+ this.min = 0;
+ this.max = 100;
+ this.scale = 0;
+ this.probability = 1;
+ if (typeof obj == "object") Object.assign(this, obj);
+ }
+ }
+ const ranges = [new reduceRange()];
+ const attrsRanges = new Array(5).fill(ranges); //5中属性的,默认填充第一个ranges的指针
+ function processingRanges(ranges, scale)
+ {
+ //先找scale.min在某个范围内的
+ const rgLessIdx = ranges.findIndex(range=>scale.hp.min > range.min && scale.hp.min < range.max),
+ //再找scale.max在某个范围内的
+ rgMoreIdx = ranges.findIndex(range=>scale.hp.max > range.min && scale.hp.max < range.max);
+ //先只拆分不乘比例
+ if (rgLessIdx >= 0)
+ {
+ const range = ranges[rgLessIdx];
+ ranges.splice(rgLessIdx, 1,
+ new reduceRange({min:range.min, max:scale.hp.min, scale: range.scale}),
+ new reduceRange({min:scale.hp.min, max:range.max, scale: range.scale})
+ );
+ }
+ if (rgMoreIdx >= 0)
+ {
+ const range = ranges[rgMoreIdx];
+ ranges.splice(rgMoreIdx, 1,
+ new reduceRange({min:range.min, max:scale.hp.max, scale: range.scale}),
+ new reduceRange({min:scale.hp.max, max:range.max, scale: range.scale})
+ );
+ }
+ const needChangeScaleRanges = ranges.filter(range=>range.min >= scale.hp.min && range.max <= scale.hp.max);
+ needChangeScaleRanges.forEach(range=>{
+ range.scale = 1 - (1 - range.scale) * (1 - scale.scale);
+ range.probability *= scale.probability;
+ });
+ }
+ //对scale进行排序,将所有全属性减伤的靠前,部分属性的靠后,这样前面的就只需要计算一次,后面的计算多次
+ reduceScales.sort((a,b)=>b.attrs - a.attrs);
+
+ reduceScales.forEach(scale=>{
+ if (scale.attrs == 0) //没有属性的
+ {
+ return;
+ }
+ else if ((scale.attrs & 31) != 31) //不符合全属性的
+ {
+ const attrs = flags(scale.attrs); //得到属性数组
+ attrs.forEach(n=>{
+ attrsRanges[n] = attrsRanges[n].map(range=>new reduceRange(range)); //复制一个新数组
+ processingRanges(attrsRanges[n], scale); //计算这个数组的减伤比例
+ });
+ }
+ else
+ { //只处理第一数组
+ processingRanges(ranges, scale);
+ }
+ });
+ return attrsRanges;
+}
+//获取盾减伤比例组
+function getReduceScales(leaderid) {
const searchTypeArray = [16, 17, 36, 38, 43, 129, 163, 130, 131, 151, 169, 198, 170, 182, 193, 171, 183];
const lss = getCardLeaderSkills(Cards[leaderid], searchTypeArray);
@@ -865,11 +933,11 @@ function getReduceScale(leaderid, allAttr = false, noHPneed = false, noProbabili
break;
case 17: //单属性盾
reduce.scale = sk[1] / 100;
- reduce.attr = 0 | sk[0] >= 0 ? 1 << sk[0] : 0;
+ reduce.attrs = 0 | (sk[0] >= 0 ? 1 << sk[0] : 0);
break;
case 36: //2个属性盾
reduce.scale = sk[2] / 100;
- reduce.attr = 0 | sk[0] >= 0 ? 1 << sk[0] : 0 | sk[1] >= 0 ? 1 << sk[1] : 0;
+ reduce.attrs = 0 | (sk[0] >= 0 ? 1 << sk[0] : 0) | (sk[1] >= 0 ? 1 << sk[1] : 0);
break;
case 38: //血线下 + 可能几率
case 43: //血线上 + 可能几率
@@ -884,11 +952,11 @@ function getReduceScale(leaderid, allAttr = false, noHPneed = false, noProbabili
if(ls.type == 38)
{
reduce.hp.max = sk[0];
- reduce.hp.mix = 0;
+ reduce.hp.min = 0;
}else
{
reduce.hp.max = 100;
- reduce.hp.mix = sk[0];
+ reduce.hp.min = sk[0];
}
}
break;
@@ -897,7 +965,7 @@ function getReduceScale(leaderid, allAttr = false, noHPneed = false, noProbabili
case 130: //血线下 + 属性个数不固定
case 131: //血线上 + 属性个数不固定
reduce.scale = (sk[6] || 0) / 100;
- reduce.attr = 0 | sk[5];
+ reduce.attrs = 0 | sk[5];
if (ls.type == 130 || ls.type == 131)
{
if (sk[0] == 100)
@@ -909,11 +977,11 @@ function getReduceScale(leaderid, allAttr = false, noHPneed = false, noProbabili
if(ls.type == 130)
{
reduce.hp.max = sk[0];
- reduce.hp.mix = 0;
+ reduce.hp.min = 0;
}else
{
reduce.hp.max = 100;
- reduce.hp.mix = sk[0];
+ reduce.hp.min = sk[0];
}
}
}
@@ -940,62 +1008,12 @@ function getReduceScale(leaderid, allAttr = false, noHPneed = false, noProbabili
}else
{
reduce.hp.max = 100;
- reduce.hp.mix = sk[2];
+ reduce.hp.min = sk[2];
}
break;
default:
}
return reduce;
}
-
- return lss.map(leaderReduceScale);
-
- const sk = ls.params;
- let scale = 0;
- const skills = getActuallySkills(ls);
- switch (ls.type) {
- case 16: //无条件盾
- scale = sk[0] / 100;
- break;
- case 17: //单属性盾
- scale = allAttr ? 0 : sk[1] / 100;
- break;
- case 36: //2个属性盾
- scale = allAttr ? 0 : sk[2] / 100;
- break;
- case 38: //血线下 + 可能几率
- case 43: //血线上 + 可能几率
- scale = (noHPneed || noProbability && sk[1] !== 100) ? 0 : sk[2] / 100;
- break;
- case 129: //无条件盾,属性个数不固定
- case 163: //无条件盾,属性个数不固定
- scale = (allAttr && (sk[5] & 31) != 31) ? 0 : sk[6] / 100;
- break;
- case 130: //血线下 + 属性个数不固定
- case 131: //血线上 + 属性个数不固定
- scale = (noHPneed || allAttr && (sk[5] & 31) != 31) ? 0 : sk[6] / 100;
- break;
- case 151: //十字心触发
- case 169: //C触发
- case 198: //回血触发
- scale = sk[2] / 100;
- break;
- case 170: //多色触发
- case 182: //长串触发
- case 193: //L触发
- scale = sk[3] / 100;
- break;
- case 171: //多串触发
- scale = sk[6] / 100;
- break;
- case 183: //又是个有两段血线的队长技
- scale = noHPneed ? 0 : sk[4] / 100;
- break;
-
- case 138: //调用其他队长技
- scale = sk.reduce((pmul, skid) => 1 - (1 - pmul) * (1 - getReduceScale(Skills[skid], allAttr, noHPneed)), 0);
- break;
- default:
- }
- return scale || 0;
+ return lss.map(leaderReduceScale).filter(re=>re.scale > 0);
}
\ No newline at end of file
diff --git a/script.js b/script.js
index aaf76cb0..ee0df3ed 100644
--- a/script.js
+++ b/script.js
@@ -1073,6 +1073,103 @@ function initialize() {
badges.forEach(badge => badge.onclick = setBadge);
});
+ //显示HP的详细值
+ const hpDetailDialog = formationBox.querySelector(".dialog-hp-detail");
+ hpDetailDialog.show = function(reduceAttrRanges, tHP, tHPNoAwoken)
+ {
+ const dialogContent = this.querySelector(".dialog-content");
+ const fragment = document.createDocumentFragment();
+
+ function insertHpRangeTable(reduceRanges, tHP, tHPNoAwoken, attr)
+ {
+ const table = document.createElement("table");
+ table.className = "hp-range-table";
+ table.setAttribute("data-attr", attr);
+ table.createCaption();
+ const tHead = table.createTHead();
+ const tBody = table.createTBody();
+ const rangeRow = tHead.insertRow();
+ rangeRow.className = "hp-range";
+ rangeRow.appendChild(document.createElement("th"));
+ const rageHpRow = tBody.insertRow();
+ rageHpRow.className = "general";
+ rageHpRow.appendChild(document.createElement("th"));
+ const rageHpNoAwokenRow = tBody.insertRow();
+ rageHpNoAwokenRow.className = "awoken-bind";
+ rageHpNoAwokenRow.appendChild(document.createElement("th"));
+ const reduceRow = tBody.insertRow();
+ reduceRow.className = "reduce-scale";
+ reduceRow.appendChild(document.createElement("th"));
+ const reduceHpRow = tBody.insertRow();
+ reduceHpRow.className = "reduce-general";
+ reduceHpRow.appendChild(document.createElement("th"));
+ const reduceHpNoAwokenRow = tBody.insertRow();
+ reduceHpNoAwokenRow.className = "reduce-awoken-bind";
+ reduceHpNoAwokenRow.appendChild(document.createElement("th"));
+ reduceRanges.forEach(range=>{
+ const hpRange = rangeRow.insertCell();
+ const hpRangeMin = hpRange.appendChild(document.createElement("span"));
+ hpRangeMin.className = "hp-range-min";
+ hpRangeMin.textContent = range.min;
+ hpRange.appendChild(document.createTextNode(" ~ "));
+ const hpRangeMax = hpRange.appendChild(document.createElement("span"));
+ hpRangeMax.className = "hp-range-max";
+ hpRangeMax.textContent = range.max;
+
+ const hpGeneral = rageHpRow.insertCell();
+ hpGeneral.textContent = `${Math.round(tHP * (range.min / 100))} ~ ${Math.round(tHP * (range.max/100))}`;
+
+ const hpAwokenBind = rageHpNoAwokenRow.insertCell();
+ hpAwokenBind.textContent = `${Math.round(tHPNoAwoken * (range.min / 100))} ~ ${Math.round(tHPNoAwoken * (range.max/100))}`;
+
+ const reduce = reduceRow.insertCell();
+ const reduceScale = reduce.appendChild(document.createElement("span"));
+ reduceScale.textContent = `${parseFloat((range.scale * 100).toFixed(2))}`;
+
+ if (range.probability < 1)
+ {
+ reduce.appendChild(document.createTextNode("("));
+ const reduceProb = reduce.appendChild(document.createElement("span"));
+ reduceProb.className = "reduce-probability";
+ reduceProb.textContent = `${(range.probability * 100).toFixed(0)}`;
+ reduce.appendChild(document.createTextNode(")"));
+ }
+
+ const reduceGeneral = reduceHpRow.insertCell();
+ reduceGeneral.textContent = `${Math.round(tHP * (range.min / 100) / (1 - range.scale))} ~ ${Math.round(tHP * (range.max/100) / (1 - range.scale))}`;
+
+ const reduceAwokenBind = reduceHpNoAwokenRow.insertCell();
+ reduceAwokenBind.textContent = `${Math.round(tHPNoAwoken * (range.min / 100) / (1 - range.scale))} ~ ${Math.round(tHPNoAwoken * (range.max/100) / (1 - range.scale))}`;
+ });
+ return table;
+ }
+ if (reduceAttrRanges.some(r=>r != reduceAttrRanges[0])) //有指定属性减伤
+ {
+ reduceAttrRanges.forEach((reduceRanges, ridx)=>fragment.appendChild(insertHpRangeTable(reduceRanges, tHP, tHPNoAwoken, ridx)));
+ }
+ else //只有阶梯盾
+ {
+ const reduceRanges = reduceAttrRanges[0];
+ fragment.appendChild(insertHpRangeTable(reduceRanges, tHP, tHPNoAwoken, 31));
+ }
+
+ dialogContent.innerHTML = "";
+ dialogContent.appendChild(fragment);
+ this.classList.remove(className_displayNone);
+ }
+ hpDetailDialog.close = function()
+ {
+ this.classList.add(className_displayNone);
+ }
+ const hpDetailDialog_Close = hpDetailDialog.querySelector(".dialog-close");
+ hpDetailDialog_Close.onclick = function(){hpDetailDialog.close();};
+ teamBigBoxs.forEach(teamBigBox => {
+ const reduceDetails = teamBigBox.querySelector(".tIf-total-hp .reduce-details");
+ reduceDetails.onclick = function(){
+ hpDetailDialog.show(this.reduceAttrRanges, this.tHP, this.tHPNoAwoken);
+ };
+ });
+
//编辑框
editBox.mid = null; //储存怪物id
editBox.latent = []; //储存潜在觉醒
@@ -2008,7 +2105,7 @@ function initialize() {
teamData[editBox.memberIdx[1]][editBox.memberIdx[2]] = mon;
- mon.id = parseInt(monstersID.value, 10);
+ mon.id = editBox.mid;
const card = Cards[mon.id] || Cards[0];
const skill = Skills[card.activeSkillId];
@@ -3067,6 +3164,43 @@ function setTextContentAndAttribute(dom,str)
dom.setAttribute(dataAttrName, str);
}
+function drawHpInfo(hpBarDom, reduceAttrRanges)
+{
+ const width = hpBarDom.width, height = hpBarDom.height;
+
+ let ctx = hpBarDom.getContext("2d");
+ console.log(reduceAttrRanges)
+ if (reduceAttrRanges.some(r=>r != reduceAttrRanges[0])) //有指定属性减伤
+ {
+ const attrColors = ['crimson','cornflowerblue','green','goldenrod','purple'];
+ reduceAttrRanges.forEach((reduceRanges, ridx)=>{
+ //console.table(reduceRanges);
+ ctx.fillStyle = attrColors[ridx];
+ ctx.fillRect(0, height / 5 * ridx, width, height / 5 * (ridx + 1));
+
+ reduceRanges.forEach(range=>{
+ ctx.fillStyle = `rgba(0, 0, 0, 0.5)`;
+ ctx.fillRect(width * (range.min / 100), height / 5 * ridx, width * (range.max / 100), height / 5 * (1 - range.scale));
+ });
+ });
+ }
+ else //只有阶梯盾
+ {
+ const reduceRanges = reduceAttrRanges[0];
+ //创建线性颜色渐变对象
+ const canvasGradient = ctx.createLinearGradient(0, 0, 0, height);
+ canvasGradient.addColorStop(0, "#EE99AA");
+ canvasGradient.addColorStop(0.4, "#FFDDEE");
+ canvasGradient.addColorStop(1, "#EE9999");
+ ctx.fillStyle = canvasGradient;
+ ctx.fillRect(0, 0, width, height);
+
+ reduceRanges.forEach(range=>{
+ ctx.fillStyle = `rgba(204, 0 ,85, 0.5)`;
+ ctx.fillRect(width * (range.min / 100), 0, width * ((range.max - range.min) / 100), height * (1 - range.scale));
+ });
+ }
+}
//刷新队伍能力值合计
function refreshTeamTotalHP(totalDom, team, teamIdx) {
//计算总的生命值
@@ -3081,9 +3215,24 @@ function refreshTeamTotalHP(totalDom, team, teamIdx) {
const leader2id = teamsCount===2 ? (teamIdx === 1 ? teams[0][0][0].id : teams[1][0][0].id) : team[0][5].id;
if (tHpDom) {
- const reduceScale1 = getReduceScale(leader1id,true,true,true);
- const reduceScale2 = getReduceScale(leader2id,true,true,true);
- const totalReduce = 1 - (1 - reduceScale1) * (1 - reduceScale2);
+ const reduceScales1 = getReduceScales(leader1id);
+ const reduceScales2 = getReduceScales(leader2id);
+ const reduceAttrRanges = getReduceRange(reduceScales1.concat(reduceScales2));
+ //将所有范围平铺,然后选择盾最少那个作为基础盾值
+ const leastScale = reduceAttrRanges.flat().sort((a,b)=>a.scale-b.scale)[0];
+
+ const hpBar = totalDom.querySelector(".reduce-details");
+
+ if (reduceAttrRanges.some(r=>r != reduceAttrRanges[0]) || reduceAttrRanges[0].length > 1 || reduceAttrRanges[0][0].probability < 1) //有阶梯盾或者有指定属性减伤或者减伤比例不是100%
+ {
+ drawHpInfo(hpBar, reduceAttrRanges);
+ hpBar.classList.remove(className_displayNone);
+ }else
+ {
+ hpBar.classList.add(className_displayNone);
+ }
+
+ const totalReduce = leastScale.scale;
const teamHPArr = countTeamHp(team[0], leader1id, leader2id, solo);
const teamHPNoAwokenArr = countTeamHp(team[0], leader1id, leader2id, solo, true);
@@ -3092,7 +3241,6 @@ function refreshTeamTotalHP(totalDom, team, teamIdx) {
let tHP = teamHPArr.reduce((pv, v) => pv + v); //队伍计算的总HP
let tHPNoAwoken = teamHPNoAwokenArr.reduce((pv, v) => pv + v); //队伍计算的总HP无觉醒
-
const teamHPAwoken = awokenCountInTeam(team, 46, solo, teamsCount); //全队大血包个数
let badgeHPScale = 1; //徽章倍率
@@ -3105,8 +3253,13 @@ function refreshTeamTotalHP(totalDom, team, teamIdx) {
tHP = Math.round(Math.round(tHP * (1 + 0.05 * teamHPAwoken)) * badgeHPScale);
tHPNoAwoken = Math.round(Math.round(tHPNoAwoken) * badgeHPScale);
- const tReduceHP = Math.round(tHP / (1 - reduceScale1) / (1 - reduceScale2)); //队伍正常满血加上盾能承受的最大伤害
- const tReduceHPNoAwoken = Math.round(tHPNoAwoken / (1 - reduceScale1) / (1 - reduceScale2)); //队伍封觉醒满血加上盾能承受的最大伤害
+ //记录到bar中,方便打开详情时调用
+ hpBar.reduceAttrRanges = reduceAttrRanges;
+ hpBar.tHP = tHP;
+ hpBar.tHPNoAwoken = tHPNoAwoken;
+
+ const tReduceHP = Math.round(tHP / (1 - totalReduce)); //队伍正常满血加上盾能承受的最大伤害
+ const tReduceHPNoAwoken = Math.round(tHPNoAwoken / (1 - totalReduce)); //队伍封觉醒满血加上盾能承受的最大伤害
const tHpDom_general = tHpDom.querySelector(".general");
const tHpDom_noAwoken = tHpDom.querySelector(".awoken-bind");
@@ -3201,9 +3354,24 @@ function refreshFormationTotalHP(totalDom, teams) {
if (tHpDom) {
- const reduceScale1 = getReduceScale(leader1id,true,true,true);
- const reduceScale2 = getReduceScale(leader2id,true,true,true);
- const totalReduce = 1 - (1 - reduceScale1) * (1 - reduceScale2);
+ const reduceScales1 = getReduceScales(leader1id);
+ const reduceScales2 = getReduceScales(leader2id);
+ const reduceAttrRanges = getReduceRange(reduceScales1.concat(reduceScales2));
+ //将所有范围平铺,然后选择盾最少那个作为基础盾值
+ const leastScale = reduceAttrRanges.flat().sort((a,b)=>a.scale-b.scale)[0];
+
+ const hpBar = totalDom.querySelector(".reduce-details");
+
+ if (reduceAttrRanges.some(r=>r != reduceAttrRanges[0]) || reduceAttrRanges[0].length > 1 || reduceAttrRanges[0][0].probability < 1) //有阶梯盾或者有指定属性减伤或者减伤比例不是100%
+ {
+ drawHpInfo(hpBar, reduceAttrRanges);
+ hpBar.classList.remove(className_displayNone);
+ }else
+ {
+ hpBar.classList.add(className_displayNone);
+ }
+
+ const totalReduce = leastScale.scale;
const tHPArr = teams.map(function(team) {
const teamHPArr = countTeamHp(team[0], leader1id, leader2id, solo);
@@ -3223,6 +3391,11 @@ function refreshFormationTotalHP(totalDom, teams) {
const tHP = tHPArr.reduce((pv, v) => pv + v);
const tHPNoAwoken = tHPNoAwokenArr.reduce((pv, v) => pv + v);
+ //记录到bar中,方便打开详情时调用
+ hpBar.reduceAttrRanges = reduceAttrRanges;
+ hpBar.tHP = tHP;
+ hpBar.tHPNoAwoken = tHPNoAwoken;
+
const tReduceHP = Math.round(tHP / (1 - reduceScale1) / (1 - reduceScale2)); //队伍正常满血加上盾能承受的最大伤害
const tReduceHPNoAwoken = Math.round(tHPNoAwoken / (1 - reduceScale1) / (1 - reduceScale2)); //队伍封觉醒满血加上盾能承受的最大伤害
diff --git a/solo.html b/solo.html
index 53295408..9dcd9263 100644
--- a/solo.html
+++ b/solo.html
@@ -83,6 +83,7 @@ var formation = new Formation(teamsCount,6);
+
diff --git a/style.css b/style.css
index 901ef733..bcf17592 100644
--- a/style.css
+++ b/style.css
@@ -594,35 +594,45 @@ ul{
.tIf-total-move .awoken-bind::before,
.tIf-total-move.fixed-move-time::after,
.tIf-effect icon::before,
-icon.poison-no-effect::after
+icon.poison-no-effect::after,
+.hp-range-table th::before
{
content: " ";
background-size: cover;
display: inline-block;
width: 20px;
height: 20px;
- vertical-align: top;
+ vertical-align: bottom;
}
.tIf-total-hp .awoken-bind::before,
.tIf-total-hp .reduce .awoken-bind::before,
-.tIf-total-move .awoken-bind::before
+.tIf-total-move .awoken-bind::before,
+.hp-range-table .awoken-bind th::before,
+.hp-range-table .reduce-awoken-bind th::before
{
background-image: url(images/icon-awoken-bind.png);
}
.tIf-total-hp .general::before,
-.tIf-total-hp .reduce .general::before
+.tIf-total-hp .reduce .general::before,
+.hp-range-table .general th::before,
+.hp-range-table .reduce-general th::before
{
background-image: url(images/icon-HP.png);
}
-.tIf-total-hp .reduce .reduce-scale::before{
+.tIf-total-hp .reduce .reduce-scale::before,
+.hp-range-table .reduce-scale th::before
+{
background-image: url(images/icon-reduce.png);
}
.tIf-total-hp .reduce .reduce-scale::after{
content: "%⇔";
}
-.tIf-total-hp .reduce.no-reduce .reduce-scale::after{
+.tIf-total-hp .reduce.no-reduce .reduce-scale::after,
+.hp-range-table .hp-range td span:after,
+.hp-range-table .reduce-scale td span:after
+{
content: "%";
}
.tIf-total-hp .reduce.no-reduce .general,
@@ -631,6 +641,57 @@ icon.poison-no-effect::after
display: none;
}
+.reduce-details
+{
+ cursor: pointer;
+ vertical-align: bottom;
+}
+.reduce-details:hover
+{
+ box-shadow: red 0 0 3px;
+}
+.hp-range-table
+{
+ font-family: var(--font-family);
+ border: 1px solid white;
+ background-color: saddlebrown;
+}
+.hp-range-table caption::before
+{
+ font-family: var(--game-font-family);
+}
+.hp-range-table td,
+.hp-range-table th
+{
+ border: 1px solid white;
+ padding: 0 4px;
+}
+.hp-range-table .hp-range th::before
+{
+ width: unset;
+ height: unset;
+}
+.hp-range-table[data-attr="0"]
+{
+ background-color: crimson;
+}
+.hp-range-table[data-attr="1"]
+{
+ background-color: cornflowerblue;
+}
+.hp-range-table[data-attr="2"]
+{
+ background-color: green;
+}
+.hp-range-table[data-attr="3"]
+{
+ background-color: goldenrod;
+}
+.hp-range-table[data-attr="4"]
+{
+ background-color: purple;
+}
+
.tIf-total-move .general::before{
background-image: url(images/icon-orb-move-time.png);
}
@@ -2434,6 +2495,7 @@ table .orb-icon
/*弹出窗口相关*/
.dialog
{
+ color: white;
position: absolute;
padding: 5px;
border: 2px ridge #D1D398;
@@ -2441,7 +2503,6 @@ table .orb-icon
background-image: linear-gradient(to bottom,#788321f0,#3E4D14f0);
border-radius: 6px;
box-shadow: black 2px 0px 1px,black 0px 2px 1px,black -2px 0px 1px,black 0px -2px 1px;
- width: 260px;
margin-left: calc(50% - 130px);
margin-top: 30px;
font-family: var(--game-font-family);
@@ -2508,6 +2569,10 @@ table .orb-icon
content: "关闭";
}
*/
+.dialog-search-string
+{
+ width: 260px;
+}
.dialog-search-string .string-copy,
.dialog-search-string .string-search
{
diff --git a/triple.html b/triple.html
index 917a2dca..9be4445c 100644
--- a/triple.html
+++ b/triple.html
@@ -98,6 +98,7 @@ var formation = new Formation(teamsCount,6);
+