基本完成所有技能的解析

This commit is contained in:
枫谷剑仙 2021-08-13 22:06:27 +08:00
parent 37cf5eee06
commit 68c41e5f57
4 changed files with 156 additions and 33 deletions

View File

@ -39,11 +39,12 @@
unbind_normal: tp`${'icon'}封锁状态减少${'turns'}`,
unbind_awakenings: tp`${'icon'}觉醒无效状态减少${'turns'}回合`,
unbind_matches: tp`${'icon'}无法消除宝珠状态减少${'turns'}回合`,
bind_skill: tp`${'icon'}自身无法使用技能`,
defense_break: tp`${'icon'}敌方的防御力减少${'value'}回合`,
poison: tp`${'icon'}使${'target'}全体中毒,每回合损失${'belong_to'} ${'value'}${'stats'}`,
time_extend: tp`${'icon'}宝珠移动时间 ${'value'}`,
follow_attack: tp`${'icon'}消除宝珠的回合,以${'belong_to'}${'value'}的伤害追打${'target'}(计算防御力)`,
follow_attack_fixed: tp`追加${'target'}${'icon'}固定伤害`,
follow_attack_fixed: tp`追加${'damage'}${'attr'}伤害`,
auto_heal_buff: tp`行动结束后${'icon'}回复${'value'}${'stats'}`,
auto_heal: tp`${'icon'}消除宝珠的回合,回复${'belong_to'}${'value'}${'stats'}`,
ctw: tp`${'icon'}${'value'}内时间停止,可以任意移动宝珠`,
@ -70,8 +71,8 @@
damage_void: tp`${'icon'}伤害无效`,
void_enemy_buff: tp`敌人的 ${'buff'} 无效化`,
change_attribute: tp`${'target'}变为${'attrs'}`,
set_orb_state_enhanced: tp`强化${'orbs'}(每颗宝珠效力增加${'value'}`,
set_orb_state_locked: tp`${'orbs'}锁定${'value'}`,
set_orb_state_enhanced: tp`${'icon'}强化${'orbs'}(每颗宝珠效力增加${'value'}`,
set_orb_state_locked: tp`${'orbs'}${'icon'}锁定${'value'}`,
set_orb_state_unlocked: tp`${'icon'}解除所有宝珠的锁定状态`,
set_orb_state_bound: tp`无法消除${'orbs'}`,
rate_multiply: tp`作为队长进入地下城时,${'rate'}变为${'value'}`,
@ -93,8 +94,8 @@
scale_match_attrs_bonus: tp`每多1串${'bonus'},最大${'max'}串时${'stats_max'}`,
scale_match_length: tp`${'in_once'}相连消除${'min'}${'orbs'}${'stats'}${'bonus'}`,
scale_match_length_bonus: tp`每多1个${'bonus'},最大${'max'}个时${'stats_max'}`,
scale_cross: tp`每以十字形式消除一组${'orbs'}${'stats'}`,
scale_cross_single: tp`以十字形式消除${'orbs'}${'stats'}`,
scale_cross: tp`每以十字形式消除5个${'orbs'}${'stats'}`,
scale_cross_single: tp`以十字形式消除5个${'orbs'}${'stats'}`,
scale_state_kind_count: tp`以队伍中${'awakenings'}${'attrs'}${'types'}的数量提升,每个${'stats'}`,
},
cond: {
@ -115,6 +116,7 @@
compo_type_evolution: tp`队员组成全为 ${'ids'} 进化时`,
L_shape: tp`以L字形式消除5个${'orbs'}`,
heal: tp`${'orbs'}回复${'heal'}`,
},
position: {
top: tp`上方第${'pos'}横行`,
@ -167,6 +169,9 @@
slight_pause: tp``, //顿号
range_hyphen: tp`~`, //范围连字符
in_once: tp`同时`,
evo_type_pixel: tp`像素进化`,
evo_type_reincarnation: tp`转生或超转生进化`,
evo_type_unknow: tp`未知进化`,
affix_attr: tp`${'cotent'}属性`, //词缀-属性
affix_orb: tp`${'cotent'}宝珠`, //词缀-宝珠
affix_type: tp`${'cotent'}类型`, //词缀-类型
@ -214,6 +219,7 @@
enhanced: tp`${'icon'}强化`,
locked: tp`${'icon'}锁定`,
nail: tp`${'icon'}钉子`,
variation: tp`${'icon'}变换珠(每${'time'}秒变换)`,
_5color: tp`${'icon'}5色`,
_6color: tp`${'_5color'}+${'orb_rcv'}`,
all: tp`所有`,

View File

@ -372,6 +372,7 @@ const SkillKinds = {
MassAttack: "mass-attack",
BoardChange: "board-change",
Unbind: "unbind",
BindSkill: "bind-skill",
RandomSkills: "random-skills",
ChangeAttribute: "change-attr",
SkillBoost: "skill-boost",
@ -381,6 +382,7 @@ const SkillKinds = {
CTW: "ctw",
Gravity: "gravity",
FollowAttack: "follow-attack",
FollowAttackFixed: "follow-attack-fixed",
AutoHeal: "auto-heal",
TimeExtend: "time-extend",
DropRefresh: "drop-refresh",
@ -522,7 +524,7 @@ const c = {
multiplayer: function () { return { multiplayer: true }; },
prob: function (percent) { return { prob: percent }; },
LShape: function (attrs) { return { LShape: { attrs: attrs } }; },
heal: function (heal) { return { heal: { heal: heal } }; },
heal: function (min) { return { heal: { min: min } }; },
}
const p = {
@ -574,7 +576,7 @@ const p = {
return { kind: SkillPowerUpKind.ScaleMatchAttrs, matches: matches ,...this.scale(min, max, baseMul, bonusMul) };
},
scaleCross: function (crosses) {
return { kind: SkillPowerUpKind.ScaleCross, crosses: crosses.map(cross => ({ ...cross, atk: (cross.atk / 100) ?? 1, rcv: (cross.rcv / 100) ?? 1 })) };
return { kind: SkillPowerUpKind.ScaleCross, crosses: crosses.map(cross => ({ ...cross, atk: ((cross.atk ?? 100) / 100), rcv: ((cross.rcv ?? 100) / 100)})) };
},
scaleStateKindCount: function (awakenings, attrs, types, value) {
return { kind: SkillPowerUpKind.ScaleStateKindCount, awakenings: awakenings, attrs: attrs, types: types, value: value };
@ -608,8 +610,8 @@ function fromTo(from, to) {
function changeOrbs() {
return { kind: SkillKinds.ChangeOrbs, changes: Array.from(arguments) };
}
function generateOrbs(orbs, exclude, count) {
return { kind: SkillKinds.GenerateOrbs, orbs: orbs, exclude: exclude, count: count };
function generateOrbs(orbs, exclude, count, time) {
return { kind: SkillKinds.GenerateOrbs, orbs: orbs, exclude: exclude, count: count, time: time};
}
function fixedOrbs() {
return { kind: SkillKinds.FixedOrbs, generates: Array.from(arguments) };
@ -640,6 +642,7 @@ function resolve(min, prob) {
function unbind(normal, awakenings, matches) {
return { kind: SkillKinds.Unbind, normal: normal, awakenings: awakenings , matches: matches};
}
function bindSkill() { return { kind: SkillKinds.BindSkill}; }
function boardChange(attrs) {
return { kind: SkillKinds.BoardChange, attrs: attrs };
}
@ -663,6 +666,7 @@ function defBreak(value) { return { kind: SkillKinds.DefenseBreak, value: value
function poison(value) { return { kind: SkillKinds.Poison, value: value }; }
function CTW(value) { return { kind: SkillKinds.CTW, value: value }; }
function followAttack(value) { return { kind: SkillKinds.FollowAttack, value: value }; }
function followAttackFixed(value) { return { kind: SkillKinds.FollowAttackFixed, value: v.constant(value) }; }
function autoHeal(value) { return { kind: SkillKinds.AutoHeal, value: value }; }
function timeExtend(value) { return { kind: SkillKinds.TimeExtend, value: value }; }
function delay() { return { kind: SkillKinds.Delay }; }
@ -981,9 +985,9 @@ const parsers = {
[175](series1, series2, series3, hp, atk, rcv) { return powerUp(null, null, p.mul({ hp, atk, rcv }), c.compo('series', [series1, series2, series3].filter(Boolean))); },
[176](row1, row2, row3, row4, row5, attrs) {
return fixedOrbs(
{ orbs: [attrs ?? 0], type: 'shape', positions: [row1, row2, row3, row4, row5].map(row=>flags(row)) }
{ orbs: [attrs ?? 0], type: 'shape', positions: [row1, row2, row3, row4, row5].map(row=>flags(row)) }
);
},
},
[177](attrs, types, hp, atk, rcv, remains, mul) {
return [
noSkyfall(),
@ -1023,8 +1027,8 @@ const parsers = {
[186](attrs, types, hp, atk, rcv) {
return [
board7x6(),
powerUp(flags(attrs), flags(types), p.mul({ hp, atk, rcv })),
];
(hp || atk ||rcv) && powerUp(flags(attrs), flags(types), p.mul({ hp, atk, rcv })) || null,
].filter(Boolean);
},
[188](value) {
@ -1060,19 +1064,61 @@ const parsers = {
return voidPoison();
},
[198](heal, atk, percent, awokenBind) {
return powerUp(null, null, p.mul([atk, 0]), c.heal(heal), v.percent(percent), [unbind(0, awokenBind ?? 0)]);
return powerUp(null, null, p.mul([atk, 0]), c.heal(heal), percent && v.percent(percent), awokenBind && [unbind(0, awokenBind ?? 0)]);
},
[199](attrs, min, damage) {
return powerUp(null, null, p.scaleAttrs(flags(attrs), min, min, [0, 0], [0, 0]), null, null, [followAttackFixed(damage)]);
},
[200](attrs, len, damage) {
return powerUp(null, null, p.scaleMatchLength(flags(attrs), len, len, [0, 0], [0, 0]), null, null, [followAttackFixed(damage)]);
},
[201](attrs1, attrs2, attrs3, attrs4, min, damage) {
const attrs = [attrs1, attrs2, attrs3, attrs4].filter(Boolean);
return powerUp(null, null, p.scaleMatchAttrs(attrs.map(flags), min, attrs.length, [0, 0], [0, 0]), null, null, [followAttackFixed(damage)]);
},
[202](id) {
return henshin(id);
},
[203](evotype, hp, atk, rcv) { return powerUp(null, null, p.mul({ hp, atk, rcv }), c.compo('evolution', [evotype])); },
[205](attrs, turns) { return activeTurns(turns, orbDropIncrease(null, flags(attrs), 'locked')); },
[205](attrs, turns) { return activeTurns(turns, orbDropIncrease(null, flags(attrs == -1 ? 1023: attrs), 'locked')); },
[206](attrs1, attrs2, attrs3, attrs4, attrs5, min, combo) {
const attrs = [attrs1, attrs2, attrs3, attrs4, attrs5].filter(Boolean);
return powerUp(null, null, p.scaleMatchAttrs(attrs.map(flags), min, attrs.length, [0, 0], [0, 0]), null, null, [addCombo(combo)]);
},
[207](turns, time, row1, row2, row3, row4, row5, count) {
return activeTurns(turns, count ?
generateOrbs( ['variation'], null, count, time/100):
fixedOrbs( { orbs: ['variation'], time: time/100, type: 'shape', positions: [row1, row2, row3, row4, row5].map(row=>flags(row)) })
);
},
[208](count1, to1, exclude1, count2, to2, exclude2) {
return [
generateOrbs(flags(to1), flags(exclude1), count1),
generateOrbs(flags(to2), flags(exclude2), count2),
];
},
[209](combo) {
return powerUp(null, null, p.scaleCross([{ single: true, attr: Attributes.Heart, atk: 100, rcv: 100}]), null, null, [addCombo(combo)]);
},
[210](attrs, _, combo) {
return powerUp(null, null, p.scaleCross([{ single: false, attr: flags(attrs), atk: 100, rcv: 100}]), null, null, [addCombo(combo)]);
},
[214](turns) { return activeTurns(turns, bindSkill()); },
[215](turns, attrs) { return activeTurns(turns, setOrbState(flags(attrs), 'bound')); },
[218](turns) { return skillBoost(v.constant(-turns)); },
[219](attrs, len, combo) {
return powerUp(null, null, p.scaleMatchLength(flags(attrs), len, len, [0, 0], [0, 0]), null, null, [addCombo(combo)]);
},
[220](attrs, combo) {
return powerUp(null, null, p.mul([0,0]), c.LShape(flags(attrs)), null, [addCombo(combo)]);
},
[223](combo, damage) {
return powerUp(null, null, p.scaleCombos(combo, combo, [100, 100], [0, 0]), null, null, [followAttackFixed(damage)]);
},
[224](turns, attr) { return activeTurns(turns, changeAttr('opponent', attr)); },
[226](turns, percent) { return activeTurns(turns, orbDropIncrease(v.percent(percent), [], 'nail')); },
@ -1332,6 +1378,15 @@ function renderSkill(skill, option = {})
frg.ap(tsp.skill.follow_attack(dict));
break;
}
case SkillKinds.FollowAttackFixed: { //队长技固伤追打
let damage = skill.value;
let dict = {
damage: renderValue(damage, {unit: tsp.unit.point}),
attr: renderAttrs('fixed'),
};
frg.ap(tsp.skill.follow_attack_fixed(dict));
break;
}
case SkillKinds.AutoHeal: { //队长技自动回血
let dict = {
icon: createIcon(skill.kind),
@ -1394,6 +1449,13 @@ function renderSkill(skill, option = {})
frg.ap(effects.nodeJoin(tsp.word.comma()));
break;
}
case SkillKinds.BindSkill: {
dict = {
icon: createIcon(skill.kind)
};
frg.ap(tsp.skill.bind_skill(dict));
break;
}
case SkillKinds.BoardChange: { //洗版
const attrs = skill.attrs;
dict = {
@ -1503,10 +1565,10 @@ function renderSkill(skill, option = {})
break;
}
case SkillKinds.GenerateOrbs: { //产生珠子
let orbs = skill.orbs, exclude = skill.exclude, count = skill.count;
let orbs = skill.orbs, exclude = skill.exclude, count = skill.count, time = skill.time;
dict = {
exclude: exclude.length ? tsp.word.affix_exclude({cotent: renderOrbs(exclude)}) : void 0,
orbs: renderOrbs(orbs),
exclude: exclude?.length ? tsp.word.affix_exclude({cotent: renderOrbs(exclude)}) : void 0,
orbs: renderOrbs(orbs, {time}),
value: count,
};
let board = new Board();
@ -1519,7 +1581,6 @@ function renderSkill(skill, option = {})
let generates = skill.generates;
let slight_pause = tsp.word.slight_pause().textContent;
let subDocument = [];
//let board = new Array(5).fill(null).map(i=>new Array(6).fill(null));
let board = new Board();
function posSplit(pos, max)
{
@ -1527,9 +1588,9 @@ function renderSkill(skill, option = {})
}
for (const generate of generates)
{
let orb = generate.orbs?.[0];
let orb = generate.orbs?.[0], time = generate.time;
dict = {
orbs: renderOrbs(orb),
orbs: renderOrbs(orb, {time}),
};
if (generate.type == 'shape')
{
@ -1600,6 +1661,7 @@ function renderSkill(skill, option = {})
let orbs = skill.orbs, state = skill.state, arg = skill.arg;
dict = {
orbs: renderOrbs(orbs, {className: state, affix: true}),
icon: createIcon('orb-' + state),
};
switch (state)
{
@ -1615,7 +1677,6 @@ function renderSkill(skill, option = {})
break;
}
case "unlocked":{
dict.icon = createIcon('orb-unlocked'),
frg.ap(tsp.skill.set_orb_state_unlocked(dict));
break;
}
@ -1681,7 +1742,7 @@ function renderSkill(skill, option = {})
}));
}
if (additional?.length) {
for (let subSkill of additional)
for (let subSkill of additional.filter(Boolean))
{
subDocument.push(renderSkill(subSkill, option));
}
@ -1788,13 +1849,20 @@ function renderOrbs(attrs, option = {}) {
icon.className = "orb";
if (option.className) icon.className += " " + option.className;
icon.setAttribute("data-orb-icon",attr);
return tsp.orbs[attr]({icon: icon});
let dict = {
icon: icon,
}
if (attr == 'variation') dict.time = option.time;
if (tsp.orbs[attr])
return tsp.orbs[attr](dict);
else
console.error(attr,'未知宝珠')
})
.nodeJoin(tsp.word.slight_pause());
}
if (option.affix)
contentFrg = tsp.word.affix_orb({cotent: contentFrg});
if (option.any)
if (option.any && attrs.length >= 2)
contentFrg = tsp.orbs.any({cotent: contentFrg});
frg.ap(contentFrg);
return frg;
@ -1892,23 +1960,53 @@ function renderCondition(cond) {
lnk.className ="detail-search monster-collabId";
lnk.setAttribute("data-collabId",cid);
lnk.onclick = searchCollab;
lnk.textContent = cid;
lnk.textContent = (cid == 10001 ? Cards[5435] : Cards.find(card=>card.collabId == cid))?.altName?.[0] ?? `No.${cid}`;
return lnk;
}).nodeJoin(tsp.word.slight_pause());
frg.ap(tsp.cond.compo_type_series(dict));
break;
}
case 'evolution':{
dict.ids = cond.compo.ids.join();
dict.ids = cond.compo.ids.map(eid=>{
const lnk = document.createElement("a");
lnk.className ="detail-search";
switch (eid)
{
case 0:{ //像素进化
lnk.appendChild(tsp.word.evo_type_pixel());
lnk.onclick = function(){
showSearch(Cards.filter(card=>card.evoMaterials.includes(3826)));
};
break;
}
case 2:{ //转生或超转生
lnk.appendChild(tsp.word.evo_type_reincarnation());
lnk.onclick = function(){
showSearch(Cards.filter(card=>isReincarnated(card)));
};
break;
}
default:{ //转生或超转生
return tsp.word.evo_type_unknow();
}
}
return lnk;
}).nodeJoin(tsp.word.slight_pause());
frg.ap(tsp.cond.compo_type_evolution(dict));
break;
}
}
} else if (cond.LShape) {
let dict = {
orbs: renderOrbs(cond.LShape.attrs, {affix: true}),
orbs: renderOrbs(cond.LShape.attrs, {affix: true, any: true}),
};
frg.ap(tsp.cond.L_shape(dict));
} else if (cond.heal) {
let dict = {
orbs: renderOrbs(5, {affix: true}),
heal: renderValue(v.constant(cond.heal.min), {unit: tsp.unit.point}),
};
frg.ap(tsp.cond.heal(dict));
} else {
frg.ap(tsp.cond.unknown());
}

View File

@ -1127,4 +1127,8 @@ icon.type
.orb[data-orb-icon='9']
{
background-position-y:calc(-36px * 9);
}
.orb[data-orb-icon='variation']
{
background-position-y:calc(-36px * 10);
}

View File

@ -3188,12 +3188,12 @@ table .orb-icon
/*margin: -4px;*/
position: relative;
}
.skill-datail-parsed .detail-search.monster-collabId
.skill-datail-parsed a.detail-search
{
cursor: pointer;
color: brown;
}
.skill-datail-parsed .detail-search.monster-collabId:hover
.skill-datail-parsed a.detail-search:hover
{
background: rgba(150,110,10,0.5);
border-radius: 5px;
@ -3308,7 +3308,8 @@ table .orb-icon
.icon-skill[data-icon-type="attr-absorb"]::after,
.icon-skill[data-icon-type="combo-absorb"]::after,
.icon-skill[data-icon-type="damage-absorb"]::after,
.icon-skill[data-icon-type="damage-void"]::after
.icon-skill[data-icon-type="damage-void"]::after,
.icon-skill[data-icon-type="bind-skill"]::after
{
content: "";
background-position-y:calc(-36px * 3);
@ -3415,7 +3416,8 @@ table .orb-icon
}
.icon-skill[data-icon-type="skill-boost"],
.icon-skill.boost-incr::after,
.icon-skill.boost-decr::after
.icon-skill.boost-decr::after,
.icon-skill[data-icon-type="bind-skill"]
{
background-position-y:calc(-36px * 19);
}
@ -3501,4 +3503,17 @@ table .orb-icon
.icon-skill[data-icon-type="reduce-damage"]
{
background-position-y:calc(-36px * 32);
}
.icon-skill[data-icon-type="orb-locked"]
{
background-position-y:calc(-36px * 11);
background-position-x:calc(-36px * 2);
}
.icon-skill[data-icon-type="orb-enhanced"]
{
background-position-y:calc(-36px * 33);
}
.icon-skill[data-icon-type="orb-nail"]
{
background-position-y:calc(-36px * 35);
}