实现分段HP详情功能

This commit is contained in:
枫谷剑仙 2021-03-16 21:31:11 +08:00
parent b7f12be789
commit 5a33cb9864
12 changed files with 551 additions and 90 deletions

View File

@ -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";
}

View File

@ -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: "簡単な検索";
}

View File

@ -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: "간단한 검색";
}

View File

@ -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]

View File

@ -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: "簡易搜索";
}

View File

@ -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: "简易搜索";
}

View File

@ -83,6 +83,7 @@ var formation = new Formation(teamsCount,5);
<span class="reduce-scale"></span>
<span class="general"></span>
<span class="awoken-bind"></span>
<canvas height="20" width="100" class="reduce-details display-none"></canvas>
</span>
</div>
<div class="tIf-effect">
@ -596,6 +597,11 @@ var formation = new Formation(teamsCount,5);
</ul>
</div>
<div class="detail-box edit"><textarea class="detail" placeholder="输入说明"></textarea><div class="detail-display"></div></div>
<div class="dialog dialog-hp-detail display-none">
<div class="dialog-title"></div>
<div class="dialog-content"></div>
<div class="dialog-control"><button class="dialog-close brown-button"></button></div>
</div>
</div>
<div class="edit-box display-none">
<div class="edit-box-title"><!--修改怪物--></div>

View File

@ -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);
}

193
script.js
View File

@ -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)); //队伍封觉醒满血加上盾能承受的最大伤害

View File

@ -83,6 +83,7 @@ var formation = new Formation(teamsCount,6);
<span class="reduce-scale"></span>
<span class="general"></span>
<span class="awoken-bind"></span>
<canvas height="20" width="100" class="reduce-details display-none"></canvas>
</span>
</div>
<div class="tIf-total-move">
@ -476,6 +477,11 @@ var formation = new Formation(teamsCount,6);
</li>
</ul>
<div class="detail-box edit"><textarea class="detail" placeholder="输入说明"></textarea><div class="detail-display"></div></div>
<div class="dialog dialog-hp-detail display-none">
<div class="dialog-title"></div>
<div class="dialog-content"></div>
<div class="dialog-control"><button class="dialog-close brown-button"></button></div>
</div>
</div>
<div class="edit-box display-none">
<div class="edit-box-title"><!--修改怪物--></div>

View File

@ -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
{

View File

@ -98,6 +98,7 @@ var formation = new Formation(teamsCount,6);
<span class="reduce-scale"></span>
<span class="general"></span>
<span class="awoken-bind"></span>
<canvas height="20" width="100" class="reduce-details display-none"></canvas>
</span>
</div>
<div class="tIf-total-move">
@ -518,6 +519,7 @@ var formation = new Formation(teamsCount,6);
<span class="reduce-scale"></span>
<span class="general"></span>
<span class="awoken-bind"></span>
<canvas height="20" width="100" class="reduce-details display-none"></canvas>
</span>
</div>
<div class="tIf-total-move">
@ -938,6 +940,7 @@ var formation = new Formation(teamsCount,6);
<span class="reduce-scale"></span>
<span class="general"></span>
<span class="awoken-bind"></span>
<canvas height="20" width="100" class="reduce-details display-none"></canvas>
</span>
</div>
<div class="tIf-total-move">
@ -1331,6 +1334,11 @@ var formation = new Formation(teamsCount,6);
</li>
</ul>
<div class="detail-box edit"><textarea class="detail" placeholder="输入说明"></textarea><div class="detail-display"></div></div>
<div class="dialog dialog-hp-detail display-none">
<div class="dialog-title"></div>
<div class="dialog-content"></div>
<div class="dialog-control"><button class="dialog-close brown-button"></button></div>
</div>
</div>
<div class="edit-box display-none">
<div class="edit-box-title"><!--修改怪物--></div>