diff --git a/languages/en.js b/languages/en.js
index e7fc1e66..7a56ff9b 100644
--- a/languages/en.js
+++ b/languages/en.js
@@ -2,7 +2,7 @@
webpage_title: `P&D ${teamsCount}P Formation Maker`,
title_blank: "Input Formation Title",
detail_blank: "Input Detail",
- sort_name:{
+ sort_name: {
sort_none: "Nope",
sort_id: "Cards Id",
sort_attrs : "Attribute",
@@ -21,6 +21,9 @@
sort_abilityIndex_awoken: "Maximum Weighted Ability Index (+Awakening)",
},
force_reload_data: "Force refresh data",
+ skill_parse: {
+ Unknown: "unknown skill",
+ },
}
localisation(localTranslating);
\ No newline at end of file
diff --git a/languages/zh-CN.css b/languages/zh-CN.css
index 9a28617b..0245588e 100644
--- a/languages/zh-CN.css
+++ b/languages/zh-CN.css
@@ -1,7 +1,8 @@
@charset "utf-8";
@import "zh.css";
.edit-box .monsterinfo-box .monster-name,
-.edit-box .skill-box .skill-datail,
+.edit-box .skill-box .skill-datail-original,
+.edit-box .skill-box .skill-datail-parsed,
.evo-panel-right .monster-name
{
font-family: "Microsoft Yahei","Source Han Sans",Arial, Helvetica, sans-serif;
diff --git a/multi.html b/multi.html
index 244b814f..4f435811 100644
--- a/multi.html
+++ b/multi.html
@@ -917,14 +917,16 @@ var formation = new Formation(teamsCount,5);
-
diff --git a/script-skill-parser.js b/script-skill-parser.js
index f0280c57..37b7fb25 100644
--- a/script-skill-parser.js
+++ b/script-skill-parser.js
@@ -111,7 +111,7 @@ const SkillKinds = {
NoSkyfall: "no-skyfall",
}
-function parser(skillId)
+function skillParser(skillId)
{
const skill = Skills[skillId];
if (!skill) return [];
@@ -119,7 +119,7 @@ function parser(skillId)
return [{ kind: SkillKinds.Unknown }];
}
//此处用apply将这个parser传递到后面解析函数的this里,用于递归解析
- const result = parsers[skill.type].apply({ parser }, skill.params);
+ const result = parsers[skill.type].apply({ parser: skillParser }, skill.params);
const skills = (Array.isArray(result) ? result : [result])
.filter(s => Boolean(s))
.map(s => ({ id: skillId, type: skill.type, params: skill.params, ...s }));
@@ -167,7 +167,7 @@ const c = {
return { hp: { min: min / 100, max: max / 100 } };
},
exact: function (type, value, attrs) {
- if (attrs === void 0) { attrs = models_1.Attributes.all(); }
+ if (attrs === void 0) { attrs = Attributes.all(); }
return { exact: { type: type, value: value, attrs: attrs } };
},
compo: function (type, ids) {
@@ -215,24 +215,25 @@ const p = {
};
},
scaleAttrs: function (attrs, min, max, baseMul, bonusMul) {
- return __assign({ kind: SkillPowerUpKind.ScaleAttributes, attrs: attrs }, scale(min, max, baseMul, bonusMul));
+ return { kind: SkillPowerUpKind.ScaleAttributes, attrs: attrs ,...scale(min, max, baseMul, bonusMul) };
},
scaleCombos: function (min, max, baseMul, bonusMul) {
- return __assign({ kind: SkillPowerUpKind.ScaleCombos }, scale(min, max, baseMul, bonusMul));
+ return { kind: SkillPowerUpKind.ScaleCombos ,...scale(min, max, baseMul, bonusMul) };
},
scaleMatchLength: function (attrs, min, max, baseMul, bonusMul) {
- return __assign({ kind: SkillPowerUpKind.ScaleMatchLength, attrs: attrs }, scale(min, max, baseMul, bonusMul));
+ return { kind: SkillPowerUpKind.ScaleMatchLength, attrs: attrs ,...scale(min, max, baseMul, bonusMul) };
},
scaleMatchAttrs: function (matches, min, max, baseMul, bonusMul) {
- return __assign({ kind: SkillPowerUpKind.ScaleMatchAttrs, matches: matches }, scale(min, max, baseMul, bonusMul));
+ return { kind: SkillPowerUpKind.ScaleMatchAttrs, matches: matches ,...scale(min, max, baseMul, bonusMul) };
},
scaleCross: function (crosses) {
- return { kind: SkillPowerUpKind.ScaleCross, crosses: crosses.map(function (cross) { return (__assign(__assign({}, cross), { mul: (cross.mul / 100) || 1 })); }) };
+ return { kind: SkillPowerUpKind.ScaleCross, crosses: crosses.map(cross => ({ ...cross, mul: (cross.mul / 100) || 1 })) };
},
scaleAwakenings: function (awakenings, value) {
return { kind: SkillPowerUpKind.ScaleAwakenings, awakenings: awakenings, value: value / 100 };
},
}
+
function activeTurns(turns, skill) {
return skill ? { kind: SkillKinds.ActiveTurns, turns: turns, skill: skill } : null;
}
@@ -253,7 +254,7 @@ function changeOrbs() {
}
function powerUp(attrs, types, value, condition, reduceDamageValue) {
if (value.kind === SkillPowerUpKind.Multiplier) {
- var _a = value, hp = _a.hp, atk = _a.atk, rcv = _a.rcv;
+ let hp = value.hp, atk = value.atk, rcv = value.rcv;
if (hp === 1 && atk === 1 && rcv === 1 && !reduceDamage)
return null;
}
@@ -611,4 +612,450 @@ const parsers = {
[188](value) {
return damageEnemy('single', 'fixed', v.constant(value));
},
-};
\ No newline at end of file
+};
+
+function renderSkill(skill)
+{
+ const fragment = document.createDocumentFragment();
+ const txt = str=>fragment.appendChild(document.createTextNode(str));
+ if (typeof localTranslating == "undefined") return fragment;
+ const tsp = localTranslating.skill_parse;
+ switch (skill.kind) {
+ case SkillKinds.Unknown: {
+ txt(tsp.Unknown);
+ }
+ /*
+ case SkillKinds.ActiveTurns: {
+ const { turns, skill: actionSkill } = skill as Skill.ActiveTurns;
+ return
{renderSkill(skillactionSkill)} × {turns} turns;
+ }
+ case SkillKinds.RandomSkills: {
+ const { skills } = skill as Skill.RandomSkills;
+ return (
+ <>
+
random skills:
+
+ >
+ );
+ }
+
+ case SkillKinds.Delay: {
+ return (
+
+
+
+ );
+ }
+ case SkillKinds.MassAttack: {
+ return (
+
+
+
+ );
+ }
+ case SkillKinds.LeaderChange: {
+ return (
+
+
+
+ );
+ }
+ case SkillKinds.NoSkyfall: {
+ return (
+
+
+
+ );
+ }
+ case SkillKinds.Heal: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+ {renderValue(value)}
+
+ );
+ }
+ case SkillKinds.DefenseBreak: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+ {renderValue(value)}
+
+ );
+ }
+ case SkillKinds.Poison: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+ {renderValue(value)}
+
+ );
+ }
+ case SkillKinds.TimeExtend: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+ {renderValue(value, 'seconds')}
+
+ );
+ }
+ case SkillKinds.FollowAttack: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+ {renderValue(value)}
+
+ );
+ }
+ case SkillKinds.AutoHeal: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+ {renderValue(value)}
+
+ );
+ }
+ case SkillKinds.CTW: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+
+
+
+ {renderValue(value, 'seconds')}
+
+ );
+ }
+ case SkillKinds.Gravity: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+ {renderValue(value)}
+
+ );
+ }
+ case SkillKinds.Resolve: {
+ const { min, max } = skill as Skill.Resolve;
+ return (
+
+
+ {renderValue(min)} ⇔ {renderValue(max)}
+
+ );
+ }
+ case SkillKinds.BoardChange: {
+ const { attrs } = skill as Skill.BoardChange;
+ return (
+
+
+
+
+
+ {renderOrbs(attrs)}
+
+ );
+ }
+ case SkillKinds.SkillBoost: {
+ const { value } = skill as Skill.WithValue
;
+ return (
+
+
+ {value} turns
+
+ );
+ }
+ case SkillKinds.AddCombo: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+
+ );
+ }
+ case SkillKinds.FixedTime: {
+ const { value } = skill as Skill.WithValue;
+ return (
+
+
+
+
+
+ {value} seconds
+
+ );
+ }
+ case SkillKinds.MinMatchLength: {
+ const { value } = skill as Skill.WithValue;
+ return minimum match length {value};
+ }
+ case SkillKinds.DropRefresh: {
+ return drop refresh;
+ }
+ case SkillKinds.Drum: {
+ return drum sound;
+ }
+ case SkillKinds.Board7x6: {
+ return 7x6 board;
+ }
+
+ case SkillKinds.DamageEnemy: {
+ const { attr, target, selfHP, damage } = skill as Skill.DamageEnemy;
+ return (
+
+ {!!selfHP && <>HP = {renderValue(selfHP)} ⇒>}
+
+
+
+ {target === 'all' && }
+ {target === 'single' && <>single enemy >}
+ {typeof target === 'number' && <>{renderAttrs(target)} enemies >}
+
+ ⇒ {renderValue(damage)}
+ {attr === 'fixed' && }
+ {typeof attr === 'number' && renderAttrs(attr)}
+
+
+ );
+ }
+ case SkillKinds.Vampire: {
+ const { attr, damage, heal } = skill as Skill.Vampire;
+ return (
+
+
+ single enemy ⇒ {renderValue(damage)}
+ {typeof attr === 'number' && renderAttrs(attr)}
+ ⇒
+
+ {renderValue(heal)} damage
+
+ );
+ }
+ case SkillKinds.CounterAttack: {
+ const { attr, prob, value } = skill as Skill.CounterAttack;
+ return (
+
+
+ {renderValue(prob)} ⇒ {renderValue(value)} damage
+ {typeof attr === 'number' && renderAttrs(attr)}
+
+ );
+ }
+ case SkillKinds.ChangeOrbs: {
+ const { changes } = skill as Skill.ChangeOrbs;
+ return (
+
+
+
+
+
+
+ {changes.map((change, i) => {
+ switch (change.kind) {
+ case 'from':
+ return (
+
+ {renderOrbs(change.from)} ⇒ {renderOrbs(change.to)}
+
+ );
+ case 'gen':
+ return (
+
+ {renderOrbs(change.exclude).map((orb, j) => (
+
+ {orb}
+
+
+ ))} ⇒ {renderOrbs(change.to)} × {change.count}
+
+ );
+ case 'fixed':
+ return (change.positions.length > 0 &&
+
+ {change.type === 'col' ? 'column' : 'row'}
+ {change.positions.map(p => p + 1).join(', ')}
+ ⇒ {renderOrbs(change.to)}
+
+ );
+ }
+ })}
+
+
+ );
+ }
+ case SkillKinds.Unbind: {
+ const { normal, awakenings } = skill as Skill.Unbind;
+ return (
+
+ {!!normal &&
+
+ {normal} turns
+ }
+ {!!awakenings &&
+
+
+
+
+ {awakenings} turns
+ }
+
+ );
+ }
+ case SkillKinds.OrbDropIncrease: {
+ const { attrs, value } = skill as Skill.OrbDropIncrease;
+ let attrElems: React.ReactNode[];
+ if (attrs === 'enhanced')
+ attrElems = [];
+ else
+ attrElems = renderOrbs(attrs);
+
+ attrElems = attrElems.map((elem, i) => (
+
+ {elem}
+
+
+ ));
+
+ return (
+
+ {attrElems}
+ {renderValue(value)}
+
+ );
+ }
+ case SkillKinds.VoidEnemyBuff: {
+ const { buffs } = skill as Skill.VoidEnemyBuff;
+ return (
+ {
+ buffs.map(buff => {
+ switch (buff) {
+ case 'attr-absorb': return (
+
+
+
+
+
+ );
+ case 'damage-absorb': return (
+
+
+
+
+ );
+ }
+ })
+ }
+ );
+ }
+ case SkillKinds.ChangeAttribute: {
+ const { attr, target } = skill as Skill.ChangeAttribute;
+
+ return (
+
+ {target === 'self' && 'Self'}
+ {target === 'opponent' && 'enemy'}
+ ⇒ {renderAttrs(attr)}
+
+ );
+ }
+ case SkillKinds.SetOrbState: {
+ const { orbs, state } = skill as Skill.SetOrbState;
+ let orbElems: React.ReactNode[];
+ if (!orbs) {
+ orbElems = [];
+ } else {
+ orbElems = renderOrbs(orbs);
+ }
+
+ return (
+
+ {(state === 'enhanced' || state === 'locked') && orbElems}
+ {state === 'unlocked' && orbElems.map((elem, i) => (
+
+ {elem}
+
+
+ ))}
+ ⇒
+ {state === 'enhanced' && orbElems.map((elem, i) => (
+
+ {elem}
+
+
+ ))}
+ {state === 'locked' && orbElems.map((elem, i) => (
+
+ {elem}
+
+
+ ))}
+ {state === 'unlocked' && orbElems}
+
+ );
+ }
+ case SkillKinds.RateMultiply: {
+ const { rate, value } = skill as Skill.RateMultiply;
+
+ return (
+
+ {rate === 'drop' && 'drop rate'}
+ {rate === 'coin' && 'coins'}
+ {rate === 'exp' && 'EXP'}
+ ×
+ {renderValue(value)}
+
+ );
+ }
+
+ case SkillKinds.ReduceDamage: {
+ const { attrs, percent, condition } = skill as Skill.ReduceDamage;
+
+ return (
+
+ {!!condition && <>{renderCondition(condition)} ⇒ >}
+
+ {(Array.isArray(attrs) && !isEqual(attrs, Attributes.all())) && renderAttrs(attrs)}
+ {renderValue(percent)}
+
+ );
+ }
+ case SkillKinds.PowerUp: {
+ const { attrs, types, condition, value, reduceDamage } = skill as Skill.PowerUp;
+ const targets: React.ReactNode[] = [];
+ if (attrs && !isEqual(attrs, Attributes.all())) targets.push(...renderAttrs(attrs || []));
+ if (types) targets.push(...renderTypes(types || []));
+
+ return (
+
+ {condition && <>{renderCondition(condition)} ⇒ >}
+ {targets.length > 0 && <>{targets}>}
+ {!!value && renderPowerUp(value)}
+ {!!reduceDamage && <>
+
+ {renderValue(reduceDamage)}
+ >}
+
+ );
+ }
+ */
+ default: {
+ console.log(skill, skill.kind);
+ txt(skill.kind);
+ }
+ }
+ return fragment;
+ };
\ No newline at end of file
diff --git a/script.js b/script.js
index 18d87f3b..75caaece 100644
--- a/script.js
+++ b/script.js
@@ -2511,8 +2511,8 @@ function editBoxChangeMonId(id) {
if (card.id == 0) {
id = 0;
}
- const skill = Skills[card.activeSkillId];
- const leaderSkill = Skills[card.leaderSkillId];
+ //const skill = Skills[card.activeSkillId];
+ //const leaderSkill = Skills[card.leaderSkillId];
let fragment = null;
@@ -2708,21 +2708,28 @@ function editBoxChangeMonId(id) {
const skillLevel = skillBox.querySelector(".m-skill-level");
//const skillLevel_1 = skillBox.querySelector(".m-skill-lv-1");
const skillLevel_Max = skillBox.querySelector(".m-skill-lv-max");
- const skillDetail = skillBox.querySelector(".skill-datail");
+ const skillDetailParsed = skillBox.querySelector(".skill-datail-parsed");
+ const skillDetailOriginal = skillBox.querySelector(".skill-datail-original");
+ const activeskill = Skills[card.activeSkillId];
+ const leaderSkill = Skills[card.leaderSkillId];
fragment = document.createDocumentFragment(); //创建节点用的临时空间
fragment.appendChild(skillBox);
- skillTitle.innerHTML = descriptionToHTML(skill.name);
- skillTitle.setAttribute("data-skillid", skill.id);
- skillDetail.innerHTML = "";
- skillDetail.appendChild(parseSkillDescription(skill));
- const t_maxLevel = card.overlay || card.types.includes(15) ? 1 : skill.maxLevel; //遇到不能升技的,最大等级强制为1
+ skillTitle.innerHTML = descriptionToHTML(activeskill.name);
+ skillTitle.setAttribute("data-skillid", activeskill.id);
+ skillDetailOriginal.innerHTML = "";
+ skillDetailOriginal.appendChild(parseSkillDescription(activeskill));
+ skillDetailParsed.innerHTML = "";
+ skillParser(card.activeSkillId)
+ .map(parsedSkill => renderSkill(parsedSkill))
+ .forEach(node => skillDetailParsed.appendChild(node));
+ const t_maxLevel = card.overlay || card.types.includes(15) ? 1 : activeskill.maxLevel; //遇到不能升技的,最大等级强制为1
skillLevel.max = t_maxLevel;
skillLevel.value = t_maxLevel;
skillLevel_Max.value = t_maxLevel;
- //skillLevel_Max.textContent = skill.maxLevel;
- skillCD.textContent = skill.initialCooldown - t_maxLevel + 1;
+ //skillLevel_Max.textContent = activeskill.maxLevel;
+ skillCD.textContent = activeskill.initialCooldown - t_maxLevel + 1;
rowSkill.appendChild(fragment);
@@ -2730,15 +2737,20 @@ function editBoxChangeMonId(id) {
const rowLederSkill = settingBox.querySelector(".row-mon-leader-skill");
const lskillBox = rowLederSkill.querySelector(".skill-box");
const lskillTitle = lskillBox.querySelector(".skill-name");
- const lskillDetail = lskillBox.querySelector(".skill-datail");
+ const lskillDetailParsed = lskillBox.querySelector(".skill-datail-parsed");
+ const lskillDetailOriginal = lskillBox.querySelector(".skill-datail-original");
fragment = document.createDocumentFragment(); //创建节点用的临时空间
fragment.appendChild(lskillBox);
lskillTitle.innerHTML = descriptionToHTML(leaderSkill.name);
lskillTitle.setAttribute("data-skillid", leaderSkill.id);
- lskillDetail.innerHTML = "";
- lskillDetail.appendChild(parseSkillDescription(leaderSkill));
+ lskillDetailOriginal.innerHTML = "";
+ lskillDetailOriginal.appendChild(parseSkillDescription(leaderSkill));
+ lskillDetailParsed.innerHTML = "";
+ skillParser(card.leaderSkillId)
+ .map(parsedSkill => renderSkill(parsedSkill))
+ .forEach(node => lskillDetailParsed.appendChild(node));
rowLederSkill.appendChild(fragment);
diff --git a/solo.html b/solo.html
index a93c626e..b7f2ba89 100644
--- a/solo.html
+++ b/solo.html
@@ -839,14 +839,16 @@ var formation = new Formation(teamsCount,6);
-
diff --git a/style.css b/style.css
index 8421d7b8..407dd4c0 100644
--- a/style.css
+++ b/style.css
@@ -2034,7 +2034,8 @@ body:not(.solo) .awoken-icon[data-awoken-icon="64"]::after
.skill-box .skill-cd{
margin-left: 10px;
}
-.skill-datail{
+.skill-datail-original,
+.skill-datail-parsed{
color: black;
padding: 0 8px 6px 8px;
line-height: 25px;
diff --git a/triple.html b/triple.html
index f8e1e171..29bc8bb1 100644
--- a/triple.html
+++ b/triple.html
@@ -1566,14 +1566,16 @@ var formation = new Formation(teamsCount,6);
-