| @@ -87,7 +87,11 @@ | |||
| power_up_targets: tp`[${'attrs_types'}]'s `, //attrs, types, attrs_types | |||
| henshin: tp`Transforms into ${'card'}`, | |||
| void_poison: tp`Voids ${'poison'} damage`, | |||
| skill_proviso: tp`The follow-up effect can only be initiated ${'condition'}`, | |||
| skill_proviso: tp`The follow-up effect can only be activates ${'condition'}`, | |||
| obstruct_opponent: tp`Apply obstruct skill effect to ${'target'}: ${'skills'}`, | |||
| obstruct_opponent_after_me: tp`The opponent ranked lower than me`, | |||
| obstruct_opponent_before_me: tp`The opponent ranked higher than me`, | |||
| obstruct_opponent_designated_position: tp`No.${'positions'} ranked opponents`, | |||
| }, | |||
| power: { | |||
| unknown: tp`[ Unkonwn power up: ${'type'} ]`, | |||
| @@ -178,7 +182,7 @@ | |||
| in_once: tp`in onece `, | |||
| evo_type_pixel: tp`Pixel Evo`, | |||
| evo_type_reincarnation: tp`Reinc. or Super Reinc. Evo`, | |||
| evo_type_unknow: tp`Unknown Evo`, | |||
| evo_type_unknow: tp`Unknown Evo: ${'type'}`, | |||
| affix_attr: tp`${'cotent'} attr.`, | |||
| affix_orb: tp`${'cotent'} orbs`, | |||
| affix_type: tp`${'cotent'} types`, | |||
| @@ -8,7 +8,7 @@ Number.prototype.bigNumberToString = function() { | |||
| let numTemp = negative ? Math.abs(this) : this.valueOf(); | |||
| if (!numTemp) return "0"; | |||
| const grouping = Math.pow(10, 4); | |||
| const grouping = 1e4; | |||
| const unit = ['', '万', '亿', '兆', '京', '垓']; | |||
| const numParts = []; | |||
| do { | |||
| @@ -34,8 +34,8 @@ Number.prototype.bigNumberToString = function() { | |||
| //查找原先完整技能 | |||
| function findFullSkill(subSkill) { | |||
| const parentSkill = Skills.find(ss => (ss.type === 116 || ss.type === 118 || ss.type === 138) && ss.params.includes(subSkill.id)) || subSkill; | |||
| const aCard = Cards.find(card => card.activeSkillId == parentSkill.id || card.leaderSkillId == parentSkill.id); | |||
| const parentSkill = Skills.find(ss => (ss.type === 116 || ss.type === 118 || ss.type === 138) && ss.params.includes(subSkill.id)) || subSkill;3 | |||
| const aCard = Cards.find(card => card?.activeSkillId == parentSkill.id || card?.leaderSkillId == parentSkill.id); | |||
| return { skill: parentSkill, card: aCard }; | |||
| } | |||
| //document.querySelector(".edit-box .row-mon-id .m-id").type = "number"; | |||
| @@ -45,20 +45,13 @@ showSearch(result.map(o=>o.card).filter(c=>c)); | |||
| console.table(result); | |||
| */ | |||
| //按住Ctrl点击技能在控制台输出技能的对象 | |||
| function fastShowSkill(event) { | |||
| if (event.ctrlKey) { | |||
| const skillId = parseInt(this.getAttribute("data-skillid"), 10); | |||
| console.log(Skills[skillId]); | |||
| } | |||
| } | |||
| //insertAdjacentHTML 可以只增加部分 HTML | |||
| //高级技能解释 | |||
| function parseSkillDescription(skill) { | |||
| const id = skill.id; | |||
| const id = skill?.id; | |||
| let fragment = document.createDocumentFragment(); //创建节点用的临时空间 | |||
| if (id == 0) return fragment; | |||
| if (!id) return fragment; | |||
| const sk = skill.params; | |||
| //珠子名和属性名数组 | |||
| @@ -1466,6 +1459,32 @@ function parseSkillDescription(skill) { | |||
| case 229: | |||
| str = `队伍中每存在1个${getAttrTypeString(flags(sk[0]), flags(sk[1]))}时,${getFixedHpAtkRcvString({hp:sk[2],atk:sk[3],rcv:sk[4]}, false)}`; | |||
| break; | |||
| case 1000:{ //8人限定的技能 | |||
| //str = skill.description + '\n'; | |||
| str = ''; | |||
| switch (sk[0]) | |||
| { | |||
| case 1: { | |||
| str += `对排名比自身靠后的`; | |||
| break; | |||
| } | |||
| case 2: { | |||
| str += `对排名${flags(sk[1]).map(n=>n+1).join('、')}`; | |||
| break; | |||
| } | |||
| case 3: { | |||
| str += `对排名比自身靠前的`; | |||
| break; | |||
| } | |||
| default: { | |||
| str += `未知排名${sk[0]}`; | |||
| break; | |||
| } | |||
| } | |||
| str += `,使用敌人技能${sk.slice(2).join('、')}`; | |||
| break; | |||
| } | |||
| default: | |||
| str = `未知的技能类型${skill.type}(No.${id})`; | |||
| //开发部分 | |||
| @@ -32,7 +32,7 @@ Number.prototype.bigNumberToString = function() | |||
| { | |||
| let numTemp = this.valueOf(); | |||
| if (!numTemp) return "0"; | |||
| const grouping = Math.pow(10, 4); | |||
| const grouping = 1e4; | |||
| const unit = ['','萬','億','兆','京','垓']; | |||
| const numParts = []; | |||
| do{ | |||
| @@ -42,6 +42,7 @@ officialAPI.forEach(function(lang) { | |||
| const oCards = lang.cardOriginal = cardJsonObj.card;//将字符串转换为json对象 | |||
| const monCards = lang.cards = []; | |||
| //const monCards = lang.cards = oCards.map(ocard=>new Card(ocard)); | |||
| /*oCards.forEach((oCard, idx)=>{ | |||
| let mid = oCard[0]; | |||
| if (mid === idx) //原始怪物 | |||
| @@ -56,7 +57,17 @@ officialAPI.forEach(function(lang) { | |||
| });*/ | |||
| for (let cardIndex = 0; oCards[cardIndex][0] === cardIndex; cardIndex++) | |||
| { | |||
| monCards.push(new Card(oCards[cardIndex])); | |||
| const card = new Card(oCards[cardIndex]); | |||
| delete card.enemy; | |||
| delete card.unk01; | |||
| delete card.unk02; | |||
| delete card.unk03; | |||
| delete card.unk04; | |||
| delete card.unk05; | |||
| delete card.unk06; | |||
| delete card.unk07; | |||
| delete card.unk08; | |||
| monCards.push(card); | |||
| } | |||
| //加入自定义的语言 | |||
| @@ -86,7 +97,6 @@ officialAPI.forEach(function(lang) { | |||
| const oSkills = lang.skillOriginal = skillJsonObj.skill;//将字符串转换为json对象 | |||
| lang.skills = oSkills.map((oc,idx)=>new Skill(idx,oc)); //每一项生成分析对象 | |||
| lang.cards.forEach((m,idx,arr)=>{ | |||
| const skill = lang.skills[m.activeSkillId]; | |||
| let henshinTo = null; | |||
| @@ -104,6 +114,10 @@ officialAPI.forEach(function(lang) { | |||
| arr[henshinTo].henshinFrom = idx; | |||
| } | |||
| }); | |||
| const eskillJson = fs.readFileSync("official-API/" + lang.code +"-enemy_skill.json", 'utf-8'); //使用同步读取技能 | |||
| const eskillJsonObj = JSON.parse(eskillJson); | |||
| lang.enemy_skills = eskillJsonObj.enemy_skills; | |||
| }); | |||
| //加入其他服务器相同角色的名字 | |||
| @@ -215,6 +229,14 @@ var newCkeyObjs = officialAPI.map(lang=>{ | |||
| } | |||
| console.log(`skill_${lcode}.json 导出成功`); | |||
| }); | |||
| const enemy_skillsStr = lang.enemy_skills; | |||
| //写入Skills | |||
| fs.writeFile(`./enemy_skills_${lcode}.json`,enemy_skillsStr,function(err){ | |||
| if(err){ | |||
| console.error(err); | |||
| } | |||
| console.log(`enemy_skills_${lcode}.json 导出成功`); | |||
| }); | |||
| const cardHash = crypto.createHash('md5'); | |||
| const skillHash = crypto.createHash('md5'); | |||
| @@ -80,8 +80,7 @@ GM_xmlhttpRequest({ | |||
| url:"ja-card.json", | |||
| onload: function(response) { | |||
| const originalJSON = JSON.parse(response.response); | |||
| console.log(originalJSON) | |||
| cards = originalJSON.card.filter((c,idx)=>{return c[0]==idx;}); | |||
| cards = originalJSON.card; | |||
| pcards = cards.map(c=>{ | |||
| let card = new Card(c); | |||
| //将可能的flag显示为二进制 | |||
| @@ -101,6 +101,10 @@ let localTranslating = { | |||
| henshin: tp`变身为${'card'}`, | |||
| void_poison: tp`消除${'poison'}时不会受到毒伤害`, | |||
| skill_proviso: tp`${'condition'}才能发动后续效果`, | |||
| obstruct_opponent: tp`对${'target'}施加敌对技能效果:${'skills'}`, | |||
| obstruct_opponent_after_me: tp`排名比自身低的对手`, | |||
| obstruct_opponent_before_me: tp`排名比自身高的对手`, | |||
| obstruct_opponent_designated_position: tp`第${'positions'}排位的对手`, | |||
| }, | |||
| power: { | |||
| unknown: tp`[ 未知能力提升: ${'type'} ]`, | |||
| @@ -190,7 +194,7 @@ let localTranslating = { | |||
| in_once: tp`同时`, | |||
| evo_type_pixel: tp`像素进化`, | |||
| evo_type_reincarnation: tp`转生或超转生进化`, | |||
| evo_type_unknow: tp`未知进化`, | |||
| evo_type_unknow: tp`未知进化: ${'type'}`, | |||
| affix_attr: tp`${'cotent'}属性`, //词缀-属性 | |||
| affix_orb: tp`${'cotent'}宝珠`, //词缀-宝珠 | |||
| affix_type: tp`${'cotent'}类型`, //词缀-类型 | |||
| @@ -3206,6 +3210,13 @@ const specialSearchFunctions = (function() { | |||
| } | |||
| }) | |||
| }, | |||
| /*{name:"8P dedicated hostile skills",otLangName:{chs:"8P专用敌对技能"}, | |||
| function:cards=>cards.filter(card=>{ | |||
| const searchTypeArray = [1000]; | |||
| const skill = getCardActiveSkill(card, searchTypeArray); | |||
| return skill; | |||
| }) | |||
| },*/ | |||
| ]}, | |||
| ]; | |||
| return functions; | |||
| @@ -369,6 +369,7 @@ const SkillKinds = { | |||
| Henshin: "henshin", | |||
| VoidPoison: "void-poison", | |||
| SkillProviso: "skill-proviso", | |||
| ObstructOpponent: "obstruct-opponent", | |||
| } | |||
| function skillParser(skillId) | |||
| @@ -920,6 +921,9 @@ function noSkyfall() { return { kind: SkillKinds.NoSkyfall }; } | |||
| function henshin(id) { return { kind: SkillKinds.Henshin, id: id }; } | |||
| function voidPoison() { return { kind: SkillKinds.VoidPoison }; } | |||
| function skillProviso(cond) { return { kind: SkillKinds.SkillProviso, cond: cond }; } | |||
| function obstructOpponent(type, pos, ids) { | |||
| return { kind: SkillKinds.ObstructOpponent, type: type, pos: pos, enemy_skills: ids }; | |||
| } | |||
| const parsers = { | |||
| parser: (() => []), //这个用来解决代码提示的报错问题,不起实际作用 | |||
| @@ -1332,9 +1336,19 @@ const parsers = { | |||
| return powerUp(null, null, p.scaleMatchAttrs(attrs.map(flags), min, attrs.length, [100, 100], [0, 0]), null, null, [followAttackFixed(damage)]); | |||
| }, | |||
| [202](id) { | |||
| return henshin(id); | |||
| return henshin(id); | |||
| }, | |||
| [203](evotypeid, hp, atk, rcv) { | |||
| let evotype = (type=>{ | |||
| switch (type) { | |||
| case 0: return "pixel-evo"; | |||
| case 2: return "reincarnation-evo"; | |||
| default: return type; | |||
| } | |||
| })(evotypeid); | |||
| return powerUp(null, null, p.mul({ hp: hp || 100, atk: atk || 100, rcv: rcv || 100 }), | |||
| c.compo('evolution', [evotype])); | |||
| }, | |||
| [203](evotype, hp, atk, rcv) { return powerUp(null, null, p.mul({ hp: hp || 100, atk: atk || 100, rcv: rcv || 100 }), c.compo('evolution', [evotype])); }, | |||
| [205](attrs, turns) { return activeTurns(turns, orbDropIncrease(null, flags(attrs == -1 ? 1023: attrs), 'locked')); }, | |||
| [206](attrs1, attrs2, attrs3, attrs4, attrs5, min, combo) { | |||
| @@ -1386,6 +1400,17 @@ const parsers = { | |||
| [229](attrs, types, hp, atk, rcv) { | |||
| return powerUp(null, null, p.scaleStateKindCount(null, flags(attrs), flags(types), p.mul({hp: hp, atk: atk, rcv: rcv}))); | |||
| }, | |||
| [1000](type, pos, ...ids) { | |||
| let posType = (type=>{ | |||
| switch (type) { | |||
| case 1: return "after-me"; | |||
| case 2: return "designated-position"; | |||
| case 3: return "before-me"; | |||
| default: return type; | |||
| } | |||
| })(type); | |||
| return obstructOpponent(posType, flags(pos), ids); | |||
| }, | |||
| }; | |||
| //将内容添加到代码片段 | |||
| @@ -2070,6 +2095,35 @@ function renderSkill(skill, option = {}) | |||
| frg.ap(tsp.skill.skill_proviso(dict)); | |||
| break; | |||
| } | |||
| case SkillKinds.ObstructOpponent: { //条件限制才能用技能 | |||
| let type = skill.type, pos = skill.pos, enemy_skills = skill.enemy_skills; | |||
| let slight_pause = tsp.word.slight_pause().textContent; | |||
| dict = { | |||
| skills: enemy_skills.join(slight_pause) | |||
| } | |||
| let targetDict = { positions: pos?.map(p=>p+1).join(slight_pause)} | |||
| switch (type) | |||
| { | |||
| case "after-me": { | |||
| dict.target = tsp.skill.obstruct_opponent_after_me(targetDict); | |||
| break; | |||
| } | |||
| case "designated-position": { | |||
| dict.target = tsp.skill.obstruct_opponent_designated_position(targetDict); | |||
| break; | |||
| } | |||
| case "before-me": { | |||
| dict.target = tsp.skill.obstruct_opponent_before_me(targetDict); | |||
| break; | |||
| } | |||
| default: { | |||
| dict.target = tsp.cond.unknown(); | |||
| break; | |||
| } | |||
| } | |||
| frg.ap(tsp.skill.obstruct_opponent(dict)); | |||
| break; | |||
| } | |||
| default: { | |||
| console.log("未处理的技能类型",skill.kind, skill); | |||
| @@ -2271,19 +2325,19 @@ function renderCondition(cond) { | |||
| break; | |||
| } | |||
| case 'evolution':{ | |||
| dict.ids = cond.compo.ids.map(eid=>{ | |||
| dict.ids = cond.compo.ids.map(type=>{ | |||
| const lnk = document.createElement("a"); | |||
| lnk.className ="detail-search"; | |||
| switch (eid) | |||
| switch (type) | |||
| { | |||
| case 0:{ //像素进化 | |||
| case "pixel-evo":{ //像素进化 | |||
| lnk.appendChild(tsp.word.evo_type_pixel()); | |||
| lnk.onclick = function(){ | |||
| showSearch(Cards.filter(card=>card.evoMaterials.includes(3826))); | |||
| }; | |||
| break; | |||
| } | |||
| case 2:{ //转生或超转生 | |||
| case "reincarnation-evo":{ //转生或超转生 | |||
| lnk.appendChild(tsp.word.evo_type_reincarnation()); | |||
| lnk.onclick = function(){ | |||
| showSearch(Cards.filter(card=>isReincarnated(card))); | |||
| @@ -2291,7 +2345,7 @@ function renderCondition(cond) { | |||
| break; | |||
| } | |||
| default:{ //转生或超转生 | |||
| return tsp.word.evo_type_unknow(); | |||
| return tsp.word.evo_type_unknow({ type }); | |||
| } | |||
| } | |||
| return lnk; | |||
| @@ -656,6 +656,19 @@ function searchCollab(event) { | |||
| showSearch(Cards.filter(card => card.collabId == collabId)); | |||
| return false; | |||
| } | |||
| //按住Ctrl点击技能在控制台输出技能的对象 | |||
| function fastShowSkill(event) { | |||
| const skillId = parseInt(this.getAttribute("data-skillid"), 10); //获得当前技能ID | |||
| if (event.ctrlKey) { | |||
| const skillId = parseInt(this.getAttribute("data-skillid"), 10); | |||
| console.debug(Skills[skillId]); | |||
| return; | |||
| }; | |||
| const s_cards = Cards.filter(card => card.activeSkillId === skillId); //搜索同技能怪物 | |||
| if (s_cards.length > 1) { | |||
| showSearch(s_cards); //显示 | |||
| } | |||
| } | |||
| //将怪物的文字介绍解析为HTML | |||
| function descriptionToHTML(str) | |||
| @@ -815,7 +815,7 @@ function loadData(force = false) | |||
| request.onsuccess = function(event) { | |||
| if (Array.isArray(request.result)) | |||
| { | |||
| Cards = request.result; | |||
| Cards = loadExtraCardsData(request.result); | |||
| dealCardsData(Cards); | |||
| }else | |||
| { | |||
| @@ -835,7 +835,7 @@ function loadData(force = false) | |||
| url: `${sourceDataFolder}/mon_${currentDataSource.code}.json?t=${_time}`, //Cards数据文件 | |||
| onload: function(response) { | |||
| try { | |||
| Cards = JSON.parse(response.response); | |||
| Cards = loadExtraCardsData(JSON.parse(response.response)); | |||
| } catch (e) { | |||
| console.error("Cards 数据 JSON 解码出错。", e); | |||
| return; | |||
| @@ -862,7 +862,17 @@ function loadData(force = false) | |||
| } | |||
| }); | |||
| } | |||
| function loadExtraCardsData(_cards) | |||
| { | |||
| let splitIdx = _cards.findIndex((card, id)=>card.id !== id); | |||
| let cards = _cards.slice(0, splitIdx); | |||
| for (let i = splitIdx + 1; i < _cards.length; i++) | |||
| { | |||
| const card = _cards[i]; | |||
| cards[card.id] = card; | |||
| } | |||
| return cards; | |||
| } | |||
| function dealCardsData() | |||
| { | |||
| if (editBox) | |||
| @@ -2830,14 +2840,7 @@ function initialize() { | |||
| const skillLevel_1 = skillBox.querySelector(".m-skill-lv-1"); | |||
| const skillLevel_Max = skillBox.querySelector(".m-skill-lv-max"); | |||
| skillTitle.onclick = function(event) { | |||
| if (event.ctrlKey) return; | |||
| const skillId = parseInt(this.getAttribute("data-skillid"), 10); //获得当前技能ID | |||
| const s_cards = Cards.filter(card => card.activeSkillId === skillId); //搜索同技能怪物 | |||
| if (s_cards.length > 1) { | |||
| showSearch(s_cards); //显示 | |||
| } | |||
| }; | |||
| skillTitle.onclick = fastShowSkill; | |||
| skillLevel.onchange = function() { | |||
| const card = Cards[editBox.mid] || Cards[0]; //怪物固定数据 | |||
| @@ -2851,6 +2854,9 @@ function initialize() { | |||
| const rowLeaderSkill = settingBox.querySelector(".row-mon-leader-skill"); | |||
| const leaderSkillBox = rowLeaderSkill.querySelector(".skill-box"); | |||
| const lskillTitle = leaderSkillBox.querySelector(".skill-name"); | |||
| lskillTitle.onclick = fastShowSkill; | |||
| const showSkillOriginalClassName = 'show-skill-original'; | |||
| const showSkillOriginal = leaderSkillBox.querySelector(`#${showSkillOriginalClassName}`); //显示官方排序的觉醒 | |||
| showSkillOriginal.onchange = function(e){ | |||
| @@ -3174,7 +3180,7 @@ function changeid(mon, monDom, latentDom) { | |||
| parentNode.classList.remove("null"); | |||
| parentNode.classList.remove("delay"); | |||
| monDom.setAttribute("data-cards-pic-idx", Math.ceil(monId / 100)); //添加图片编号 | |||
| monDom.setAttribute("data-cards-pic-idx", Math.ceil(monId % 1e5 / 100)); //添加图片编号 | |||
| const idxInPage = (monId - 1) % 100; //获取当前页面的总序号 | |||
| monDom.setAttribute("data-cards-pic-x", idxInPage % 10); //添加X方向序号 | |||
| monDom.setAttribute("data-cards-pic-y", Math.floor(idxInPage / 10)); //添加Y方向序号 | |||
| @@ -3462,7 +3468,7 @@ function editBoxChangeMonId(id) { | |||
| } | |||
| const evoLinkCardsIdArray = Cards.filter(m=>m.evoRootId == card.evoRootId).map(m=>m.id); //筛选出相同进化链的 | |||
| const evoLinkCardsIdArray = card.evoRootId !== 0 ? Cards.filter(m=>m.evoRootId == card.evoRootId).map(m=>m.id) : []; //筛选出相同进化链的 | |||
| function loopAddHenshin(arr,card) | |||
| { | |||