重新写部分类
This commit is contained in:
parent
7ef34fa486
commit
8500889341
|
@ -1,17 +1,27 @@
|
|||
const unsupportFeatures = (()=>{
|
||||
function runCodeWithFunction(obj) {
|
||||
return Function('"use strict";return (' + obj + ")")();
|
||||
return Function(`"use strict"; return (${obj})`)();
|
||||
}
|
||||
|
||||
function supportsPseudoClass(clazz) {
|
||||
const style = document.createElement('style');
|
||||
style.innerHTML = clazz + '{}';
|
||||
document.head.appendChild(style); // required, or style.sheet === null
|
||||
const result = style.sheet.cssRules.length === 1;
|
||||
style.remove(); // document.head.removeChild(style);
|
||||
return result;
|
||||
}
|
||||
|
||||
const features = [
|
||||
{name: "Optional chaining (?.) / 可选链操作符(?.)", version:{firefox:74,chrome:80,safari:13.4}, url: "https://caniuse.com/mdn-javascript_operators_optional_chaining", test: ()=>Boolean(runCodeWithFunction("undefined?.undefined || true"))},
|
||||
{name: "Nullish coalescing operator (??) / 空值合并操作符(??)", version:{firefox:72,chrome:80,safari:13.4}, url: "https://caniuse.com/mdn-javascript_operators_nullish_coalescing", test: ()=>Boolean(runCodeWithFunction("undefined ?? true"))},
|
||||
{name: "BigInt value (1n) / BigInt 数据类型(1n)", version:{firefox:79,chrome:67,safari:14}, url: "https://caniuse.com/bigint", test: ()=>Boolean(runCodeWithFunction("1n"))},
|
||||
// {name: "CSS selector: :is() / CSS选择器: :is()", version:{firefox:78,chrome:88,safari:14}, url: "https://caniuse.com/css-matches-pseudo", test: ()=>Boolean(eval("document.querySelector(':is()') || true"))},
|
||||
// {name: "CSS selector: :where() / CSS选择器: :where()", version:{firefox:78,chrome:88,safari:14}, url: "https://caniuse.com/mdn-css_selectors_where", test: ()=>Boolean(eval("document.querySelector(':where()') || true"))},
|
||||
{name: "CSS selector: :not() / CSS选择器: :not()", version:{firefox:84,chrome:88,safari:9}, url: "https://caniuse.com/css-not-sel-list", test: ()=>Boolean(runCodeWithFunction("document.querySelector(':not(html)') || true"))},
|
||||
// {name: "Private class fields (#name) / 类私有域(#name)", version:{firefox:90,chrome:74,safari:14.5}, url: "https://caniuse.com/mdn-javascript_classes_private_class_fields", test: ()=>Boolean(eval("class test {#v = 0;}; true;"))},
|
||||
{name: "BigInt value (1n) / BigInt 数据类型(1n)", version:{firefox:68,chrome:67,safari:14}, url: "https://caniuse.com/bigint", test: ()=>Boolean(runCodeWithFunction("1n"))},
|
||||
// {name: "CSS selector: :is() / CSS选择器: :is()", version:{firefox:78,chrome:88,safari:14}, url: "https://caniuse.com/css-matches-pseudo", test: ()=>supportsPseudoClass(":is()")},
|
||||
{name: "CSS selector: :where() / CSS选择器: :where()", version:{firefox:78,chrome:88,safari:14}, url: "https://caniuse.com/mdn-css_selectors_where", test: ()=>supportsPseudoClass(":where()")},
|
||||
{name: "CSS selector: :not() / CSS选择器: :not()", version:{firefox:84,chrome:88,safari:9}, url: "https://caniuse.com/css-not-sel-list", test: ()=>supportsPseudoClass(":not(html)")},
|
||||
//{name: "CSS selector: :has() / CSS选择器: :has()", version:{firefox:121,chrome:105,safari:15.4}, url: "https://caniuse.com/css-has", test: ()=>supportsPseudoClass(":has(html)")},
|
||||
{name: "Private class fields (#name) / 类私有域(#name)", version:{firefox:90,chrome:74,safari:14.5}, url: "https://caniuse.com/mdn-javascript_classes_private_class_fields", test: ()=>Boolean(runCodeWithFunction("class test {#v = 0;}, true"))},
|
||||
// {name: "Dialog element / Dialog 元素", version:{firefox:98,chrome:37,safari:15.4}, url: "https://caniuse.com/dialog", test: ()=>Boolean(eval("HTMLDialogElement"))},
|
||||
// {name: "Class static initialization blocks / 静态初始化块", version:{firefox:93,chrome:94,safari:16.4}, url: "https://caniuse.com/mdn-javascript_classes_static_initialization_blocks", test: ()=>supportsPseudoClass(":not(html)")},
|
||||
]
|
||||
return features.filter(feature=>{
|
||||
try {
|
||||
|
@ -46,22 +56,22 @@ if (unsupportFeatures.length) {
|
|||
let alertStr;
|
||||
if (/^zh-(?:han(?:s|t)-)?/.test(navigator.language)) {
|
||||
alertStr =
|
||||
`🙁浏览器内核版本太老<br>
|
||||
`<div>🙁浏览器内核版本太老<br>
|
||||
您的浏览器版本为: ${browserVersion}<br>
|
||||
您的浏览器内核不支持本程序使用的以下技术
|
||||
<ol>
|
||||
${unsupportFeatures.map(feature=>`<li><a href="${feature.url}">${feature.name}</a></li>`).join('')}
|
||||
</ol>
|
||||
请更新您的浏览器内核到 Firefox(火狐) ≥ ${needBrowserVersion.firefox} 或 Chrome(谷歌) ≥ ${needBrowserVersion.chrome} 或 Safari ≥ ${needBrowserVersion.safari}。`;
|
||||
请更新您的浏览器内核到 Firefox(火狐) ≥ ${needBrowserVersion.firefox} 或 Chrome(谷歌) ≥ ${needBrowserVersion.chrome} 或 Safari ≥ ${needBrowserVersion.safari}。</div>`;
|
||||
} else {
|
||||
alertStr =
|
||||
`🙁Browser kernel is too old<br>
|
||||
`<div>🙁Browser kernel is too old<br>
|
||||
Your browser is: ${browserVersion}<br>
|
||||
Your browser kernel does not support the following technologies used by this program:
|
||||
<ol>
|
||||
${unsupportFeatures.map(feature=>`<li><a href="${feature.url}">${feature.name}</a></li>`).join('')}
|
||||
</ol>
|
||||
Please update your browser core to Firefox ≥ ${needBrowserVersion.firefox} or Chrome ≥ ${needBrowserVersion.chrome} or Safari ≥ ${needBrowserVersion.safari}`;
|
||||
Please update your browser core to Firefox ≥ ${needBrowserVersion.firefox} or Chrome ≥ ${needBrowserVersion.chrome} or Safari ≥ ${needBrowserVersion.safari}</div>`;
|
||||
}
|
||||
|
||||
//alert(alertStr);
|
||||
|
@ -92,6 +102,12 @@ if (/\b(?:MicroMessenger|WeChat|Weixin|QQ|AliApp)\b/.test(navigator.userAgent))
|
|||
const alertDiv = mask.appendChild(document.createElement("div"));
|
||||
alertDiv.className = "alert";
|
||||
alertDiv.innerHTML = `请勿使用内置浏览<br>点击菜单使用正常浏览器打开↗`;
|
||||
const removeMe = mask.appendChild(document.createElement("button"));
|
||||
removeMe.append("我知道了");
|
||||
removeMe.onclick = ()=>{
|
||||
mask.remove();
|
||||
delete mask;
|
||||
};
|
||||
|
||||
const event = window.addEventListener("load", ()=>{
|
||||
document.body.appendChild(mask);
|
||||
|
|
571
script.js
571
script.js
|
@ -115,38 +115,455 @@ DBOpenRequest.onupgradeneeded = function(event) {
|
|||
console.log("PADDF:数据库建立完毕");
|
||||
};
|
||||
};
|
||||
|
||||
/*class Member2
|
||||
{
|
||||
constructor(oldmember, isAssist)
|
||||
{
|
||||
//this.index = oldmember?.index ?? 0;
|
||||
this.id = oldmember?.id ?? 0;
|
||||
//this.exp = oldmember?.exp ?? 0;
|
||||
this.level = oldmember?.level ?? 1;
|
||||
this.plus = oldmember?.plus ?? {hp:0,atk:0,rcv:0};
|
||||
this.awoken = oldmember.awoken ?? 0;
|
||||
this.superAwoken = oldmember.superAwoken ?? null;
|
||||
this.latent = oldmember?.latent.concat() ?? [];
|
||||
this.skillLevel = oldmember.skillLevel ?? 0;
|
||||
this.assist = oldmember.assist ?? null;
|
||||
this.isAssist = Boolean(isAssist !== undefined ? isAssist : oldmember?.isAssist);
|
||||
}
|
||||
calculateAbility(solo,teamCount){
|
||||
const card = Cards[this.id];
|
||||
let bonus = null;
|
||||
if (!this.isAssist &&
|
||||
this.assist &&
|
||||
this.assist.id>0 &&
|
||||
Cards[this.assist.id].attrs[0] === card.attrs[0]
|
||||
){
|
||||
bonus = this.assist.calculateAbility(solo,teamCount);
|
||||
class Plus extends Array {
|
||||
constructor(hp = 0 , atk = 0, rcv = 0) {
|
||||
super(3);//建立 Array
|
||||
if (Array.isArray(hp) && hp.length >= 3 //传入数组的形式
|
||||
&& hp.every(n=>Number.isInteger(n))) {
|
||||
this[0] = hp[0];
|
||||
this[1] = hp[1];
|
||||
this[2] = hp[2];
|
||||
} else { //传入三个数字的形式
|
||||
if (!Number.isInteger(hp) || !Number.isInteger(atk) || !Number.isInteger(rcv)) throw new TypeError("传入的+值不是整数");
|
||||
this[0] = hp;
|
||||
this[1] = atk;
|
||||
this[2] = rcv;
|
||||
}
|
||||
}
|
||||
toJSON(){
|
||||
|
||||
get hp() {
|
||||
return this[0];
|
||||
}
|
||||
}*/
|
||||
set hp(num) {
|
||||
if (!Number.isInteger(num)) throw new TypeError("传入的+值不是整数");
|
||||
this[0] = num;
|
||||
}
|
||||
get atk() {
|
||||
return this[1];
|
||||
}
|
||||
set atk(num) {
|
||||
if (!Number.isInteger(num)) throw new TypeError("传入的+值不是整数");
|
||||
this[1] = num;
|
||||
}
|
||||
get rcv() {
|
||||
return this[2];
|
||||
}
|
||||
set rcv(num) {
|
||||
if (!Number.isInteger(num)) throw new TypeError("传入的+值不是整数");
|
||||
this[2] = num;
|
||||
}
|
||||
get is297() {
|
||||
return (this[0] + this[1] + this[2]) === 297;
|
||||
}
|
||||
}
|
||||
class LatentAwakening extends Array {
|
||||
blocks = 6;
|
||||
constructor(arg = []) {
|
||||
super();//建立 Array
|
||||
if (typeof arg === "bigint" ||
|
||||
typeof arg === "number" && Number.isInteger(arg) ||
|
||||
typeof arg === "string" && /^\d+$/.test(arg)
|
||||
){ //单个大数字模式
|
||||
let latentNumber = BigInt(arg);
|
||||
//console.log("原始数字",latentNumber.toString(2));
|
||||
const latentVersion = latentNumber & 0b111n; //记录版本,111是用几位来做记录,也就是最多7位
|
||||
latentNumber >>= 3n; //右移3位
|
||||
//console.log("读取潜觉记录位数",latentNumber.toString(2));
|
||||
const changeLatentBlocksNum = Boolean(latentNumber & 1n); //1时就是开孔了
|
||||
latentNumber >>= 1n; //右移1位
|
||||
//console.log("读取潜觉格子数是否改变",latentNumber.toString(2));
|
||||
if (changeLatentBlocksNum)
|
||||
{
|
||||
this.blocks = Number(latentNumber & 0b1111n);
|
||||
latentNumber >>= 4n;
|
||||
//console.log("读取潜觉格子数",latentNumber.toString(2));
|
||||
}
|
||||
const rightNumn = latentVersion > 6n ? 7n : 5n; //右移的距离
|
||||
const getbnum = (1n << rightNumn) - 1n; //逻辑与的数字 //latentVersion > 6 ? 0b1111111n : 0b11111n;
|
||||
while (latentNumber > 0n)
|
||||
{
|
||||
const latentId = Number(latentNumber & getbnum);
|
||||
this.push(latentId);
|
||||
//判断是几格,然后直接右移几次
|
||||
const useHole = latentUseHole(latentId);
|
||||
latentNumber >>= rightNumn * BigInt(useHole);
|
||||
}
|
||||
} else if (Array.isArray(arg)) {
|
||||
Object.assign(this, arg);
|
||||
}
|
||||
}
|
||||
toBigInt() {
|
||||
//直接使用目前的最新版本
|
||||
const leftNumn = 0b111n;
|
||||
//重复添加潜觉
|
||||
let latentNum = this.reduceRight((pre,latentId, idx)=>{
|
||||
const useHole = latentUseHole(latentId);
|
||||
const latentIdn = BigInt(latentId);
|
||||
for (let i=1; i <= useHole; i++) {
|
||||
pre <<= leftNumn;
|
||||
pre |= latentIdn;
|
||||
}
|
||||
return pre;
|
||||
}, 0n);
|
||||
|
||||
//添加使用的格子数
|
||||
latentNum <<= 4n;
|
||||
latentNum |= BigInt(this.blocks);
|
||||
|
||||
//添加是否已打开格子
|
||||
latentNum <<= 1n;
|
||||
latentNum |= this.blocks > 6 ? 1n : 0n;
|
||||
|
||||
//潜觉版本,直接来最新版本
|
||||
latentNum <<=3n;
|
||||
latentNum |= latentVersion;
|
||||
|
||||
return BigInt.asUintN(64, latentNum);;
|
||||
}
|
||||
}
|
||||
class Member2 {
|
||||
id = 0;
|
||||
level = 1;
|
||||
plus = new Plus();
|
||||
awakening = 0;
|
||||
superAwakening= 0;
|
||||
latentAwakening = new LatentAwakening();
|
||||
skillLevel = 0;
|
||||
assistMember = null;
|
||||
get hasAssist() {
|
||||
return assistMember instanceof Member2;
|
||||
}
|
||||
removeAssist() {
|
||||
this.assistMember = null;
|
||||
}
|
||||
constructor(oldMember = {}, assistMember = null)
|
||||
{
|
||||
if (assistMember instanceof Member2) {
|
||||
this.assistMember = assistMember;
|
||||
assistMember.removeAssist();
|
||||
}
|
||||
if (oldMember instanceof Member2) {
|
||||
Object.assign(this, oldMember);
|
||||
}
|
||||
}
|
||||
get card() {
|
||||
return Cards[this.id] ?? Cards[0];
|
||||
}
|
||||
}
|
||||
class Card {
|
||||
flags = 0;
|
||||
id = 0;
|
||||
name = null;
|
||||
attrs = [];
|
||||
types = [];
|
||||
isUltEvo = false;
|
||||
rarity = 0;
|
||||
cost = 0;
|
||||
maxLevel = 0;
|
||||
feedExp = 0;
|
||||
isEmpty = true;
|
||||
sellPrice = 0;
|
||||
hp = null;
|
||||
atk = null;
|
||||
rcv = null;
|
||||
exp = null;
|
||||
activeSkillId = 0;
|
||||
leaderSkillId = 0;
|
||||
enemy = null;
|
||||
evoBaseId = null;
|
||||
evoMaterials = [];
|
||||
unevoMaterials = [];
|
||||
awakenings = [];
|
||||
superAwakenings = [];
|
||||
evoRootId = 0;
|
||||
seriesId = 0;
|
||||
sellMP = 0;
|
||||
latentAwakeningId = 0;
|
||||
collabId = 0;
|
||||
altName = [];
|
||||
limitBreakIncr = 0;
|
||||
voiceId = 0;
|
||||
blockSkinOrBgmId = 0;
|
||||
specialAttribute = null;
|
||||
searchFlags = [];
|
||||
#leaderSkillTypes = null;
|
||||
gachaId = 0;
|
||||
|
||||
unk01 = null;
|
||||
unk02 = null;
|
||||
unk03 = null;
|
||||
unk04 = null;
|
||||
unk05 = null;
|
||||
unk06 = null;
|
||||
unk07 = null;
|
||||
unk08 = null;
|
||||
static fixId(id, reverse = false){
|
||||
if (id === 0xFFFF) return id;
|
||||
return reverse ? (id >= 9900 ? id + 100 : id) : (id >= 10000 ? id - 100 : id);
|
||||
}
|
||||
constructor(data){
|
||||
if (Array.isArray(data)) {
|
||||
this.fromOfficialData(data);
|
||||
} else {
|
||||
const classPrototype = Card.prototype;
|
||||
|
||||
for (let key in data) {
|
||||
const propertyDescriptor = Object.getOwnPropertyDescriptor(classPrototype, key);
|
||||
if (propertyDescriptor &&
|
||||
!propertyDescriptor.writable &&
|
||||
!propertyDescriptor.set)
|
||||
continue;
|
||||
this[key] = data[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
fromOfficialData(data) {
|
||||
const e = data.entries();
|
||||
function readCurve(entries) {
|
||||
return {
|
||||
min: entries.next().value[1],
|
||||
max: entries.next().value[1],
|
||||
scale: entries.next().value[1],
|
||||
};
|
||||
}
|
||||
this.id = Card.fixId(e.next().value[1]); //ID
|
||||
this.name = e.next().value[1]; //名字
|
||||
this.attrs.push(e.next().value[1]); //属性1
|
||||
this.attrs.push(e.next().value[1]); //属性2
|
||||
this.isUltEvo = e.next().value[1] !== 0; //是否究极进化
|
||||
this.types.push(e.next().value[1]); //类型1
|
||||
this.types.push(e.next().value[1]); //类型2
|
||||
this.rarity = e.next().value[1]; //星级
|
||||
this.cost = e.next().value[1]; //cost
|
||||
this.unk01 = e.next().value[1]; //未知01
|
||||
this.maxLevel = e.next().value[1]; //最大等级
|
||||
this.feedExp = e.next().value[1]; //1级喂食经验,需要除以4
|
||||
this.isEmpty = e.next().value[1] === 1; //空卡片?
|
||||
this.sellPrice = e.next().value[1]; //1级卖钱,需要除以10
|
||||
this.hp = readCurve(e); //HP增长
|
||||
this.atk = readCurve(e); //攻击增长
|
||||
this.rcv = readCurve(e); //回复增长
|
||||
this.exp = { min: 0, max: e.next().value[1], scale: e.next().value[1] }; //经验增长
|
||||
this.activeSkillId = e.next().value[1]; //主动技
|
||||
this.leaderSkillId = e.next().value[1]; //队长技
|
||||
this.enemy = { //作为怪物的数值
|
||||
countdown: e.next().value[1],
|
||||
hp: readCurve(e),
|
||||
atk: readCurve(e),
|
||||
def: readCurve(e),
|
||||
maxLevel: e.next().value[1],
|
||||
coin: e.next().value[1],
|
||||
exp: e.next().value[1],
|
||||
skills: []
|
||||
};
|
||||
this.evoBaseId = Card.fixId(e.next().value[1]); //进化基础ID
|
||||
this.evoMaterials.push(...([ //进化素材
|
||||
e.next().value[1],
|
||||
e.next().value[1],
|
||||
e.next().value[1],
|
||||
e.next().value[1],
|
||||
e.next().value[1]
|
||||
].map(n=>Card.fixId(n,false))));
|
||||
this.unevoMaterials.push(...([ //退化素材
|
||||
e.next().value[1],
|
||||
e.next().value[1],
|
||||
e.next().value[1],
|
||||
e.next().value[1],
|
||||
e.next().value[1]
|
||||
].map(n=>Card.fixId(n,false))));
|
||||
this.unk02 = e.next().value[1]; //未知02
|
||||
this.unk03 = e.next().value[1]; //未知03
|
||||
this.unk04 = e.next().value[1]; //未知04
|
||||
this.unk05 = e.next().value[1]; //未知05
|
||||
this.unk06 = e.next().value[1]; //未知06
|
||||
this.unk07 = e.next().value[1]; //未知07
|
||||
const numSkills = e.next().value[1]; //几种敌人技能
|
||||
for (let si = 0; si < numSkills; si++) {
|
||||
this.enemy.skills.push({
|
||||
id: e.next().value[1],
|
||||
ai: e.next().value[1],
|
||||
rnd: e.next().value[1]
|
||||
});
|
||||
}
|
||||
const numAwakening = e.next().value[1]; //觉醒个数
|
||||
for (let ai = 0; ai < numAwakening; ai++) {
|
||||
this.awakenings.push(e.next().value[1]);
|
||||
}
|
||||
this.superAwakenings.push(...(e.next().value[1].split(',').filter(Boolean).map(strN=>parseInt(strN,10)))); //超觉醒
|
||||
this.evoRootId = Card.fixId(e.next().value[1]); //进化链根ID
|
||||
this.seriesId = e.next().value[1]; //系列ID
|
||||
this.types.push(e.next().value[1]); //类型3
|
||||
this.sellMP = e.next().value[1]; //卖多少MP
|
||||
this.latentAwakeningId = e.next().value[1]; //潜在觉醒ID
|
||||
this.collabId = e.next().value[1]; //合作ID
|
||||
this.flags = e.next().value[1];
|
||||
|
||||
this.altName.push(...e.next().value[1].split("|").filter(Boolean)); //替换名字(分类标签)
|
||||
this.limitBreakIncr = e.next().value[1]; //110级增长
|
||||
this.voiceId = e.next().value[1]; //语音觉醒的ID
|
||||
this.blockSkinOrBgmId = e.next().value[1]; //珠子皮肤ID
|
||||
this.specialAttribute = e.next().value[1]; //特别属性,比如黄龙
|
||||
this.searchFlags.push(e.next().value[1], e.next().value[1]); //队长技搜索类型,解析写在这里会导致文件太大,所以写到前端去了
|
||||
this.gachaId = e.next().value[1]; //目前猜测是桶ID
|
||||
this.unk08 = e.next().value[1]; //未知08
|
||||
this.attrs.push(e.next().value[1]); //属性3
|
||||
|
||||
this.attrs = this.attrs.filter(n=>Number.isInteger(n) && n>=0);
|
||||
this.types = this.types.filter(n=>Number.isInteger(n) && n>=0);
|
||||
|
||||
const last = e.next();
|
||||
if (!last.done)
|
||||
console.debug(`有新增数据/residue data for #%d: %o`, this.id , last.value);
|
||||
}
|
||||
get activeSkill(){
|
||||
return Skills[this.activeSkillId];
|
||||
}
|
||||
get leaderSkill(){
|
||||
return Skills[this.leaderSkillId];
|
||||
}
|
||||
get canAssist(){ //是否能当二技
|
||||
return Boolean(this.flags & 1<<0);
|
||||
}
|
||||
get enabled(){ //是否已启用
|
||||
return Boolean(this.flags & 1<<1);
|
||||
}
|
||||
get stacking(){ //flag有1<<3时,不合并占一格,没有时则根据类型进行合并(目前合并已经不占格子)
|
||||
const specialType = [0,12,14,15];
|
||||
return Boolean(this.flags & 1<<3) &&
|
||||
this.types.some(t=>specialType.includes(t)); //0進化用;12能力覺醒用;14強化合成用;15販賣用默认合并
|
||||
}
|
||||
get onlyAssist(){ //是否只能当二技
|
||||
return Boolean(this.flags & 1<<4);
|
||||
}
|
||||
get skillBanner(){ //是否支持8个潜觉
|
||||
return Boolean(this.flags & 1<<5);
|
||||
}
|
||||
get onlyAssist(){ //是否有技能横幅
|
||||
return Boolean(this.flags & 1<<6);
|
||||
}
|
||||
get leaderSkillTypes(){
|
||||
if (this.#leaderSkillTypes == null) {
|
||||
this.#leaderSkillTypes = new LeaderSkillType(this);
|
||||
}
|
||||
return this.#leaderSkillTypes;
|
||||
}
|
||||
}
|
||||
//队长技能类型的翻译
|
||||
class LeaderSkillType{
|
||||
#card = null;
|
||||
#flags = [];
|
||||
#matchMode = null;
|
||||
#restriction = null;
|
||||
#appendEffects = null;
|
||||
constructor(flags1, flags2){
|
||||
if (flags1 instanceof Card || Array.isArray(flags1.searchFlags)) {
|
||||
this.#card = flags1;
|
||||
} else if (Array.isArray(flags1)) {
|
||||
this.#flags.push(...flags1);
|
||||
} else {
|
||||
this.#flags.push(flags1, flags2);
|
||||
}
|
||||
}
|
||||
get matchMode(){
|
||||
if (this.#matchMode == null) {
|
||||
this.#matchMode = new LeaderSkillType_MatchingStyle(this.#card ?? this.#flags);
|
||||
}
|
||||
return this.#matchMode;
|
||||
}
|
||||
get restriction(){
|
||||
if (this.#restriction == null) {
|
||||
this.#restriction = new LeaderSkillType_Restriction_Bind(this.#card ?? this.#flags);
|
||||
}
|
||||
return this.#restriction;
|
||||
}
|
||||
get appendEffects(){
|
||||
if (this.#appendEffects == null) {
|
||||
this.#appendEffects = new LeaderSkillType_ExtraEffects(this.#card ?? this.#flags);
|
||||
}
|
||||
return this.#appendEffects;
|
||||
}
|
||||
}
|
||||
class LeaderSkillType_MatchingStyle {
|
||||
#card = null;
|
||||
#flags = [];
|
||||
constructor(arg){
|
||||
if (arg instanceof Card || Array.isArray(arg.searchFlags)) {
|
||||
this.#card = arg;
|
||||
} else {
|
||||
this.#flags = arg;
|
||||
}
|
||||
}
|
||||
get multipleAttr(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 0)}
|
||||
get rowMatch(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 1)}
|
||||
get combo(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 2)}
|
||||
get sameColor(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 3)}
|
||||
get LShape(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 4)}
|
||||
get crossMatch(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 5)}
|
||||
get heartCrossMatch(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 6)}
|
||||
get remainOrbs(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 7)}
|
||||
get enhanced5Orbs(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 8)}
|
||||
}
|
||||
class LeaderSkillType_Restriction_Bind {
|
||||
#card = null;
|
||||
#flags = [];
|
||||
constructor(arg){
|
||||
if (arg instanceof Card || Array.isArray(arg.searchFlags)) {
|
||||
this.#card = arg;
|
||||
} else {
|
||||
this.#flags = arg;
|
||||
}
|
||||
}
|
||||
get attrEnhance(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 9)}
|
||||
get typeEnhance(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 10)}
|
||||
get board7x6(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 11)}
|
||||
get noSkyfall(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 12)}
|
||||
get HpRange(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 13)}
|
||||
get useSkill(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 14)}
|
||||
get moveTimeDecrease_Fixed(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 15)}
|
||||
get minMatchLen(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 16)}
|
||||
get specialTeam(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 17)}
|
||||
get effectWhenRecover(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 18)}
|
||||
}
|
||||
class LeaderSkillType_ExtraEffects {
|
||||
#card = null;
|
||||
#flags = [];
|
||||
constructor(arg){
|
||||
if (arg instanceof Card || Array.isArray(arg.searchFlags)) {
|
||||
this.#card = arg;
|
||||
} else {
|
||||
this.#flags = arg;
|
||||
}
|
||||
}
|
||||
get addCombo(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 21)}
|
||||
get fixedFollowAttack(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 22)}
|
||||
get scaleFollowAttack(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 23)}
|
||||
get reduce49down(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 24)}
|
||||
get reduce50(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 25)}
|
||||
get reduce51up(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 26)}
|
||||
get moveTimeIncrease(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 20)}
|
||||
get rateMultiplyExp_Coin(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 27)}
|
||||
get rateMultiplyDrop(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 28)}
|
||||
get voidPoison(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 29)}
|
||||
get counterAttack(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 30)}
|
||||
get autoHeal(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 31)}
|
||||
get unbindAwokenBind(){return Boolean(this.#card?.searchFlags?.[0] ?? this.#flags[0] & 1 << 19)}
|
||||
get resolve(){return Boolean(this.#card?.searchFlags?.[1] ?? this.#flags[1] & 1 << 0)}
|
||||
get predictionFalling(){return Boolean(this.#card?.searchFlags?.[1] ?? this.#flags[1] & 1 << 1)}
|
||||
}
|
||||
class Team extends Array {
|
||||
badge = 0;
|
||||
helperTeam = null;
|
||||
constructor(memberCount = 6)
|
||||
{
|
||||
super(memberCount);//建立 Array
|
||||
}
|
||||
get leader1(){
|
||||
return this[0];
|
||||
}
|
||||
get leader2(){
|
||||
//当有 helperTeam 时,使用另一个队伍的队长
|
||||
return helperTeam instanceof Team ? this.helperTeam.leader1 : this[5];
|
||||
}
|
||||
}
|
||||
|
||||
//队员基本的留空
|
||||
var Member = function(id = 0) {
|
||||
|
@ -156,7 +573,7 @@ var Member = function(id = 0) {
|
|||
};
|
||||
//让 Member 能直接获取 card
|
||||
Object.defineProperty(Member.prototype, "card", {
|
||||
get() { return Cards[this.id]; }
|
||||
get() { return Cards[this.id] ?? Cards[0]; }
|
||||
})
|
||||
Member.prototype.effectiveAwokens = function(assist) {
|
||||
const memberCard = this.card;
|
||||
|
@ -1137,9 +1554,7 @@ class PlayerDataCard {
|
|||
};
|
||||
this.awoken = e.next().value[1];
|
||||
|
||||
let parsedLatent = this.parseLatent(e.next().value[1]);
|
||||
this.latentBlocksNum = parsedLatent.latentBlocksNum;
|
||||
this.latent = this.deleteRepeatLatent(parsedLatent.latent.reverse());
|
||||
this.latent = new LatentAwakening(e.next().value[1]);
|
||||
|
||||
this.assistIndex = e.next().value[1];
|
||||
e.next(); //未知
|
||||
|
@ -1171,49 +1586,6 @@ class PlayerDataCard {
|
|||
});
|
||||
return parsedCards;
|
||||
}
|
||||
parseLatent(number)
|
||||
{
|
||||
let latentNumber = BigInt(number);
|
||||
const obj = {
|
||||
latent: [],
|
||||
latentBlocksNum: 6,
|
||||
};
|
||||
//console.log("原始数字",latentNumber.toString(2));
|
||||
const latentVersion = latentNumber & 0b111n; //记录版本,111是用几位来做记录,也就是最多7位
|
||||
latentNumber >>= 3n; //右移3位
|
||||
//console.log("读取潜觉记录位数",latentNumber.toString(2));
|
||||
const changeLatentBlocksNum = Boolean(latentNumber & 1n); //1时就是开孔了
|
||||
latentNumber >>= 1n; //右移1位
|
||||
//console.log("读取潜觉格子数是否改变",latentNumber.toString(2));
|
||||
if (changeLatentBlocksNum)
|
||||
{
|
||||
obj.latentBlocksNum = Number(latentNumber & 0b1111n);
|
||||
latentNumber >>= 4n;
|
||||
//console.log("读取潜觉格子数",latentNumber.toString(2));
|
||||
}
|
||||
const rightbnum = latentVersion > 6n ? 7n : 5n; //右移的距离
|
||||
const getbnum = (1n << rightbnum) - 1n; //逻辑与的数字 //latentVersion > 6 ? 0b1111111n : 0b11111n;
|
||||
while (latentNumber > 0n)
|
||||
{
|
||||
obj.latent.push(Number(latentNumber & getbnum));
|
||||
latentNumber >>= rightbnum;
|
||||
//console.log("读取一个潜觉",latentNumber.toString(2));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
deleteRepeatLatent(olatents)
|
||||
{
|
||||
//splice性能太差,改成push一个新的数组
|
||||
const latents = [];
|
||||
for (let ai = 0; ai < olatents.length;)
|
||||
{
|
||||
const latent = olatents[ai];
|
||||
latents.push(latent);
|
||||
const useHole = latentUseHole(latent);
|
||||
ai += useHole;
|
||||
}
|
||||
return latents;
|
||||
}
|
||||
}
|
||||
//进化树
|
||||
class EvoTree
|
||||
|
@ -1408,51 +1780,6 @@ class RequirementTree extends EvoTree
|
|||
};
|
||||
}
|
||||
|
||||
//队长技能类型的翻译
|
||||
class LeaderSkillType{
|
||||
constructor(flags1, flags2){
|
||||
this.matchMode = {
|
||||
multipleAttr: Boolean(flags1 & 1 << 0),
|
||||
rowMatch: Boolean(flags1 & 1 << 1),
|
||||
combo: Boolean(flags1 & 1 << 2),
|
||||
sameColor: Boolean(flags1 & 1 << 3),
|
||||
LShape: Boolean(flags1 & 1 << 4),
|
||||
crossMatch: Boolean(flags1 & 1 << 5),
|
||||
heartCrossMatch: Boolean(flags1 & 1 << 6),
|
||||
remainOrbs: Boolean(flags1 & 1 << 7),
|
||||
enhanced5Orbs: Boolean(flags1 & 1 << 8),
|
||||
};
|
||||
this.restriction = {
|
||||
attrEnhance: Boolean(flags1 & 1 << 9),
|
||||
typeEnhance: Boolean(flags1 & 1 << 10),
|
||||
board7x6: Boolean(flags1 & 1 << 11),
|
||||
noSkyfall: Boolean(flags1 & 1 << 12),
|
||||
HpRange: Boolean(flags1 & 1 << 13),
|
||||
useSkill: Boolean(flags1 & 1 << 14),
|
||||
moveTimeDecrease_Fixed: Boolean(flags1 & 1 << 15),
|
||||
minMatchLen: Boolean(flags1 & 1 << 16),
|
||||
specialTeam: Boolean(flags1 & 1 << 17),
|
||||
effectWhenRecover: Boolean(flags1 & 1 << 18),
|
||||
};
|
||||
this.appendEffects = {
|
||||
addCombo: Boolean(flags1 & 1 << 21),
|
||||
fixedFollowAttack: Boolean(flags1 & 1 << 22),
|
||||
scaleFollowAttack: Boolean(flags1 & 1 << 23),
|
||||
reduce49down: Boolean(flags1 & 1 << 24),
|
||||
reduce50: Boolean(flags1 & 1 << 25),
|
||||
reduce51up: Boolean(flags1 & 1 << 26),
|
||||
moveTimeIncrease: Boolean(flags1 & 1 << 20),
|
||||
rateMultiplyExp_Coin: Boolean(flags1 & 1 << 27),
|
||||
rateMultiplyDrop: Boolean(flags1 & 1 << 28),
|
||||
voidPoison: Boolean(flags1 & 1 << 29),
|
||||
counterAttack: Boolean(flags1 & 1 << 30),
|
||||
autoHeal: Boolean(flags1 & 1 << 31),
|
||||
unbindAwokenBind: Boolean(flags1 & 1 << 19),
|
||||
resolve: Boolean(flags2 & 1 << 0),
|
||||
predictionFalling: Boolean(flags2 & 1 << 1),
|
||||
};
|
||||
}
|
||||
}
|
||||
//清除数据
|
||||
function clearData()
|
||||
{
|
||||
|
@ -1685,7 +2012,7 @@ function loadData(force = false)
|
|||
for (let i = splitIdx + 1; i < _cards.length; i++)
|
||||
{
|
||||
const card = _cards[i];
|
||||
if (card.searchFlags) card.leaderSkillTypes = new LeaderSkillType(...card.searchFlags);
|
||||
if (card.searchFlags) card.leaderSkillTypes = new LeaderSkillType(card);
|
||||
card.onlyAssist = Boolean(card.flags & 1<<4);
|
||||
/*card.unk01p = flags(card.unk01);
|
||||
card.unk02p = flags(card.unk02);
|
||||
|
|
Loading…
Reference in New Issue