diff --git a/game/game.js b/game/game.js index d95200bbf..3c111b0bd 100644 --- a/game/game.js +++ b/game/game.js @@ -1,100 +1,101 @@ -"use strict"; - -new Promise(resolve => { - // 客户端自带core.js的请注意跟进 - if ('__core-js_shared__' in window) resolve(null); - else { - const nonameInitialized = localStorage.getItem('noname_inited'); - const assetURL = typeof nonameInitialized != 'string' || nonameInitialized == 'nodejs' ? '' : nonameInitialized; - const coreJSBundle = document.createElement('script'); - coreJSBundle.onerror = coreJSBundle.onload = resolve; - coreJSBundle.src = `${assetURL}game/core-js-bundle.js`; - document.head.appendChild(coreJSBundle); - } -}).then(() => { - const nonameInitialized = localStorage.getItem('noname_inited'); - const assetURL = typeof nonameInitialized != 'string' || nonameInitialized == 'nodejs' ? '' : nonameInitialized; - const userAgent = navigator.userAgent.toLowerCase(); - - const exit = () => { - const ios = userAgent.includes('iphone') || userAgent.includes('ipad') || userAgent.includes('macintosh'); - //electron - if (typeof window.process == 'object' && typeof window.require == 'function') { - const versions = window.process.versions; - // @ts-ignore - const electronVersion = parseFloat(versions.electron); - let remote; - if (electronVersion >= 14) { - // @ts-ignore - remote = require('@electron/remote'); - } else { - // @ts-ignore - remote = require('electron').remote; - } - const thisWindow = remote.getCurrentWindow(); - thisWindow.destroy(); - window.process.exit(); - } - //android-cordova环境 - //ios-cordova环境或ios浏览器环境 - //非ios的网页版 - else if (!ios) { - window.close(); - } - }; - - if (!localStorage.getItem('gplv3_noname_alerted')) { - if (confirm('①无名杀是一款基于GPLv3协议的开源软件!\n你可以在遵守GPLv3协议的基础上任意使用,修改并转发《无名杀》,以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓️\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库!\n其他所有的所谓“无名杀”社群(包括但不限于绝大多数“官方”QQ群、QQ频道等)均为玩家自发组织,与无名杀官方无关!')) { - // @ts-ignore - localStorage.setItem('gplv3_noname_alerted', true); - } - else { - exit(); - } - } - window['b' + 'ann' + 'e' + 'dE' + 'x' + 'ten' + 's' + 'i' + 'o' + 'ns'] = ['\u4fa0\u4e49', '\u5168\u6559\u7a0b']; - - /** - * - * @returns {["firefox" | "chrome" | "safari" | "other", number]} - */ - function coreInfo() { - const regex = /(firefox|chrome|safari)\/([\d.]+)/; - let result; - if (!(result = userAgent.match(regex))) return ["other", NaN]; - if (result[1] !== "safari") return [result[1], parseInt(result[2])]; - result = userAgent.match(/version\/([\d.]+).*safari/); - // @ts-ignore - return ["safari", parseInt(result[1])]; - } - const [core, version] = coreInfo(); - const supportMap = { - "firefox": 60, - "chrome": 61, - // 因为coreInfo不考虑子版本,故就强行只能以11运行 - "safari": 11 - } - - if (core in supportMap && supportMap[core] > version) { - const tip = '检测到您的浏览器内核版本无法支持ES Module,请立即升级浏览器或手机webview内核!'; - console.error(tip); - const redirect_tip = '您使用的浏览器或无名杀客户端内核版本过低,已经无法正常运行无名杀!\n点击“确认”以前往GitHub下载最新版无名杀客户端(可能需要科学上网)。\n稍后您的无名杀将自动退出(可能的话)'; - if (confirm(redirect_tip)) { - window.open('https://github.com/libccy/noname/releases/tag/chromium77-client'); - } - exit() - } - else { - const script = document.createElement('script') - script.type = "module"; - script.src = `${assetURL}game/entry.js` - script.async = true - script.onerror = (event) => { - console.error(event) - const message = `您使用的浏览器或无名杀客户端加载内容失败!\n报错内容: \n${event}\n若该BUG不为您个人原因造成的,请及时反馈给无名杀开发组!`; - alert(message); - exit() - } - document.head.appendChild(script) - } -}); +"use strict"; + +new Promise(resolve => { + // 客户端自带core.js的请注意跟进 + if ('__core-js_shared__' in window) resolve(null); + else { + const nonameInitialized = localStorage.getItem('noname_inited'); + const assetURL = typeof nonameInitialized != 'string' || nonameInitialized == 'nodejs' ? '' : nonameInitialized; + const coreJSBundle = document.createElement('script'); + coreJSBundle.onerror = coreJSBundle.onload = resolve; + coreJSBundle.src = `${assetURL}game/core-js-bundle.js`; + document.head.appendChild(coreJSBundle); + } +}).then(() => { + const nonameInitialized = localStorage.getItem('noname_inited'); + const assetURL = typeof nonameInitialized != 'string' || nonameInitialized == 'nodejs' ? '' : nonameInitialized; + const userAgent = navigator.userAgent.toLowerCase(); + + const exit = () => { + const ios = userAgent.includes('iphone') || userAgent.includes('ipad') || userAgent.includes('macintosh'); + //electron + if (typeof window.process == 'object' && typeof window.require == 'function') { + const versions = window.process.versions; + // @ts-ignore + const electronVersion = parseFloat(versions.electron); + let remote; + if (electronVersion >= 14) { + // @ts-ignore + remote = require('@electron/remote'); + } else { + // @ts-ignore + remote = require('electron').remote; + } + const thisWindow = remote.getCurrentWindow(); + thisWindow.destroy(); + window.process.exit(); + } + //android-cordova环境 + //ios-cordova环境或ios浏览器环境 + //非ios的网页版 + else if (!ios) { + window.close(); + } + }; + + if (!localStorage.getItem('gplv3_noname_alerted')) { + if (confirm('①无名杀是一款基于GPLv3协议的开源软件!\n你可以在遵守GPLv3协议的基础上任意使用,修改并转发《无名杀》,以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓️\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库!\n其他所有的所谓“无名杀”社群(包括但不限于绝大多数“官方”QQ群、QQ频道等)均为玩家自发组织,与无名杀官方无关!')) { + // @ts-ignore + localStorage.setItem('gplv3_noname_alerted', true); + } + else { + exit(); + } + } + window['b' + 'ann' + 'e' + 'dE' + 'x' + 'ten' + 's' + 'i' + 'o' + 'ns'] = ['\u4fa0\u4e49', '\u5168\u6559\u7a0b']; + + /** + * + * @returns {["firefox" | "chrome" | "safari" | "other", number]} + */ + function coreInfo() { + const regex = /(firefox|chrome|safari)\/([\d.]+)/; + let result; + if (!(result = userAgent.match(regex))) return ["other", NaN]; + if (result[1] !== "safari") return [result[1], parseInt(result[2])]; + result = userAgent.match(/version\/([\d.]+).*safari/); + // @ts-ignore + return ["safari", parseInt(result[1])]; + } + const [core, version] = coreInfo(); + const supportMap = { + "firefox": 60, + "chrome": 61, + // 因为coreInfo不考虑子版本,故就强行只能以11运行 + "safari": 11 + } + + if (core in supportMap && supportMap[core] > version) { + const tip = '检测到您的浏览器内核版本无法支持ES Module,请立即升级浏览器或手机webview内核!'; + console.error(tip); + const redirect_tip = '您使用的浏览器或无名杀客户端内核版本过低,已经无法正常运行无名杀!\n点击“确认”以前往GitHub下载最新版无名杀客户端(可能需要科学上网)。\n稍后您的无名杀将自动退出(可能的话)'; + if (confirm(redirect_tip)) { + window.open('https://github.com/libccy/noname/releases/tag/chromium77-client'); + } + exit() + } + else { + const script = document.createElement('script') + script.type = "module"; + script.src = `${assetURL}game/entry.js` + script.async = true + script.onerror = (event) => { + console.error(event) + const message = `您使用的浏览器或无名杀客户端加载内容失败!\n请检查游戏环境以及"(游戏根目录)/game/entry.js"文件的位置\n若该BUG不为您个人原因造成的,请及时反馈给无名杀开发组!`; + console.error(message); + alert(message); + exit() + } + document.head.appendChild(script) + } +}); diff --git a/noname/get/index.js b/noname/get/index.js index df87b1d4e..332b78f66 100644 --- a/noname/get/index.js +++ b/noname/get/index.js @@ -1,4548 +1,4561 @@ -import { userAgent, Uninstantable, GeneratorFunction, AsyncFunction } from "../util/index.js"; -import { AI as ai } from '../ai/index.js'; -import { Game as game } from '../game/index.js'; -import { Library as lib } from '../library/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { GNC as gnc } from '../gnc/index.js'; - -import { Is } from "./is.js"; - -export class Get extends Uninstantable { - static is = Is; - /** - * 获取当前内核版本信息 - * - * 目前仅考虑`chrome`, `firefox`和`safari`三种浏览器的信息,其余均归于其他范畴 - * - * > 其他后续或许会增加,但`IE`永无可能 - * - * @returns {["firefox" | "chrome" | "safari" | "other", number]} - */ - static coreInfo() { - const regex = /(firefox|chrome|safari)\/([\d.]+)/; - let result; - if (!(result = userAgent.match(regex))) return ["other", NaN]; - if (result[1] != "safari") return [result[1], parseInt(result[2])]; - result = userAgent.match(/version\/([\d.]+).*safari/); - return ["safari", parseInt(result[1])]; - } - /** - * 返回 VCard[] 形式的所有牌,用于印卡将遍历 - * @param {Function} filter - * @returns {string[][]} - */ - static inpileVCardList(filter) { - let list = []; - for (const name of lib.inpile) { - const type = get.type(name); - const info = [type, '', name]; - if (!filter || filter(info)) list.push(info); - if (name == 'sha') { - for (const nature of lib.inpile_nature) { - const info = [type, '', name, nature]; - if (!filter || filter(info)) list.push(info); - } - } - } - return list; - } - /** - * 根据座次数n(从0开始)获取对应的“n+1号位”翻译 - * @param {number} seat - */ - static seatTranslation(seat) { return `${get.cnNumber(seat + 1, true)}号位`; } - /** - * @param {number} numberOfPlayers - * @returns {string[]} - */ - static identityList(numberOfPlayers) { - const modeConfig = lib.config.mode_config; - if (modeConfig) { - const identityConfig = modeConfig.identity; - if (identityConfig) { - const identityLists = identityConfig.identity; - if (identityLists) { - const identityList = identityLists[numberOfPlayers - 2]; - if (Array.isArray(identityList)) return identityList.slice(); - } - } - } - const numberOfPlayersExceptLord = numberOfPlayers - 1, numberOfLoyalists = Math.round(numberOfPlayersExceptLord * 3 / 9), numberOfSpys = Math.round(numberOfPlayersExceptLord * 2 / 9); - return ['zhu'].concat(Array.from({ - length: numberOfLoyalists - }, () => 'zhong'), Array.from({ - length: numberOfSpys - }, () => 'nei'), Array.from({ - length: numberOfPlayersExceptLord - numberOfLoyalists - numberOfSpys - }, () => 'fan')); - } - /** - * Generate an object URL from the Base64-encoded octet stream - * - * 从Base64编码的八位字节流生成对象URL - */ - static objectURL(octetStream) { - const objectURLMap = lib.objectURL; - if (objectURLMap.has(octetStream)) return objectURLMap.get(octetStream); - const objectURL = URL.createObjectURL(new Blob([Uint8Array.from(atob(octetStream.replace(/^data:[\s\S]*\/[\s\S]*;base64,/, '')), character => character.charCodeAt())])); - objectURLMap.set(octetStream, objectURL); - return objectURL; - } - /** - * Get the card name length - * - * 获取此牌的字数 - */ - static cardNameLength(card, player) { - const actualCardName = lib.actualCardName, name = get.translation(typeof card == 'string' ? card : get.name(card, player)); - return (actualCardName.has(name) ? actualCardName.get(name) : name).length; - } - //Yingbian - //应变 - /** - * Get the Yingbian conditions (of the card) - * - * 获取(此牌的)应变条件 - */ - static yingbianConditions(card) { return get.complexYingbianConditions(card).concat(get.simpleYingbianConditions(card)); } - static complexYingbianConditions(card) { - const complexYingbianConditions = Array.from(lib.yingbian.condition.complex.keys()); - return card ? complexYingbianConditions.filter(value => get.cardtag(card, `yingbian_${value}`)) : complexYingbianConditions; - } - static simpleYingbianConditions(card) { - const simpleYingbianConditions = Array.from(lib.yingbian.condition.simple.keys()); - return card ? simpleYingbianConditions.filter(value => get.cardtag(card, `yingbian_${value}`)) : simpleYingbianConditions; - } - /** - * Get the Yingbian effects (of the card) - * - * 获取(此牌的)应变效果 - */ - static yingbianEffects(card) { - const yingbianEffects = Array.from(lib.yingbian.effect.keys()); - return card ? yingbianEffects.filter(value => get.cardtag(card, `yingbian_${value}`)) : yingbianEffects; - } - /** - * Get the default Yingbian effect of the card - * - * 获取此牌的默认应变效果 - */ - static defaultYingbianEffect(card) { - const info = get.info(card); - return info && info.defaultYingbianEffect || null; - } - /** - * 优先度判断 - */ - static priority(skill) { - const info = get.info(skill); - if (!info) return 0; - if ('_priority' in info) return info._priority; - let priority = 0; - if (info.priority) { - priority = info.priority * 100; - } - if (info.silent) { - priority++; - } - if (info.equipSkill) priority -= 25; - if (info.cardSkill) priority -= 50; - if (info.ruleSkill) priority -= 75; - info._priority = priority; - return priority; - } - /** - * 新装备栏相关 - * - * 获取一张装备牌实际占用的装备栏(君曹操六龙) - * - * 用法同get.subtype,返回数组 - */ - static subtypes(obj, player) { - if (typeof obj == 'string') obj = { name: obj }; - if (typeof obj != 'object') return; - var name = get.name(obj, player); - if (!lib.card[name]) return []; - if (lib.card[name].subtypes) { - const subtypes = get.copy(lib.card[name].subtypes); - return subtypes; - } - else if (lib.card[name].subtype) { - const subtype = lib.card[name].subtype; - return [subtype]; - } - return []; - } - //装备栏 END - /** - * @returns { string[] } - */ - static pinyin(chinese, withTone) { - const pinyinUtilx = window.pinyinUtilx; - if (!pinyinUtilx) return []; - const pinyins = lib.pinyins; - if (pinyins) { - const pinyin = pinyins[chinese]; - if (Array.isArray(pinyin)) return withTone === false ? pinyin.map(pinyinUtilx.removeTone) : pinyin.slice(); - } - return pinyinUtilx.getPinyin(chinese, null, withTone, true); - } - static yunmu(str) { - //部分整体认读音节特化处理 - const util = window.pinyinUtilx; - if (util && lib.pinyins._metadata.zhengtirendu.includes(util.removeTone(str))) { - return '-' + str[str.length - 1]; - } - //排除声母 - for (let i of lib.pinyins._metadata.shengmu) { - if (str.startsWith(i)) { - str = str.slice(i.length); - if (str[0] == 'u' && lib.pinyins._metadata.special_shengmu.includes(i)) str = 'ü' + str.slice(1); - break; - } - } - //排除介母 - if (str.length > 0) { - for (let i in lib.pinyins._metadata.feijiemu) { - if (str[0] == i) { - let goon = false; - for (let j of lib.pinyins._metadata.feijiemu[i]) { - if (str.startsWith(j)) goon = true; - } - if (!goon) str = str.slice(1); - break; - } - } - } - return str; - } - /** - * 用于将参数转换为字符串,作为缓存的key。 - */ - static paramToCacheKey() { - var str = ""; - for (var arg of arguments) { - if (arg === null || arg === undefined) { - str += (arg + "-"); - continue; - } - if (arg.playerid) { - str += "p:" + arg.playerid; - } else if (arg.cardid) { - str += "c:" + arg.cardid; - } else if (arg.name) { - str += "n:" + arg.name; - } else { - str += "s:" + arg; - } - str += "-"; - } - return str; - } - static yunjiao(str) { - const util = window.pinyinUtilx; - if (util) str = util.removeTone(str); - if (lib.pinyins._metadata.zhengtirendu.includes(str)) { - str = ('-' + str[str.length - 1]); - } - else { - for (let i of lib.pinyins._metadata.shengmu) { - if (str.startsWith(i)) { - str = str.slice(i.length); - if (str[0] == 'u' && lib.pinyins._metadata.special_shengmu.includes(i)) str = 'ü' + str.slice(1); - break; - } - } - } - for (let i in lib.pinyins._metadata.yunjiao) { - if (lib.pinyins._metadata.yunjiao[i].includes(str)) return i; - } - return null; - } - static skillCategoriesOf(skill, player) { - var list = [], info = get.info(skill); - if (!info) return list; - if (get.is.locked(skill, player)) list.add('锁定技'); - if (info.zhuSkill) list.add('主公技'); - if (info.limited) list.add('限定技'); - if (info.juexingji) list.add('觉醒技'); - if (info.zhuanhuanji) list.add('转换技'); - if (info.hiddenSkill) list.add('隐匿技'); - if (info.clanSkill) list.add('宗族技'); - if (info.groupSkill) list.add('势力技'); - if (info.dutySkill) list.add('使命技'); - if (info.chargeSkill) list.add('蓄力技'); - if (info.zhenfa) list.add('阵法技'); - if (info.mainSkill) list.add('主将技'); - if (info.viceSkill) list.add('副将技'); - if (info.lordSkill) list.add('君主技'); - if (info.chargingSkill) list.add('蓄能技'); - if (info.charlotte) list.add('Charlotte'); - if (info.sunbenSkill) list.add('昂扬技'); - if (info.categories) list.addArray(info.categories(skill, player)); - return list; - } - static numOf(obj, item) { return obj.filter(element => element == item).length; } - static connectNickname() { return typeof lib.config.connect_nickname == 'string' ? (lib.config.connect_nickname.slice(0, 12)) : "无名玩家"; } - static zhinangs(filter) { - var list = (_status.connectMode ? lib.configOL : lib.config).zhinang_tricks; - if (!list || !list.filter || !list.length) return get.inpile('trick', 'trick').randomGets(3); - if (filter === false) return list.slice(0); - list = list.filter(card => lib.inpile.includes(card)); - if (list.length) return list; - return get.inpile('trick', 'trick').randomGets(3); - } - static sourceCharacter(str) { - if (str) { - for (var i in lib.characterReplace) { - if (lib.characterReplace[i].includes(str)) return i; - } - } - return str; - } - static isLuckyStar(player) { - if (player && player.hasSkillTag('luckyStar')) return true; - if (_status.connectMode) return false; - return (!player || player == game.me || player.isUnderControl()) && lib.config.lucky_star == true; - } - static infoHp(hp) { - if (typeof hp == 'number') return hp; - else if (typeof hp == 'string' && hp.includes('/')) { - return parseInt(hp.split('/')[0]); - } - return 0; - } - static infoMaxHp(hp) { - if (typeof hp == 'number') return hp; - else if (typeof hp == 'string' && hp.includes('/')) { - return parseInt(hp.split('/')[1]); - } - return 0; - } - static infoHujia(hp) { - if (typeof hp == 'string' && hp.includes('/')) { - var splited = hp.split('/'); - if (splited.length > 2) return parseInt(splited[2]); - } - return 0; - } - static bottomCards(num, putBack) { - if (_status.waitingForCards) { - ui.create.cards.apply(ui.create, _status.waitingForCards); - delete _status.waitingForCards; - } - var list = []; - var card = false; - if (typeof num != 'number') num = 1; - if (num == 0) { card = true; num = 1; } - if (num < 0) num = 1; - while (num--) { - if (ui.cardPile.hasChildNodes() == false) { - game.washCard(); - } - if (ui.cardPile.hasChildNodes() == false) { - game.over('平局'); - return []; - } - var cardx = ui.cardPile.removeChild(ui.cardPile.lastChild); - cardx.original = 'c'; - list.push(cardx); - } - if (putBack) { - for (let i = list.length - 1; i >= 0; i--) { - ui.cardPile.appendChild(list[i]); - } - } - game.updateRoundNumber(); - if (card) return list[0]; - return list; - } - static discarded() { return _status.discarded.filter(item => item.parentNode == ui.discardPile); } - static cardOffset() { - var x = ui.arena.getBoundingClientRect(); - var y = ui.window.getBoundingClientRect(); - return -y.width / 2 + (x.left + x.width / 2); - } - static colorspan(str) { - if (str[0] == '#') { - var color; - switch (str[1]) { - case 'r': color = 'fire'; break; - case 'p': color = 'legend'; break; - case 'b': color = 'blue'; break; - case 'g': color = 'green'; break; - default: return str.slice(2); - } - return '' + str.slice(2) + ''; - } - return str; - } - static evtprompt(next, str) { - if (next.prompt) { - next.set('prompt2', str); - } - else { - if (str.startsWith('###')) { - var prompts = str.slice(3).split('###'); - if (prompts[0]) next.set('prompt', prompts[0]); - if (prompts[1]) next.set('prompt2', prompts[1]); - } - else { - next.set('prompt', str); - } - } - } - static autoViewAs(card, cards) { return new lib.element.VCard(card, cards); } - /** - * @deprecated - */ - static _autoViewAs(card, cards) { - var info = get.info(card); - if (info.autoViewAs) { - if (cards === false) { - return { - name: info.autoViewAs, - }; - } - else if (Array.isArray(cards)) { - return { - name: info.autoViewAs, - cards: cards.slice(0), - }; - } - else if (get.itemtype(card) == 'card') { - return { - name: info.autoViewAs, - cards: [card], - }; - } - else { - return { - name: info.autoViewAs, - suit: card.suit, - number: card.number, - nature: card.nature, - }; - } - } - else { - if (card.isCard || get.itemtype(card) == 'card') { - var next = { - name: get.name(card), - suit: get.suit(card), - number: get.number(card), - nature: get.nature(card), - isCard: true, - cardid: card.cardid, - wunature: card.wunature, - storage: get.copy(card.storage), - cards: get.copy(card.cards), - }; - if (get.itemtype(cards) == 'cards' && !card.cards) next.cards = cards.slice(0); - else if (get.itemtype(card) == 'card') next.cards = [card]; - return next; - } - else if (get.is.object(card) && get.itemtype(cards) == 'cards' && !card.cards) { - card = get.copy(card); - card.cards = cards.slice(0); - } - return card; - } - } - static max(list, func, type) { - list = list.slice(0); - if (typeof func == 'string') { - var key = func; - func = function (item) { - return item[key]; - }; - } - list.sort(function (a, b) { - return func(b) - func(a); - }); - if (type == 'list') { - var list2 = []; - for (var i = 0; i < list.length; i++) { - if (func(list[i]) == func(list[0])) { - list2.push(list[i]); - } - } - return list2; - } - else if (type == 'item') { - return list[0]; - } - else { - return func(list[0]); - } - } - static min(list, func, type) { - list = list.slice(0); - if (typeof func == 'string') { - var key = func; - func = function (item) { - return item[key]; - }; - } - list.sort(function (a, b) { - return func(a) - func(b); - }); - if (type == 'list') { - var list2 = []; - for (var i = 0; i < list.length; i++) { - if (func(list[i]) == func(list[0])) { - list2.push(list[i]); - } - } - return list2; - } - else if (type == 'item') { - return list[0]; - } - else { - return func(list[0]); - } - } - /** - * @overload - * @param { string } name - * @returns { Character } - */ - /** - * @template { 0 | 1 | 2 | 3 | 4 } T - * @overload - * @param { string } name - * @param { T } num - * @returns { Character[T] } - */ - static character(name, num) { - let info = lib.character[name]; - if (!info) { - const pack = Object.keys(lib.characterPack).find(pack => name in lib.characterPack[pack]); - if (pack) info = lib.characterPack[pack][name]; - } - if (typeof num === 'number') { - if (!info) info = []; - if (info[num]) return info[num]; - if (num === 3 || num === 4) return []; - return; - } - return info; - } - static characterIntro(name) { - if (lib.characterIntro[name]) return lib.characterIntro[name]; - var tags = get.character(name, 4); - if (tags) { - for (var i = 0; i < tags.length; i++) { - if (tags[i].startsWith('des:')) { - return tags[i].slice(4); - } - } - } - while (name.includes('_') && !lib.characterIntro[name]) { - name = name.slice(name.indexOf('_') + 1); - } - if (lib.characterIntro[name]) return lib.characterIntro[name]; - return '暂无武将介绍'; - } - static bordergroup(info, raw) { - if (!Array.isArray(info)) { - info = lib.character[info]; - if (!info) return ''; - } - if (Array.isArray(info[4])) for (const str of info[4]) { - if (typeof str == 'string' && str.startsWith('border:')) return str.slice(7); - } - return raw ? '' : info[1] || ''; - } - static groupnature(group, method) { - var nature = lib.groupnature[group]; - if (!nature) return ''; - if (method == 'raw') { - return nature; - } - return nature + 'mm'; - } - static sgn(num) { - if (num > 0) return 1; - if (num < 0) return -1; - return 0; - } - static rand(num, num2) { - if (typeof num2 == 'number') { - return num + Math.floor(Math.random() * (num2 - num + 1)); - } - else { - return Math.floor(Math.random() * num); - } - } - static sort(arr, method, arg) { return method == "seat" ? arr.sortBySeat(arg) : void 0; } - static sortSeat(arr, target) { return arr.sortBySeat(target); } - static zip(callback) { - if (!window.JSZip) { - lib.init.js(lib.assetURL + 'game', 'jszip', function () { - callback(new JSZip()); - }); - } - else { - callback(new JSZip()); - } - } - static delayx(num, max) { - if (typeof num != 'number') num = 1; - if (typeof max != 'number') max = Infinity; - switch (lib.config.game_speed) { - case 'vslow': return Math.min(max, 2.5 * num); - case 'slow': return Math.min(max, 1.5 * num); - case 'fast': return Math.min(max, 0.7 * num); - case 'vfast': return Math.min(max, 0.4 * num); - case 'vvfast': return Math.min(max, 0.2 * num); - default: return Math.min(max, num); - } - } - static prompt(skill, target, player) { - player = player || _status.event.player; - if (target) { - var str = get.translation(target); - if (target == player) { - str += '(你)'; - } - return '是否对' + str + '发动【' + get.skillTranslation(skill, player) + '】?'; - } - else { - return '是否发动【' + get.skillTranslation(skill, player) + '】?'; - } - } - static prompt2(skill, target, player) { - var str = get.prompt.apply(this, arguments); - if (!lib.translate[skill + '_info']) return str; - return '###' + str + '###' + lib.translate[skill + '_info']; - } - static url(master) { - var url = lib.config.updateURL || lib.updateURL; - if (url[url.length - 1] != '/') { - url += '/'; - } - if (master != 'nodev') { - return url + 'master/'; - } - else { - return url + 'v' + lib.version + '/'; - } - } - static round(num, f) { - var round = Math.pow(10, f); - return Math.round(num * round) / round; - } - static playerNumber() { - var num; - if (_status.brawl && _status.brawl.playerNumber) { - num = _status.brawl.playerNumber; - } - else { - num = get.config('player_number'); - } - return parseInt(num) || 2; - } - static benchmark(func1, func2, iteration, arg) { - var tic, toc; - var key1, key2; - if (!arg) arg = []; - if (Array.isArray(func2)) { - key1 = func2[0]; - key2 = func2[1]; - } - else if (typeof func2 == 'string') { - key1 = func2; - func2 = iteration || 100; - } - else if (typeof func2 == 'number') { - arg = iteration || arg; - iteration = func2; - } - tic = get.utc(); - for (var i = 0; i < iteration; i++) { - if (key1) { - func1[key1](arg.randomGet()); - } - else { - func1(arg.randomGet()); - } - } - toc = get.utc(); - if (typeof func2 == 'number') { - return toc - tic; - } - console.log('time1: ' + (toc - tic)); - tic = get.utc(); - for (var i = 0; i < iteration; i++) { - if (key2) { - func1[key2](arg.randomGet()); - } - else { - func2(arg.randomGet()); - } - } - toc = get.utc(); - console.log('time2: ' + (toc - tic)); - } - static stringify(obj, level) { - level = level || 0; - var indent = ''; - var str; - for (var i = 0; i < level; i++) { - indent += ' '; - } - if (get.objtype(obj) == 'object') { - str = '{\n'; - for (var i in obj) { - var insertDefaultString; - var insertFunctionString = indent + ' ' + get.stringify(obj[i], level + 1) + ',\n'; - var parseFunction = i => { - var string = obj[i].toString(); - var execResult; - if (obj[i] instanceof GeneratorFunction) { - // *content(){} - execResult = new RegExp(`\\*\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]); - if (execResult && execResult.index === 0) { - return insertFunctionString; - } - // content:function*(){} - else { - return insertDefaultString; - } - } - else if (obj[i] instanceof AsyncFunction) { - execResult = new RegExp(`async\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]); - // async content(){} - if (execResult && execResult.index === 0) { - return insertFunctionString; - } - // content:async function(){} - else { - return insertDefaultString; - } - } else { - execResult = new RegExp(`${i}[\\s\\S]*?\\(`).exec(obj[i]); - // content(){} - if (execResult && execResult.index === 0) { - return insertFunctionString; - } - // content:function(){} - else { - return insertDefaultString; - } - } - }; - if (/[^a-zA-Z]/.test(i)) { - insertDefaultString = indent + ' "' + i + '":' + get.stringify(obj[i], level + 1) + ',\n'; - if (typeof obj[i] !== 'function') { - str += insertDefaultString; - } else { - str += parseFunction(i); - } - } - else { - insertDefaultString = indent + ' ' + i + ':' + get.stringify(obj[i], level + 1) + ',\n'; - if (typeof obj[i] !== 'function') { - str += insertDefaultString; - } else { - str += parseFunction(i); - } - } - } - str += indent + '}'; - return str; - } - else { - if (typeof obj == 'function') { - str = obj.toString(); - str = str.replace(/\t/g, ' '); - var i = str.lastIndexOf('\n'); - var num = 0; - for (var j = i + 1; j < str.length && str[j] == ' '; j++) { - num++; - } - num = Math.floor(num / 4); - for (i = 0; i < num - level; i++) { - str = str.replace(/\n {4}/g, '\n'); - } - } - else { - try { - if (Array.isArray(obj) && obj.includes(Infinity)) { - obj = obj.slice(0); - var rand = get.id(); - for (var i = 0; i < obj.length; i++) { - if (obj[i] === Infinity) { - obj[i] = parseInt(rand); - } - } - str = JSON.stringify(obj).replace(new RegExp(rand, 'g'), 'Infinity'); - } - else { - str = JSON.stringify(obj) || ''; - } - } - catch (e) { - str = ''; - } - } - return str; - } - } - /** - * 深拷贝函数(虽然只处理了部分情况) - * - * 除了普通的Object和NullObject,均不考虑自行赋值的数据,但会原样将Symbol复制过去 - * - * @template T - * @param {T} obj - 要复制的对象,若不是对象则直接返回原值 - * @param {WeakMap} [map] - 拷贝用的临时存储,用于处理循环引用(请勿自行赋值) - * @returns {T} - 深拷贝后的对象,若传入值不是对象则为传入值 - */ - static copy(obj, map = new WeakMap()) { - // 参考[这里](https://juejin.cn/post/7315612852890026021)实现深拷贝 - // 不再判断是否能structuredClone是因为structuredClone会把Symbol给毙了 - const getType = (obj) => Object.prototype.toString.call(obj); - - const canTranverse = { - "[object Map]": true, - "[object Set]": true, - "[object Object]": true, - "[object Array]": true, - "[object Arguments]": true, - }; - - if (typeof obj !== "object" || obj === null) - return obj; - - // @ts-ignore - if (map.has(obj)) return map.get(obj); - - const constructor = obj.constructor; - let target; - if (!canTranverse[getType(obj)]) { - target = obj; - return target; - } - // @ts-ignore - else target = constructor ? new constructor(target) : Object.create(null); - map.set(obj, target); - - if (obj instanceof Map) { - obj.forEach((value, key) => { - target.set(get.copy(key, map), get.copy(value, map)); - }); - } else if (obj instanceof Set) { - obj.forEach((value) => { - target.add(get.copy(value, map)); - }); - } - - const descriptors = Object.getOwnPropertyDescriptors(obj); - if (descriptors) { - for (const [key, descriptor] of Object.entries(descriptors)) { - const { enumerable, configurable } = descriptor; - if (obj.hasOwnProperty(key)) { - const result = { enumerable, configurable }; - if (descriptor.hasOwnProperty('value')) { - result.value = get.copy(descriptor.value, map); - result.writable = descriptor.writable; - } else { - const { get, set } = descriptor; - result.get = get; - result.set = set; - } - Reflect.defineProperty(target, key, result); - } - } - } - - const symbols = Object.getOwnPropertySymbols(obj); - symbols.forEach((symbol) => { - target[symbol] = get.copy(obj[symbol], map); - }); - - return target; - } - static inpilefull(type) { - var list = []; - for (var i in lib.cardPile) { - for (var j = 0; j < lib.cardPile[i].length; j++) { - var info = lib.cardPile[i][j]; - if (lib.inpile.includes(info[2]) && get.type(info[2]) == type) { - list.push({ - name: info[2], - suit: info[0], - number: info[1], - nature: info[3] - }); - } - } - } - return list; - } - static inpile(type, filter) { - var list = []; - if (filter == 'trick') { - for (var i = 0; i < lib.inpile.length; i++) { - if (get.type(lib.inpile[i], 'trick') == type) list.push(lib.inpile[i]); - } - } - else { - for (var i = 0; i < lib.inpile.length; i++) { - if (typeof type == 'function') { - if (type(lib.inpile[i])) { - list.push(lib.inpile[i]); - } - } - else { - if (typeof filter == 'function' && !filter(lib.inpile[i])) continue; - if (type.startsWith('equip') && type.length == 6) { - if (get.subtype(lib.inpile[i]) == type) list.push(lib.inpile[i]); - } - else { - if (get.type(lib.inpile[i]) == type) list.push(lib.inpile[i]); - } - } - } - } - return list; - } - static inpile2(type) { return get.inpile(type, 'trick'); } - static typeCard(type, filter) { - var list = []; - for (var i in lib.card) { - if (lib.card[i].mode && lib.card[i].mode.includes(get.mode()) == false) continue; - // if(lib.card[i].vanish||lib.card[i].destroy) continue; - if (lib.card[i].destroy) continue; - if (typeof filter == 'function' && !filter(i)) continue; - if (lib.config.bannedcards.includes(i)) continue; - if (!lib.translate[i + '_info']) continue; - if ((type.startsWith('equip') && type.length == 6) || - (type.startsWith('hslingjian') && type.length == 11) || - (type.startsWith('spell_'))) { - if (get.subtype(i) == type) list.push(i); - } - else { - if (get.type(i) == type) list.push(i); - } - } - return list; - } - static libCard(filter) { - var list = []; - for (var i in lib.card) { - if (lib.card[i].mode && lib.card[i].mode.includes(get.mode()) == false) continue; - // if(lib.card[i].vanish||lib.card[i].destroy) continue; - if (lib.card[i].destroy) continue; - if (lib.config.bannedcards.includes(i)) continue; - if (!lib.translate[i + '_info']) continue; - if (filter(lib.card[i], i)) { - list.push(i); - } - } - return list; - } - static ip() { - if (!require) return ''; - var interfaces = require('os').networkInterfaces(); - for (var devName in interfaces) { - var iface = interfaces[devName]; - for (var i = 0; i < iface.length; i++) { - var alias = iface[i]; - if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { - return alias.address; - } - } - } - } - static modetrans(config, server) { - if (config.mode == 'doudizhu') { - switch (config.doudizhu_mode) { - case 'kaihei': return '开黑斗地主'; - case 'huanle': return '欢乐斗地主'; - case 'binglin': return '兵临城下'; - case 'online': return '智斗三国'; - default: return '休闲' + (config.double_character ? '双将' : '') + '斗地主'; - } - } - if (config.mode == 'versus') { - switch (config.versus_mode) { - case '1v1': return '单人对决'; - case '2v2': return '欢乐成双'; - case '3v3': return '血战到底'; - case '4v4': return '四人对决'; - case 'guandu': return '官渡之战'; - } - } - if (config.mode == 'single') { - switch (config.single_mode) { - case 'normal': return '新1v1'; - case 'changban': return '血战长坂坡'; - case 'dianjiang': return '点将单挑'; - } - } - if (config.mode == 'identity') { - switch (config.identity_mode) { - case 'purple': return '三对三对二'; - case 'zhong': return (config.double_character ? '双将' : '') + '忠胆英杰'; - case 'stratagem': return get.cnNumber(parseInt(config.number)) + '人' + (config.double_character ? '双将' : '') + '谋攻'; - default: return `${get.cnNumber(parseInt(config.number))}人${config.double_nei ? '双内' : ''}${config.enable_commoner ? '带民' : ''}${config.double_character ? '双将' : ''}身份`; - } - } - if (config.mode == 'guozhan') { - if (config.separatism) return '群雄割据'; - if (config.guozhan_mode != 'normal') switch (config.guozhan_mode) { - case 'yingbian': return '应变国战'; - case 'old': return '怀旧国战'; - } - } - if (server) { - return get.translation(config.mode) + '模式'; - } - else { - return get.cnNumber(parseInt(config.number)) + '人' + get.translation(config.mode); - } - } - static charactersOL(func) { - var list = []; - var libCharacter = {}; - for (var i = 0; i < lib.configOL.characterPack.length; i++) { - var pack = lib.characterPack[lib.configOL.characterPack[i]]; - for (var j in pack) { - if (typeof func == 'function' && func(j)) continue; - if (lib.connectBanned.includes(j)) continue; - if (lib.character[j]) libCharacter[j] = pack[j]; - } - } - for (i in libCharacter) { - if (lib.filter.characterDisabled(i, libCharacter)) continue; - list.push(i); - } - return list; - } - static trimip(str) { - var len = str.length - 5; - if (str.lastIndexOf(':8080') == len) { - str = str.slice(0, len); - } - return str; - } - static mode() { return lib[_status.connectMode ? 'configOL' : 'config'].mode; } - static idDialog(id) { return ui.dialogs.find(dialog => dialog.videoId == id) || null; } - static arenaState() { - var state = { - number: ui.arena.dataset.number, - players: {}, - mode: _status.mode, - dying: _status.dying, - servermode: window.isNonameServer, - roomId: game.roomId, - over: _status.over, - inpile: lib.inpile, - inpile_nature: lib.inpile_nature, - renku: _status.renku, - }; - for (var i in lib.playerOL) { - state.players[i] = lib.playerOL[i].getState(); - } - return state; - } - static skillState(player) { - var skills = { - global: lib.skill.global - }; - var skillinfo = {}; - for (var i in lib.playerOL) { - skills[i] = { - skills: lib.playerOL[i].skills, - hiddenSkills: lib.playerOL[i].hiddenSkills, - invisibleSkills: lib.playerOL[i].invisibleSkills, - additionalSkills: lib.playerOL[i].additionalSkills, - disabledSkills: lib.playerOL[i].disabledSkills, - tempSkills: lib.playerOL[i].tempSkills, - storage: lib.playerOL[i].storage, - }; - } - //for(var i in lib.skill){ - // if(lib.skill[i].chooseButton&&lib.skill[i].enable){ - // skillinfo[i]=lib.skill[i].chooseButton; - // } - //} - skills.skillinfo = skillinfo; - if (player) { - skills.stat = player.getStat(); - } - return skills; - } - static id() { return (Math.floor(1000000 + 9000000 * Math.random())).toString() + (10 + lib.status.globalId++); } - static zhu(player, skill, group) { - if (typeof player == 'string') { - skill = player; - player = null; - } - var mode = get.mode(); - if (mode == 'identity') { - if (_status.mode == 'purple') { - if (!player) return null; - var zhu = game[player.identity.slice(0, 1) + 'Zhu']; - if (!zhu) return null; - if (skill && !zhu.hasSkill(skill)) return null; - return zhu; - } - if (!game.zhu) return null; - if (skill && !game.zhu.hasSkill(skill)) return null; - if (game.zhu.isZhu) return game.zhu; - } - else if (mode == 'versus' && (_status.mode == 'four' || _status.mode == 'guandu')) { - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isZhu) { - if (skill && !(game.players[i].hasSkill(skill))) continue; - if (!player) return game.players[i]; - if (player.side == game.players[i].side) { - return game.players[i]; - } - } - } - } - else if (mode == 'guozhan') { - for (var i = 0; i < game.players.length; i++) { - if (get.is.jun(game.players[i]) && !game.players[i].isUnseen()) { - if (skill && !game.players[i].hasSkill(skill)) continue; - if (!player) return game.players[i]; - if (player.identity == game.players[i].identity) { - return game.players[i]; - } - else if (group && group == game.players[i].identity) { - return game.players[i]; - } - } - } - } - return null; - } - static config(item, mode) { - mode = mode || lib.config.mode; - if (!lib.config.mode_config[mode]) return; - return lib.config.mode_config[mode][item]; - } - static coinCoeff(list) { - var num = 0; - for (var i = 0; i < list.length; i++) { - var rank = get.rank(list[i]); - switch (rank) { - case 'sp': return 0.1; - case 's': num += 0.4; break; - case 'ap': num += 0.6; break; - case 'a': num += 0.8; break; - case 'am': num += 0.95; break; - case 'bp': num += 1.05; break; - case 'b': num += 1.2; break; - case 'bm': num += 1.4; break; - case 'c': num += 1.6; break; - case 'd': num += 1.8; break; - } - } - return num / list.length; - } - static rank(name, num) { - if (typeof name == 'object' && name.name) { - name = name.name; - } - if (num == true) num = 9; - if (typeof num != 'number') num = false; - if (name == _status.lord) return num ? Math.round(7 * (num - 1) / 8 + 1) : 'ap'; - var rank = lib.rank; - if (lib.characterPack.standard[name] || lib.characterPack.shenhua[name]) { - var skills; - if (lib.character[name]) { - skills = lib.character[name][3]; - } - else { - var tmpinfo = get.character(name); - if (tmpinfo) { - skills = tmpinfo[3]; - } - else { - skills = []; - } - } - for (var i = 0; i < skills.length; i++) { - if (skills[i].alter && !lib.config.vintageSkills.includes(skills[i])) { - name = lib.rank.a[0]; break; - } - } - } - if (rank.s.includes(name)) return num ? Math.round(8 * (num - 1) / 8 + 1) : 's'; - if (rank.ap.includes(name)) return num ? Math.round(7 * (num - 1) / 8 + 1) : 'ap'; - if (rank.a.includes(name)) return num ? Math.round(6 * (num - 1) / 8 + 1) : 'a'; - if (rank.am.includes(name)) return num ? Math.round(5 * (num - 1) / 8 + 1) : 'am'; - if (rank.bp.includes(name)) return num ? Math.round(4 * (num - 1) / 8 + 1) : 'bp'; - if (rank.b.includes(name)) return num ? Math.round(3 * (num - 1) / 8 + 1) : 'b'; - if (rank.bm.includes(name)) return num ? Math.round(2 * (num - 1) / 8 + 1) : 'bm'; - if (rank.c.includes(name)) return num ? Math.round(1 * (num - 1) / 8 + 1) : 'c'; - if (rank.d.includes(name)) return num ? Math.round(0 * (num - 1) / 8 + 1) : 'd'; - if (lib.character[name] && lib.character[name][4]) { - if (lib.character[name][4].includes('boss') || - lib.character[name][4].includes('bossallowed') || - lib.character[name][4].includes('hiddenboss')) { - return num ? Math.round(9 * (num - 1) / 8 + 1) : 'sp'; - } - } - return num ? Math.round(9 * (num - 1) / 8 + 1) : 'x'; - } - static skillRank(skill, type, grouped) { - var info = lib.skill[skill]; - var player = _status.event.skillRankPlayer || _status.event.player; - if (!info) return 0; - if (info.ai) { - if (info.ai.halfneg) return 0; - if (typeof info.ai.combo == 'string' && player && !player.hasSkill(info.ai.combo)) { - return 0; - } - if (info.ai.neg) return -1; - } - var num = 1; - var threaten = 1; - if (info.ai && info.ai.threaten) { - if (typeof info.ai.threaten == 'number') { - threaten = info.ai.threaten; - } - else if (typeof info.ai.threaten == 'function' && player) { - threaten = info.ai.threaten(player, player); - } - } - if (type && type.includes('in')) { - if (info.enable == 'phaseUse') num += 0.5; - if (info.trigger && info.trigger.player) { - var list = Array.isArray(info.trigger.player) ? info.trigger.player : [info.trigger.player]; - var add = false; - for (var i of list) { - if (i.startsWith('phase')) { - num += 0.5; - add = true; - } - else { - for (var j of lib.phaseName) { - if (i.indexOf[j] == 0) { - num += 0.5; - add = true; - break; - } - } - } - if (add) break; - } - } - if (info.trigger && ((typeof info.trigger.player == 'string' && info.trigger.player.startsWith('use')) || info.trigger.source)) { - num += 0.3; - } - if (num > 1 && threaten > 1) { - num += Math.sqrt(threaten) - 1; - } - } - if (type && type.includes('out')) { - if (threaten < 1) { - num *= 1 / Math.sqrt(threaten); - } - if (info.trigger) { - if (info.trigger.global) { - var list = Array.isArray(info.trigger.global) ? info.trigger.global : [info.trigger.global]; - num += Math.min(3, list.length) / 10; - for (var i of list) { - if (i.startsWith('lose') || i.startsWith('use')) num += 0.3; - if (i.startsWith('cardsDiscard')) num += 0.4; - } - } - if (info.trigger.target || (typeof info.trigger.player == 'string' && - (info.trigger.player.startsWith('damage') || info.trigger.player.startsWith('lose')))) num += 0.1; - } - if (info.ai) { - if (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend) { - num += 0.5; - } - if (info.ai.nolose || info.ai.noh || info.ai.noe || info.ai.nodiscard) { - num += 0.3; - } - } - } - if (!grouped) { - var groups = game.expandSkills([skill]); - groups.remove(skill); - var ggt = []; - for (var i = 0; i < groups.length; i++) { - var gi = get.skillRank(groups[i], type, true); - if (gi < 0) { - num -= 0.5; - } - else if (gi > 1) { - ggt.push(gi); - } - } - if (ggt.length) { - num += Math.max.apply(this, ggt) - 1 + ggt.length / 20; - } - } - return num; - } - static targetsInfo(targets) { - var info = []; - for (var i = 0; i < targets.length; i++) { - info.push(targets[i].dataset.position); - } - return info; - } - static infoTargets(infos) { return Array.from(infos || []).map(info => game.playerMap[info]); } - static cardInfo(card) { return [card.suit, card.number, card.name, card.nature]; } - static cardsInfo(cards) { return Array.from(cards || []).map(get.cardInfo); } - static infoCard(info) { - var card = ui.create.card(); - if (info[0]) { - card.init(info); - } - return card; - } - static infoCards(infos) { return Array.from(infos || []).map(get.infoCard); } - static cardInfoOL(card) { return '_noname_card:' + JSON.stringify([card.cardid, card.suit, card.number, card.name, card.nature]); } - static infoCardOL(info) { - if (!lib.cardOL) return info; - var card; - try { - var info = JSON.parse(info.slice(13)); - var id = info.shift(); - if (!id) { - card = ui.create.card(); - if (info && info[2]) card.init(info); - } - else if (lib.cardOL[id]) { - if (lib.cardOL[id].name != info[2]) { - if (info && info[2]) lib.cardOL[id].init(info); - } - card = lib.cardOL[id]; - } - else if (game.online) { - card = ui.create.card(); - card.cardid = id; - if (info && info[2]) card.init(info); - lib.cardOL[id] = card; - } - } - catch (e) { - console.log(e); - } - return card || info; - } - static cardsInfoOL(cards) { return Array.from(cards || []).map(get.cardInfoOL); } - static infoCardsOL(infos) { return Array.from(infos || []).map(get.infoCardOL); } - static playerInfoOL(player) { return '_noname_player:' + player.playerid; } - static infoPlayerOL(info) { return lib.playerOL ? (lib.playerOL[info.slice(15)] || info) : info; } - static playersInfoOL(players) { return Array.from(players || []).map(get.playerInfoOL); } - static infoPlayersOL(infos) { return Array.from(infos || []).map(get.infoPlayerOL); } - static funcInfoOL(func) { - if (typeof func == 'function') { - if (func._filter_args) { - return '_noname_func:' + JSON.stringify(get.stringifiedResult(func._filter_args, 3)); - } - return '_noname_func:' + func.toString(); - } - return ''; - } - static infoFuncOL(info) { - var func; - try { - eval('func=(' + info.slice(13) + ');'); - } - catch (e) { - return function () { }; - } - if (Array.isArray(func)) { - func = get.filter.apply(this, get.parsedResult(func)); - } - return func; - } - static eventInfoOL(item, level, noMore) { - return get.itemtype(item) == 'event' ? `_noname_event:${JSON.stringify(Object.entries(item).reduce((stringifying, entry) => { - const key = entry[0]; - if (key == '_trigger') { - if (noMore !== false) stringifying[key] = get.eventInfoOL(entry[1], null, false); - } - else if (!lib.element.GameEvent.prototype[key] && key != 'content' && get.itemtype(entry[1]) != 'event') stringifying[key] = get.stringifiedResult(entry[1], null, false); - return stringifying; - }, {}))}` : ''; - } - /** - * @param {string} item - */ - static infoEventOL(item) { - const evt = new lib.element.GameEvent(); - try { - Object.entries(JSON.parse(item.slice(14))).forEach(entry => { - const key = entry[0]; - if (typeof evt[key] != 'function') evt[key] = get.parsedResult(entry[1]); - }); - } - catch (error) { - console.log(error); - } - return evt || item; - } - static stringifiedResult(item, level, nomore) { - if (!item) return item; - if (typeof item == 'function') { - return get.funcInfoOL(item); - } - else if (typeof item == 'object') { - switch (get.itemtype(item)) { - case 'card': return get.cardInfoOL(item); - case 'cards': return get.cardsInfoOL(item); - case 'player': return get.playerInfoOL(item); - case 'players': return get.playersInfoOL(item); - case 'event': - if (nomore === false) return ''; - return get.eventInfoOL(item); - default: - if (typeof level != 'number') { - level = 8; - } - if (Array.isArray(item)) { - if (level == 0) { - return []; - } - var item2 = []; - for (var i = 0; i < item.length; i++) { - item2.push(get.stringifiedResult(item[i], level - 1, nomore)); - } - return item2; - } - else if (Object.prototype.toString.call(item) == '[object Object]') { - if (level == 0) { - return {}; - } - var item2 = {}; - for (var i in item) { - item2[i] = get.stringifiedResult(item[i], level - 1, nomore); - } - return item2; - } - else { - return {}; - } - } - } - else if (item === Infinity) { - return '_noname_infinity'; - } - else { - return item; - } - } - static parsedResult(item) { - if (!item) return item; - if (typeof item == 'string') { - if (item.startsWith('_noname_func:')) { - return get.infoFuncOL(item); - } - else if (item.startsWith('_noname_card:')) { - return get.infoCardOL(item); - } - else if (item.startsWith('_noname_player:')) { - return get.infoPlayerOL(item); - } - else if (item.startsWith('_noname_event:')) { - return get.infoEventOL(item); - } - else if (item == '_noname_infinity') { - return Infinity; - } - else { - return item; - } - } - else if (Array.isArray(item)) { - var item2 = []; - for (var i = 0; i < item.length; i++) { - item2.push(get.parsedResult(item[i])); - } - return item2; - } - else if (typeof item == 'object') { - var item2 = {}; - for (var i in item) { - item2[i] = get.parsedResult(item[i]); - } - return item2; - } - else { - return item; - } - } - static verticalStr(str, sp) { - if (typeof str != 'string') return ''; - return Array.from(str).filter(value => value != '`').join(''); - } - static numStr(num, method) { - if (num == Infinity) { - if (method == 'card') return get.selectableCards().length + ui.selected.cards.length; - if (method == 'target') return get.selectableTargets().length + ui.selected.targets.length; - return '∞'; - } - return num.toString(); - } - static rawName(str) { - let str2 = lib.translate[str]; - if (lib.translate[str + '_ab']) str2 = lib.translate[str + '_ab']; - if (!str2) return ''; - if (lib.translate[str + '_prefix'] && str2.startsWith(lib.translate[str + '_prefix'])) { - return str2.slice(lib.translate[str + '_prefix'].length); - } - return str2; - } - /** - * 作用修改:只读前缀 不读_ab - */ - static rawName2(str) { - let str2 = lib.translate[str]; - if (!str2) return ''; - if (lib.translate[str + '_prefix'] && str2.startsWith(lib.translate[str + '_prefix'])) { - return str2.slice(lib.translate[str + '_prefix'].length); - } - return str2; - } - static slimNameHorizontal(str) { - const slimName = lib.translate[`${str}_ab`] || lib.translate[str]; - if (!slimName) return ''; - const prefix = lib.translate[`${str}_prefix`]; - if (prefix && slimName.startsWith(prefix)) { - //兼容版特化处理 - if (lib.compatibleEdition) return `${get.prefixSpan(prefix, str)}${slimName.slice(prefix.length)} `; - return `${get.prefixSpan(prefix, str)}${slimName.slice(prefix.length)}`; - } - return slimName; - } - /** - * @param {string} prefix - * @param {string} name - * @returns {string} - */ - static prefixSpan(prefix, name) { - const config = lib.config.buttoncharacter_prefix; - if (config == 'off') return ''; - if (config == 'simple') { - const span = document.createElement('span'); - span.innerHTML = prefix; - return span.outerHTML; - } - const namePrefix = lib.namePrefix.get(prefix), exists = Boolean(namePrefix); - if (exists && 'getSpan' in namePrefix) return namePrefix.getSpan(prefix, name); - const span = document.createElement('span'); - if (exists) { - if ('color' in namePrefix) span.style.color = namePrefix.color; - if ('nature' in namePrefix) span.dataset.nature = namePrefix.nature; - if ('showName' in namePrefix) prefix = namePrefix.showName; - } - else span.style.color = '#ffffff'; - span.innerHTML = prefix; - return span.outerHTML; - } - static slimName(str) { return get.verticalStr(get.slimNameHorizontal(str), true); } - static time() { - if (lib.status.dateDelaying) { - return lib.getUTC(lib.status.dateDelaying) - lib.getUTC(lib.status.date) - lib.status.dateDelayed; - } - else { - return lib.getUTC(new Date()) - lib.getUTC(lib.status.date) - lib.status.dateDelayed; - } - } - static utc() { return (new Date()).getTime(); } - static evtDistance(e1, e2) { - var dx = (e1.clientX - e2.clientX) / game.documentZoom; - var dy = (e1.clientY - e2.clientY) / game.documentZoom; - return Math.sqrt(dx * dx + dy * dy); - } - static xyDistance(from, to) { return Math.sqrt((from[0] - to[0]) * (from[0] - to[0]) + (from[1] - to[1]) * (from[1] - to[1])); } - /** - * @overload - * @returns { void } - */ - /** - * @overload - * @param { string } obj - * @returns { 'position' | 'natures' | 'nature' } - */ - /** - * @overload - * @param { Player[] } obj - * @returns { 'players' } - */ - /** - * @overload - * @param { Card[] } obj - * @returns { 'cards' } - */ - /** - * @overload - * @param { [number, number] } obj - * @returns { 'select' } - */ - /** - * @overload - * @param { [number, number, number, number] } obj - * @returns { 'divposition' } - */ - /** - * @overload - * @param { Button } obj - * @returns { 'button' } - */ - /** - * @overload - * @param { Card } obj - * @returns { 'card' } - */ - /** - * @overload - * @param { Player } obj - * @returns { 'player' } - */ - /** - * @overload - * @param { Dialog } obj - * @returns { 'dialog' } - */ - /** - * @overload - * @param { GameEvent | GameEventPromise } obj - * @returns { 'event' } - */ - static itemtype(obj) { - if (typeof obj == 'string') { - if (obj.length <= 5) { - let bool = true; - for (let i = 0; i < obj.length; i++) { - if (/h|e|j|s|x/.test(obj[i]) == false) { - bool = false; break; - } - } - if (bool) return 'position'; - } - if (obj.includes(lib.natureSeparator) && obj.split(lib.natureSeparator).every(n => lib.nature.has(n))) return 'natures'; - if (lib.nature.has(obj)) return 'nature'; - } - if (Array.isArray(obj) && obj.length > 0) { - if (obj.every(p => p instanceof lib.element.Player)) return 'players'; - if (obj.every(p => p instanceof lib.element.Card)) return 'cards'; - if (obj.length == 2) { - if (typeof obj[0] == 'number' && typeof obj[1] == 'number') { - if (obj[0] <= obj[1] || obj[1] <= -1) return 'select'; - } - } - if (obj.length == 4) { - if (obj.every(p => typeof p == 'number')) { - return 'divposition'; - } - } - } - if (obj instanceof lib.element.Button || (obj instanceof HTMLDivElement && obj.classList.contains('button'))) return 'button'; - if (obj instanceof lib.element.Card) return 'card'; - if (obj instanceof lib.element.Player) return 'player'; - if (obj instanceof lib.element.Dialog) return 'dialog'; - if (obj instanceof lib.element.GameEvent || - obj instanceof lib.element.GameEventPromise) return 'event'; - } - static equipNum(card) { - if (get.type(card) == 'equip') { - return parseInt(get.subtype(card)[5]); - } - return 0; - } - static objtype(obj) { - if (Object.prototype.toString.call(obj) === '[object Array]') return 'array'; - if (Object.prototype.toString.call(obj) === '[object Object]') return 'object'; - if (Object.prototype.toString.call(obj) === '[object HTMLDivElement]') return 'div'; - if (Object.prototype.toString.call(obj) === '[object HTMLTableElement]') return 'table'; - if (Object.prototype.toString.call(obj) === '[object HTMLTableRowElement]') return 'tr'; - if (Object.prototype.toString.call(obj) === '[object HTMLTableCellElement]') return 'td'; - if (Object.prototype.toString.call(obj) === '[object HTMLBodyElement]') return 'td'; - if (Object.prototype.toString.call(obj) === '[object DocumentFragment]') return 'fragment'; - } - static type(obj, method, player) { - if (typeof obj == 'string') obj = { name: obj }; - if (typeof obj != 'object') return; - var name = get.name(obj, player); - if (!lib.card[name]) { - if (!name.startsWith('sha_')) return; - if (name.slice(4).split('_').every(n => lib.nature.has(n))) return lib.card['sha'].type; - } - if (method == 'trick' && lib.card[name].type == 'delay') return 'trick'; - return lib.card[name].type; - } - static type2(card, player) { return get.type(card, 'trick', player); } - static subtype(obj, player) { - if (typeof obj == 'string') obj = { name: obj }; - if (typeof obj != 'object') return; - const name = get.name(obj, player); - if (!lib.card[name]) return; - let subtype = lib.card[name].subtype; - return subtype; - } - static equiptype(card, player) { - var subtype = get.subtype(card, player); - if (subtype.startsWith('equip')) return parseInt(subtype[5]); - return 0; - } - /** - * - * @param {Card | VCard} card - * @param {false | Player} [player] - * @returns {string} - */ - static name(card, player) { - if (get.itemtype(player) == 'player' || (player !== false && get.position(card) == 'h')) { - var owner = player || get.owner(card); - if (owner) { - return game.checkMod(card, owner, card.name, 'cardname', owner); - } - } - return card.name; - } - /** - * @param {Card | VCard | Card[] | VCard[]} card - * @param {false | Player} [player] - * @returns {string} - */ - static suit(card, player) { - if (!card) return; - if (Array.isArray(card)) { - if (card.length == 1) return get.suit(card[0], player); - return 'none'; - } - else if (!('suit' in card) && Array.isArray(card.cards)) { - return get.suit(card.cards, player); - } - else { - if (player !== false) { - const owner = player || get.owner(card); - if (owner) { - return game.checkMod(card, owner, game.checkMod(card, card.suit, 'suit', owner), 'cardsuit', owner); - } - } - if (lib.suits.includes(card.suit)) return card.suit; - return 'none'; - } - } - /** - * @param {Card | VCard | Card[] | VCard[]} card - * @param {false | Player} [player] - * @returns {string} - */ - static color(card, player) { - if (!card) return; - if (Array.isArray(card)) { - if (!card.length) return 'none'; - const cards = card.slice(), color = get.color(cards.shift(), player); - for (const anotherCard of cards) { - if (get.color(anotherCard, player) != color) return 'none'; - } - return color; - } - else if (Object.keys(lib.color).includes(card.color)) { - return card.color; - } - else if (Array.isArray(card.cards) && !lib.suit.includes(card.suit)) { - return get.color(card.cards, player); - } - else { - const suit = get.suit(card, player); - for (const entry of Object.entries(lib.color)) { - if (entry[1].includes(suit)) return entry[0]; - } - return 'none'; - } - } - /** - * @param {Card | VCard} card - * @param {false | Player} [player] - * @returns {number} - */ - static number(card, player) { - if (!card) return; - //狗卡你是真敢出啊 - var number = null; - if ('number' in card) { - number = card.number; - if (typeof number != 'number') number = null; - } - else { - if (card.cards && card.cards.length == 1) number = get.number(card.cards[0], false); - } - if (player !== false) { - var owner = player || get.owner(card); - if (owner) { - return game.checkMod(card, owner, number, 'cardnumber', owner); - } - } - return number; - } - /** - * 返回一张杀的属性。如有多种属性则用`lib.natureSeparator`分割开来。例:火雷【杀】的返回值为`fire|thunder` - * @param {string | string[] | Card | VCard} card - * @param {false | Player} [player] - * @returns {string} - */ - static nature(card, player) { - if (typeof card == 'string') return card.split(lib.natureSeparator).sort(lib.sort.nature).join(lib.natureSeparator); - if (Array.isArray(card)) return card.sort(lib.sort.nature).join(lib.natureSeparator); - var nature = card.nature; - if (get.itemtype(player) == 'player' || player !== false) { - var owner = get.owner(card); - if (owner) { - return game.checkMod(card, owner, nature, 'cardnature', owner); - } - } - return nature; - } - /** - * 返回包含所有属性的数组 - * @param {string[] | string} card - * @param {false | Player} [player] - * @returns {string[]} - */ - static natureList(card, player) { - if (!card) return []; - if (get.itemtype(card) == 'natures') return card.split(lib.natureSeparator); - if (get.itemtype(card) == 'nature') return [card]; - const natures = get.nature(card, player); - if (typeof natures != 'string') return []; - return natures.split(lib.natureSeparator); - } - static cards(num, putBack) { - if (_status.waitingForCards) { - ui.create.cards.apply(ui.create, _status.waitingForCards); - delete _status.waitingForCards; - } - var list = []; - var card = false; - if (typeof num != 'number') num = 1; - if (num == 0) { card = true; num = 1; } - if (num < 0) num = 1; - while (num--) { - if (ui.cardPile.hasChildNodes() == false) { - game.washCard(); - } - if (ui.cardPile.hasChildNodes() == false) { - game.over('平局'); - return []; - } - var cardx = ui.cardPile.removeChild(ui.cardPile.firstChild); - cardx.original = 'c'; - list.push(cardx); - } - if (putBack) { - for (let i = list.length - 1; i >= 0; i--) { - ui.cardPile.insertBefore(list[i], ui.cardPile.firstChild); - } - } - game.updateRoundNumber(); - if (card) return list[0]; - return list; - } - static judge(card) { return card.viewAs ? lib.card[card.viewAs].judge : get.info(card).judge; } - static judge2(card) { return card.viewAs ? lib.card[card.viewAs].judge2 : get.info(card).judge2; } - static distance(from, to, method) { - if (from == to) return 0; - if (!game.players.includes(from) && !game.dead.includes(from)) return Infinity; - if (!game.players.includes(to) && !game.dead.includes(to)) return Infinity; - let n = 1; - if (game.chess) { - let fxy = from.getXY(), txy = to.getXY(); - n = Math.abs(fxy[0] - txy[0]) + Math.abs(fxy[1] - txy[1]); - if (method == 'raw' || method == 'pure' || method == 'absolute') return n; - } - else if (to.isMin(true) || from.isMin(true)) { - if (method == 'raw' || method == 'pure' || method == 'absolute') return n; - } - else { - let player = from, length = game.players.length; - const totalPopulation = game.players.length + game.dead.length + 1; - for (let iwhile = 0; iwhile < totalPopulation; iwhile++) { - if (player.nextSeat != to) { - player = player.nextSeat; - if (player.isAlive() && !player.isOut() && !player.hasSkill('undist') && !player.isMin(true)) n++; - } - else { - break; - } - } - for (let i = 0; i < game.players.length; i++) { - if (game.players[i].isOut() || game.players[i].hasSkill('undist') || game.players[i].isMin(true)) length--; - } - if (method == 'absolute') return n; - if (from.isDead()) length++; - if (to.isDead()) length++; - const left = from.hasSkillTag('left_hand'), right = from.hasSkillTag('right_hand'); - if (left === right) n = Math.min(n, length - n); - else if (left == true) n = length - n; - if (method == 'raw' || method == 'pure') return n; - } - n = game.checkMod(from, to, n, 'globalFrom', from); - n = game.checkMod(from, to, n, 'globalTo', to); - const equips1 = from.getCards('e', function (card) { - return !ui.selected.cards || !ui.selected.cards.includes(card); - }), equips2 = to.getCards('e', function (card) { - return !ui.selected.cards || !ui.selected.cards.includes(card); - }); - for (let i = 0; i < equips1.length; i++) { - let info = get.info(equips1[i]).distance; - if (!info) continue; - if (info.globalFrom) { - n += info.globalFrom; - } - } - for (let i = 0; i < equips2.length; i++) { - let info = get.info(equips2[i]).distance; - if (!info) continue; - if (info.globalTo) { - n += info.globalTo; - } - if (info.attaclTo) { - m += info.attaclTo; - } - } - if (method == 'attack') { - let m = n; - m = game.checkMod(from, to, m, 'attackFrom', from); - m = game.checkMod(from, to, m, 'attackTo', to); - return m; - // const attakRange=from.getEquipRange(); - // m+=(1-attakRange); - // for(let i=0;i[number, number]) } [select] - * @returns { [number, number] } - */ - static select(select) { - if (typeof select == 'function') return get.select(select()); - else if (typeof select == 'number') return [select, select]; - else if (select && get.itemtype(select) == 'select') return select; - return [1, 1]; - } - static card(original) { - if (_status.event.skill) { - var card = get.info(_status.event.skill).viewAs; - if (typeof card == 'function') card = card(ui.selected.cards, _status.event.player); - if (card) { - return get.autoViewAs(card, ui.selected.cards); - } - } - if (_status.event._get_card) { - return _status.event._get_card; - } - var card = ui.selected.cards[0]; - if (original) return card; - if (card) { - card = get.autoViewAs(card, ui.selected.cards); - } - return card; - } - /** - * @template T - * @overload - * @param {T} key - * @returns {GameEvent[T]} - */ - /** - * @overload - * @returns {GameEvent} - */ - static event(key) { return key ? _status.event[key] : _status.event; } - static player() { return _status.event.player; } - static players(sort, dead, out) { - var players = game.players.slice(0); - if (sort != false) { - if (typeof sort == 'function') players.sort(sort); - else players.sortBySeat(get.itemtype(sort) == "player" ? sort : _status.event.player); - } - if (dead) players = players.concat(game.dead); - if (!out) players = players.filter(current => !current.isOut()); - return players; - } - static position(card, ordering) { - if (get.itemtype(card) == 'player') return parseInt(card.dataset.position); - if (card.timeout && card.destiny && card.destiny.classList) { - if (card.destiny.classList.contains('equips')) return 'e'; - if (card.destiny.classList.contains('judges')) return 'j'; - if (card.destiny.classList.contains('expansions')) return 'x'; - if (card.destiny.classList.contains('handcards')) return card.classList.contains('glows') ? 's' : 'h'; - if (card.destiny.id == 'cardPile') return 'c'; - if (card.destiny.id == 'discardPile') return 'd'; - if (card.destiny.id == 'special') return 's'; - if (card.destiny.id == 'ordering') return ordering ? 'o' : 'd'; - return null; - } - if (!card.parentNode || !card.parentNode.classList) return; - if (card.parentNode.classList.contains('equips')) return 'e'; - if (card.parentNode.classList.contains('judges')) return 'j'; - if (card.parentNode.classList.contains('expansions')) return 'x'; - if (card.parentNode.classList.contains('handcards')) return card.classList.contains('glows') ? 's' : 'h'; - if (card.parentNode.id == 'cardPile') return 'c'; - if (card.parentNode.id == 'discardPile') return 'd'; - if (card.parentNode.id == 'special') return 's'; - if (card.parentNode.id == 'ordering') return ordering ? 'o' : 'd'; - return null; - } - static skillTranslation(str, player) { - var str2; - if (str.startsWith('re')) { - str2 = str.slice(2); - if (str2) { - if (lib.translate[str] == lib.translate[str2]) { - if (player.hasSkill(str2)) { - return '界' + lib.translate[str]; - } - } - } - } - else if (str.startsWith('xin')) { - str2 = str.slice(3); - if (str2) { - if (lib.translate[str] == lib.translate[str2]) { - if (player.hasSkill(str2)) { - return '新' + lib.translate[str]; - } - } - } - } - return get.translation(str); - } - static skillInfoTranslation(name, player) { - if (player && lib.dynamicTranslate[name]) return lib.dynamicTranslate[name](player, name); - var str = lib.translate[name + '_info']; - if (!str) return ''; - return str; - // return str.replace(/锁定技/g,'锁定技'). - // replace(/限定技/g,'限定技'). - // replace(/觉醒技/g,'觉醒技'). - // replace(/主将技/g,'主将技'). - // replace(/副将技/g,'副将技'). - // replace(/阵法技/g,'阵法技'). - // replace(/主公技/g,'主公技'); - } - /** - * @returns {string} - */ - static translation(str, arg) { - if (str && typeof str == 'object' && (str.name || str._tempTranslate)) { - if (str._tempTranslate) return str._tempTranslate; - var str2; - if (arg == 'viewAs' && str.viewAs) { - str2 = get.translation(str.viewAs); - } - else { - str2 = get.translation(str.name); - } - if (str2 == '杀') { - str2 = ''; - if (typeof str.nature == 'string') { - let natures = str.nature.split(lib.natureSeparator).sort(lib.sort.nature); - for (let nature of natures) { - str2 += lib.translate['nature_' + nature] || lib.translate[nature] || ''; - } - } - str2 += '杀'; - } - if (get.itemtype(str) == 'card' || str.isCard) { - if (_status.cardtag && str.cardid) { - var tagstr = ''; - for (var i in _status.cardtag) { - if (_status.cardtag[i].includes(str.cardid)) { - tagstr += lib.translate[i + '_tag']; - } - } - if (tagstr) { - str2 += '·' + tagstr; - } - } - if (str.suit && str.number || str.isCard) { - var cardnum = get.number(str, false) || ''; - if ([1, 11, 12, 13].includes(cardnum)) { - cardnum = { '1': 'A', '11': 'J', '12': 'Q', '13': 'K' }[cardnum]; - } - if (arg == 'viewAs' && str.viewAs != str.name && str.viewAs) { - str2 += '(' + get.translation(str) + ')'; - } - else { - str2 += '【' + get.translation(get.suit(str, false)) + cardnum + '】'; - // var len=str2.length-1; - // str2=str2.slice(0,len)+''+str2[len]+'·'+get.translation(str.suit)+str.number; - } - } - } - return str2; - } - if (Array.isArray(str)) { - var str2 = get.translation(str[0], arg); - for (var i = 1; i < str.length; i++) { - str2 += '、' + get.translation(str[i], arg); - } - return str2; - } - if (get.itemtype(str) == 'natures') { - let natures = str.split(lib.natureSeparator).sort(lib.sort.nature); - var str2 = ''; - for (var nature of natures) { - str2 += lib.translate['nature_' + nature] || lib.translate[nature] || ''; - } - return str2; - } - if (arg == 'skill') { - if (lib.translate[str + '_ab']) return lib.translate[str + '_ab']; - if (lib.translate[str]) return lib.translate[str].slice(0, 2); - return str; - } - else if (arg == 'info') { - if (lib.translate[str + '_info']) return lib.translate[str + '_info']; - var str2 = str.slice(0, str.length - 1); - if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; - if (str.lastIndexOf('_') > 0) { - str2 = str.slice(0, str.lastIndexOf('_')); - if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; - } - str2 = str.slice(0, str.length - 2); - if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; - if (lib.skill[str] && lib.skill[str].prompt) return lib.skill[str].prompt; - } - if (lib.translate[str]) { - return lib.translate[str]; - } - if (typeof str == 'string') { - if (lib.translate['nature_' + str]) return lib.translate['nature_' + str]; - return str; - } - if (typeof str == 'number' || typeof str == 'boolean') { - return str.toString(); - } - if (str && str.toString) { - return str.toString(); - } - return ''; - } - static strNumber(num) { - switch (num) { - case 1: return 'A'; - case 11: return 'J'; - case 12: return 'Q'; - case 13: return 'K'; - default: return num.toString(); - } - } - static cnNumber(num, two) { - if (num == Infinity) return '∞'; - if (typeof num != 'number' && typeof num != 'string') return num; - if (isNaN(num)) return ''; - let numStr = num.toString(); - if (!/^\d+$/.test(numStr)) return num; - - const chars = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; - const units = ['', '十', '百', '千']; - - if (numStr.length <= 2) {//两位数以下单独处理保证效率 - if (numStr.length == 1) return !two && num == 2 ? '两' : chars[num]; - return (numStr[0] == '1' ? '' : chars[numStr[0]]) + '十' + (numStr[1] == '0' ? '' : chars[numStr[1]]); - } - - numStr = numStr.replace(/(?=(\d{4})+$)/g, ',').split(',').filter(Boolean); - const handleZero = str => str.replace(/零{2,}/g, '零').replace(/零+$/g, ''); - const _transform = str => { - if (str === '0000') return '零'; - if (!two && str === '2') return '两'; - let result = ''; - for (let i = 0; i < str.length; i++) { - let char = chars[+str[i]]; - const unitIndex = str.length - 1 - i; - let unit = units[unitIndex]; - if (!two && char === '二' && unitIndex > 1) char = '两'; - if (char === '零') unit = ''; - result += char + unit; - } - result = handleZero(result); - return result; - }; - let result = ''; - for (let i = 0; i < numStr.length; i++) { - const part = numStr[i]; - let char = _transform(part); - const unitIndex = numStr.length - 1 - i; - let unit = unitIndex % 2 ? '万' : '亿'.repeat(unitIndex / 2); - if (char === '零') unit = ''; - result += char + unit; - } - result = handleZero(result); - return result; - } - /** - * @param {((a: Button, b: Button) => number)} [sort] 排序函数 - * @returns { Button[] } - */ - static selectableButtons(sort) { - if (!_status.event.player) return []; - var buttons = _status.event.dialog.buttons; - var selectable = []; - for (var i = 0; i < buttons.length; i++) { - if (buttons[i].classList.contains('selectable') && - buttons[i].classList.contains('selected') == false) { - selectable.push(buttons[i]); - } - } - if (sort) { - selectable.sort(sort); - } - return selectable; - } - /** - * @param {((a: Card, b: Card) => number)} [sort] 排序函数 - * @returns { Card[] } - */ - static selectableCards(sort) { - if (!_status.event.player) return []; - var cards = _status.event.player.getCards('hes'); - var selectable = []; - for (var i = 0; i < cards.length; i++) { - if (cards[i].classList.contains('selectable') && - cards[i].classList.contains('selected') == false) { - selectable.push(cards[i]); - } - } - if (sort) { - selectable.sort(sort); - } - return selectable; - } - /** - * @returns { string[] } 技能名数组 - */ - static skills() { - var skills = []; - if (ui.skills) { - skills = skills.concat(ui.skills.skills); - } - if (ui.skills2) { - skills = skills.concat(ui.skills2.skills); - } - if (ui.skills3) { - skills = skills.concat(ui.skills3.skills); - } - return skills; - } - static gainableSkills(func, player) { - var list = []; - for (var i in lib.character) { - if (lib.filter.characterDisabled(i)) continue; - if (lib.filter.characterDisabled2(i)) continue; - if (lib.character[i][4]) { - if (lib.character[i][4].includes('boss')) continue; - if (lib.character[i][4].includes('hiddenboss')) continue; - if (lib.character[i][4].includes('minskin')) continue; - if (lib.character[i][4].includes('unseen')) continue; - } - for (var j = 0; j < lib.character[i][3].length; j++) { - var skill = lib.character[i][3][j]; - var info = lib.skill[skill]; - if (lib.filter.skillDisabled(skill)) continue; - if (func && !func(info, skill, i)) continue; - if (player && player.hasSkill && info.ai && info.ai.combo && !player.hasSkill(info.ai.combo)) continue; - list.add(skill); - } - } - return list; - } - static gainableSkillsName(name, func) { - var list = []; - if (name && lib.character[name]) { - if (lib.character[name][4]) { - if (lib.character[name][4].includes('boss')) return list; - if (lib.character[name][4].includes('hiddenboss')) return list; - if (lib.character[name][4].includes('minskin')) return list; - if (lib.character[name][4].includes('unseen')) return list; - } - for (var j = 0; j < lib.character[name][3].length; j++) { - var skill = lib.character[name][3][j]; - var info = lib.skill[skill]; - if (lib.filter.skillDisabled(skill)) continue; - if (func && !func(info, skill, name)) continue; - list.add(skill); - } - } - return list; - } - static gainableCharacters(func) { - var list = []; - for (var i in lib.character) { - var info = lib.character[i]; - if (!info) continue; - if (typeof func == 'function' && !func(info, i)) continue; - if (lib.filter.characterDisabled(i)) continue; - if (lib.filter.characterDisabled2(i)) continue; - list.push(i); - } - if (func === true) { - var players = game.players.concat(game.dead); - for (var i = 0; i < players.length; i++) { - list.remove(players[i].name); - list.remove(players[i].name1); - list.remove(players[i].name2); - } - } - return list; - } - /** - * @param {((a: Player, b: Player) => number)} [sort] 排序函数 - * @returns { Player[] } - */ - static selectableTargets(sort) { - var selectable = []; - var players = game.players.slice(0); - if (_status.event.deadTarget) players.addArray(game.dead); - for (var i = 0; i < players.length; i++) { - if (players[i].classList.contains('selectable') && - players[i].classList.contains('selected') == false) { - selectable.push(players[i]); - } - } - selectable.randomSort(); - if (sort) { - selectable.sort(sort); - } - return selectable; - } - static filter(filter, i) { - if (typeof filter == 'function') return filter; - if (i == undefined) i = 0; - var result = function () { - if (filter == arguments[i]) return true; - for (var j in filter) { - if (Object.prototype.hasOwnProperty.call(filter, j)) { - if (get.itemtype(arguments[i]) == 'card') { - if (j == 'name') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.name(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.name(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'type') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.type(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.type(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'subtype') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.subtype(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.subtype(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'color') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.color(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.color(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'suit') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.suit(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.suit(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'number') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.number(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.number(arguments[i]) != filter[j]) return false; - } - } - else if (Array.isArray(filter[j])) { - if (filter[j].includes(arguments[i][j]) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (arguments[i][j] != filter[j]) return false; - } - } - else { - if (arguments[i][j] != filter[j]) return false; - } - } - } - return true; - }; - result._filter_args = [filter, i]; - return result; - } - static cardCount(card, player) { - var num; - if (player == undefined) player = _status.event.player; - if (card == true) { - num = 0; - var stat = player.getStat('card'); - for (var i in stat) { - if (typeof stat[i] == 'number') num += stat[i]; - } - return num; - } - if (typeof card == 'object') { - card = card.name; - } - num = player.getStat('card')[card]; - if (num == undefined) return 0; - return num; - } - static skillCount(skill, player) { - if (player == undefined) player = _status.event.player; - var num = player.getStat('skill')[skill]; - if (num == undefined) return 0; - return num; - } - static owner(card, method) { - return game.players.concat(game.dead).find(current => - current.getCards("hejsx").includes(card) || (current.judging[0] == card && method != "judge")); - } - static noSelected() { return ui.selected.buttons.length + ui.selected.cards.length + ui.selected.targets.length == 0; } - static population(identity) { - return identity == undefined ? - game.players.length + game.dead.length : - game.players.filter(current => current.identity == identity).length; - } - static totalPopulation(identity) { - return identity == undefined ? - game.players.length + game.dead.length : - game.players.concat(game.dead).filter(current => current.identity == identity).length; - } - /** - * @param { Card | VCard } item - */ - static cardtag(item, tag) { - return (item.cardid && (get.itemtype(item) == 'card' || !item.cards || !item.cards.length || item.name == item.cards[0].name) && _status.cardtag && _status.cardtag[tag] && _status.cardtag[tag].includes(item.cardid)) - || (item.cardtags && item.cardtags.includes(tag)); - } - static tag(item, tag, item2, bool) { - var result; - if (get.info(item, bool) && get.info(item, bool).ai && get.info(item, bool).ai.tag) { - result = get.info(item, bool).ai.tag[tag]; - } - if (typeof result == 'function') return result(item, item2); - return result; - } - static sortCard(sort) { - var func; - if (sort == 'type_sort') { - func = function (card) { - var type = get.type(card, null, false); - var subtype = get.subtype(card, false); - if (lib.cardType[subtype]) { - return lib.cardType[subtype]; - } - if (lib.cardType[type]) { - return lib.cardType[type]; - } - switch (type) { - case 'basic': return 2; - case 'chess': return 1.5; - case 'trick': return -1; - case 'delay': return -2; - case 'equip': return -3; - default: return -4; - } - }; - } - else if (sort == 'suit_sort') { - func = function (card) { - if (get.suit(card) == 'heart') return 2; - if (get.suit(card) == 'diamond') return 1; - if (get.suit(card) == 'spade') return -1; - if (get.suit(card) == 'club') return -2; - }; - } - else if (sort == 'number_sort') { - func = function (card) { - return get.number(card) - 7 + 0.5; - }; - } - return func; - } - static difficulty() { - switch (get.config('difficulty')) { - case 'easy': return 1; - case 'normal': return 2; - case 'hard': return 3; - default: return 1; - } - } - static cardPile(name, create) { - var filter = function (card) { - if (typeof name == 'string') { - if (card.name == name) { - return true; - } - } - else if (typeof name == 'function') { - if (name(card)) { - return true; - } - } - return false; - }; - if (create != 'discardPile') { - var num = get.rand(0, ui.cardPile.childNodes.length - 1); - for (var i = 0; i < ui.cardPile.childNodes.length; i++) { - var j = i; - if (j >= ui.cardPile.childNodes.length) j -= ui.cardPile.childNodes.length; - if (filter(ui.cardPile.childNodes[j])) { - return ui.cardPile.childNodes[j]; - } - } - } - if (create != 'cardPile') { - for (var i = 0; i < ui.discardPile.childNodes.length; i++) { - var j = i; - if (j >= ui.discardPile.childNodes.length) j -= ui.discardPile.childNodes.length; - if (filter(ui.discardPile.childNodes[j])) { - return ui.discardPile.childNodes[j]; - } - } - } - if (create == 'field') { - var found = null; - game.findPlayer(function (current) { - var ej = current.getCards('ej'); - for (var i = 0; i < ej.length; i++) { - if (filter(ej[i])) { - found = ej[i]; - return true; - } - } - }); - return found; - } - if (create && !['cardPile', 'discardPile', 'field'].includes(create)) { - return game.createCard(name); - } - return null; - } - static cardPile2(name) { return get.cardPile(name, 'cardPile'); } - static discardPile(name) { return get.cardPile(name, 'discardPile'); } - static aiStrategy() { - switch (get.config('ai_strategy')) { - case 'ai_strategy_1': return 1; - case 'ai_strategy_2': return 2; - case 'ai_strategy_3': return 3; - case 'ai_strategy_4': return 4; - case 'ai_strategy_5': return 5; - case 'ai_strategy_6': return 6; - default: return 1; - } - } - static skillintro(name, learn, learn2) { - var str = ''; - var infoitem = lib.character[name]; - if (!infoitem) { - for (var itemx in lib.characterPack) { - if (lib.characterPack[itemx][name]) { - infoitem = lib.characterPack[itemx][name]; break; - } - } - } - var skills = infoitem[3]; - var opacity; - for (var i = 0; i < skills.length; i++) { - if (lib.translate[skills[i]] && lib.translate[skills[i] + '_info'] && lib.skill[skills[i]]) { - if (learn && lib.skill[skills[i]].unique && (learn2 || !lib.skill[skills[i]].gainable)) { - opacity = 'opacity:0.5'; - } - else { - opacity = ''; - } - var skilltrans = get.translation(skills[i]).slice(0, 2); - str += '
【' + skilltrans + '】
' + - get.skillInfoTranslation(skills[i]) + '
'; - } - } - return str; - } - static intro(name) { - var info = lib.character[name]; - var str = '性别:' + get.translation(info[0]) + '
'; - str += '势力:' + get.translation(info[1]) + '
'; - str += '体力:' + get.translation(info[2]) + '
'; - str += '技能:'; - if (info[3].length) { - str += get.translation(info[3][0]); - for (var i = 1; i < info[3].length; i++) { - str += '、' + get.translation(info[3][i]); - } - } - return str; - } - static storageintro(type, content, player, dialog, skill) { - switch (type) { - case 'mark': { - if (content > 0) { - return '共有' + content + '个标记'; - } - return false; - } - case 'turn': { - if (content > 0) { - return '剩余' + content + '个回合'; - } - return false; - } - case 'time': { - if (content > 0) { - return '剩余' + content + '次'; - } - return false; - } - case 'limited': { - if (content) { - return '已发动'; - } - return '未发动'; - } - case 'info': { - return lib.translate[skill + '_info']; - } - case 'cardCount': { - if (Array.isArray(content)) { - return '共有' + get.cnNumber(content.length) + '张牌'; - } - return false; - } - case 'expansion': { - content = player.getCards('x', function (card) { - return card.hasGaintag(skill); - }); - if (dialog && content.length) { - dialog.addAuto(content); - } - else { - return '没有卡牌'; - } - return false; - } - case 'card': case 'cards': { - if (get.itemtype(content) == 'card') { - content = [content]; - } - if (dialog && get.itemtype(content) == 'cards') { - dialog.addAuto(content); - } - else { - if (content && content.length) { - return get.translation(content); - } - } - if (Array.isArray(content) && !content.length) { - return '没有卡牌'; - } - return false; - } - case 'player': case 'players': { - if (get.itemtype(content) == 'player') { - content = [content]; - } - if (dialog && get.itemtype(content) == 'players') { - dialog.addAuto(content); - return false; - } - else { - if (content && content.length) { - return get.translation(content); - } - return false; - } - } - case 'character': case 'characters': { - if (typeof content == 'string') { - content = [content]; - } - if (dialog && Array.isArray(content)) { - dialog.addAuto([content, 'character']); - return false; - } - else { - if (content && content.length) { - return get.translation(content); - } - return false; - } - } - default: { - if (typeof type == 'string') { - type = type.replace(/#/g, content); - type = type.replace(/&/g, get.cnNumber(content)); - type = type.replace(/\$/g, get.translation(content)); - return type; - } - else if (typeof type == 'function') { - return type(content, player, skill); - } - return false; - } - } - } - static nodeintro(node, simple, evt) { - var uiintro = ui.create.dialog('hidden', 'notouchscroll'); - if (node.classList.contains('player') && !node.name) { - return uiintro; - } - var i, translation, intro, str; - if (node._nointro) return; - if (typeof node._customintro == 'function') { - if (node._customintro(uiintro, evt) === false) return; - if (evt) lib.placePoppedDialog(uiintro, evt); - } - else if (Array.isArray(node._customintro)) { - var caption = node._customintro[0]; - var content = node._customintro[1]; - if (typeof caption == 'function') { - caption = caption(node); - } - if (typeof content == 'function') { - content = content(node); - } - uiintro.add(caption); - uiintro.add('
' + content + '
'); - } - else if (node.classList.contains('player') || node.linkplayer) { - if (node.linkplayer) { - node = node.link; - } - let capt = get.translation(node.name); - const characterInfo = get.character(node.name), sex = node.sex || characterInfo[0]; - if (sex && sex != 'unknown' && lib.config.show_sex) capt += `  ${sex == 'none' ? '无' : get.translation(sex)}`; - const group = node.group; - if (group && group != 'unknown' && lib.config.show_group) capt += `  ${get.translation(group)}`; - uiintro.add(capt); - - if (lib.characterTitle[node.name]) { - uiintro.addText(get.colorspan(lib.characterTitle[node.name])); - } - - if (!node.noclick) { - const allShown = (node.isUnderControl() || (!game.observe && game.me && game.me.hasSkillTag('viewHandcard', null, node, true))); - const shownHs = node.getShownCards(); - if (shownHs.length) { - uiintro.add('
明置的手牌
'); - uiintro.addSmall(shownHs); - if (allShown) { - var hs = node.getCards('h'); - hs.removeArray(shownHs); - if (hs.length) { - uiintro.add('
其他手牌
'); - uiintro.addSmall(hs); - } - } - } - else if (allShown) { - var hs = node.getCards('h'); - if (hs.length) { - uiintro.add('
手牌
'); - uiintro.addSmall(hs); - } - } - } - - var skills = node.getSkills(null, false, false).slice(0); - var skills2 = game.filterSkills(skills, node); - if (node == game.me && node.hiddenSkills.length) { - skills.addArray(node.hiddenSkills); - } - for (var i in node.disabledSkills) { - if (node.disabledSkills[i].length == 1 && - node.disabledSkills[i][0] == i + '_awake' && - !node.hiddenSkills.includes(i)) { - skills.add(i); - } - } - for (i = 0; i < skills.length; i++) { - if (lib.skill[skills[i]] && (lib.skill[skills[i]].nopop || lib.skill[skills[i]].equipSkill)) continue; - if (lib.translate[skills[i] + '_info']) { - if (lib.translate[skills[i] + '_ab']) translation = lib.translate[skills[i] + '_ab']; - else { - translation = get.translation(skills[i]); - if (!lib.skill[skills[i]].nobracket) translation = `【${translation.slice(0, 2)}】`; - } - - if (node.forbiddenSkills[skills[i]]) { - var forbidstr = '
' + translation + '
'; - if (node.forbiddenSkills[skills[i]].length) { - forbidstr += '(与' + get.translation(node.forbiddenSkills[skills[i]]) + '冲突)
'; - } - else { - forbidstr += '(双将禁用)
'; - } - forbidstr += get.skillInfoTranslation(skills[i], node) + '
'; - uiintro.add(forbidstr); - } - else if (!skills2.includes(skills[i])) { - if (lib.skill[skills[i]].preHidden && get.mode() == 'guozhan') { - uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
预亮技能
'); - var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); - if (_status.prehidden_skills.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - underlinenode.link = skills[i]; - underlinenode.listen(ui.click.hiddenskill); - } - else uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
'); - } - else if (lib.skill[skills[i]].temp || !node.skills.includes(skills[i]) || lib.skill[skills[i]].thundertext) { - if (lib.skill[skills[i]].frequent || lib.skill[skills[i]].subfrequent) { - uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
自动发动
'); - var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); - if (lib.skill[skills[i]].frequent) { - if (lib.config.autoskilllist.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - } - if (lib.skill[skills[i]].subfrequent) { - for (var j = 0; j < lib.skill[skills[i]].subfrequent.length; j++) { - if (lib.config.autoskilllist.includes(skills[i] + '_' + lib.skill[skills[i]].subfrequent[j])) { - underlinenode.classList.remove('on'); - } - } - } - if (lib.config.autoskilllist.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - underlinenode.link = skills[i]; - underlinenode.listen(ui.click.autoskill2); - } - else { - uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
'); - } - } - else if (lib.skill[skills[i]].frequent || lib.skill[skills[i]].subfrequent) { - uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
自动发动
'); - var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); - if (lib.skill[skills[i]].frequent) { - if (lib.config.autoskilllist.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - } - if (lib.skill[skills[i]].subfrequent) { - for (var j = 0; j < lib.skill[skills[i]].subfrequent.length; j++) { - if (lib.config.autoskilllist.includes(skills[i] + '_' + lib.skill[skills[i]].subfrequent[j])) { - underlinenode.classList.remove('on'); - } - } - } - if (lib.config.autoskilllist.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - underlinenode.link = skills[i]; - underlinenode.listen(ui.click.autoskill2); - } - else if (lib.skill[skills[i]].clickable && node.isIn() && node.isUnderControl(true)) { - var intronode = uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
').querySelector('.skillbutton'); - if (!_status.gameStarted || (lib.skill[skills[i]].clickableFilter && !lib.skill[skills[i]].clickableFilter(node))) { - intronode.classList.add('disabled'); - intronode.style.opacity = 0.5; - } - else { - intronode.link = node; - intronode.func = lib.skill[skills[i]].clickable; - intronode.classList.add('pointerdiv'); - intronode.listen(ui.click.skillbutton); - } - } - else { - uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
'); - } - if (lib.translate[skills[i] + '_append']) { - uiintro._place_text = uiintro.add('
' + lib.translate[skills[i] + '_append'] + '
'); - } - } - } - // if(get.is.phoneLayout()){ - // var storage=node.storage; - // for(i in storage){ - // if(get.info(i)&&get.info(i).intro){ - // intro=get.info(i).intro; - // if(node.getSkills().concat(lib.skill.global).includes(i)==false&&!intro.show) continue; - // var name=intro.name?intro.name:get.translation(i); - // if(typeof name=='function'){ - // name=name(storage[i],node); - // } - // translation='
『'+name.slice(0,2)+'』
'; - // var stint=get.storageintro(intro.content,storage[i],node,null,i); - // if(stint){ - // translation+=stint+'
'; - // uiintro.add(translation); - // } - // } - // } - // } - - if (lib.config.right_range && _status.gameStarted) { - uiintro.add(ui.create.div('.placeholder')); - var table, tr, td; - table = document.createElement('table'); - tr = document.createElement('tr'); - table.appendChild(tr); - td = document.createElement('td'); - td.innerHTML = '距离'; - tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '手牌'; - tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '行动'; - tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '伤害'; - tr.appendChild(td); - - tr = document.createElement('tr'); - table.appendChild(tr); - td = document.createElement('td'); - if (node == game.me || !game.me || !game.me.isIn()) { - td.innerHTML = '-'; - } - else { - var dist1 = get.numStr(Math.max(1, game.me.distanceTo(node))); - var dist2 = get.numStr(Math.max(1, node.distanceTo(game.me))); - if (dist1 == dist2) { - td.innerHTML = dist1; - } - else { - td.innerHTML = dist1 + '/' + dist2; - } - } - tr.appendChild(td); - td = document.createElement('td'); - let handcardLimit = node.getHandcardLimit(); - td.innerHTML = `${node.countCards('h')}/${handcardLimit >= 114514 ? '∞' : handcardLimit}`; - tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = node.phaseNumber; - tr.appendChild(td); - td = document.createElement('td'); - - (function () { - num = 0; - for (var j = 0; j < node.stat.length; j++) { - if (typeof node.stat[j].damage == 'number') num += node.stat[j].damage; - } - td.innerHTML = num; - }()); - tr.appendChild(td); - table.style.width = 'calc(100% - 20px)'; - table.style.marginLeft = '10px'; - - uiintro.content.appendChild(table); - if (!lib.config.show_favourite) { - table.style.paddingBottom = '5px'; - } - } - if (!simple || get.is.phoneLayout()) { - var es = node.getCards('e'); - for (var i = 0; i < es.length; i++) { - var cardinfo = lib.card[es[i].name]; - if (cardinfo && cardinfo.cardPrompt) uiintro.add('
' + es[i].outerHTML + '
' + cardinfo.cardPrompt(es[i]) + '
'); - else uiintro.add('
' + es[i].outerHTML + '
' + lib.translate[es[i].name + '_info'] + '
'); - uiintro.content.lastChild.querySelector('.skill>.card').style.transform = ''; - - if (lib.translate[es[i].name + '_append']) { - uiintro.add('
' + lib.translate[es[i].name + '_append'] + '
'); - } - } - var js = node.getCards('j'); - for (var i = 0; i < js.length; i++) { - if (js[i].viewAs && js[i].viewAs != js[i].name) { - uiintro.add('
' + js[i].outerHTML + '
' + lib.translate[js[i].viewAs] + ':' + lib.translate[js[i].viewAs + '_info'] + '
'); - } - else { - uiintro.add('
' + js[i].outerHTML + '
' + lib.translate[js[i].name + '_info'] + '
'); - } - uiintro.content.lastChild.querySelector('.skill>.card').style.transform = ''; - } - if (get.is.phoneLayout()) { - var markCoutainer = ui.create.div('.mark-container.marks'); - for (var i in node.marks) { - var nodemark = node.marks[i].cloneNode(true); - nodemark.classList.add('pointerdiv'); - nodemark.link = node.marks[i]; - nodemark.style.transform = ''; - markCoutainer.appendChild(nodemark); - nodemark.listen(function () { - uiintro.noresume = true; - var rect = this.link.getBoundingClientRect(); - ui.click.intro.call(this.link, { - clientX: rect.left + rect.width, - clientY: rect.top + rect.height / 2, - }); - if (lib.config.touchscreen) { - uiintro._close(); - } - }); - } - if (markCoutainer.childElementCount) { - uiintro.addText('标记'); - uiintro.add(markCoutainer); - } - } - } - if (!game.observe && _status.gameStarted && game.me && node != game.me) { - ui.throwEmotion = []; - uiintro.addText('发送交互表情'); - var click = function () { - if (_status.dragged) return; - if (_status.justdragged) return; - if (_status.throwEmotionWait) return; - var emotion = this.link; - if (game.online) { - game.send('throwEmotion', node, emotion); - } - else game.me.throwEmotion(node, emotion); - uiintro._close(); - _status.throwEmotionWait = true; - setTimeout(function () { - _status.throwEmotionWait = false; - if (ui.throwEmotion) { - for (var i of ui.throwEmotion) i.classList.remove('exclude'); - } - }, (emotion == 'flower' || emotion == 'egg') ? 500 : 5000); - }; - var td; - var table = document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin = '0'; - table.style.width = '100%'; - table.style.position = 'relative'; - var listi = ['flower', 'egg']; - for (var i = 0; i < listi.length; i++) { - td = ui.create.div('.menubutton.reduce_radius.pointerdiv.tdnode'); - ui.throwEmotion.add(td); - if (_status.throwEmotionWait) td.classList.add('exclude'); - td.link = listi[i]; - table.appendChild(td); - td.innerHTML = '' + get.translation(listi[i]) + ''; - td.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', click); - } - uiintro.content.appendChild(table); - table = document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin = '0'; - table.style.width = '100%'; - table.style.position = 'relative'; - var listi = ['wine', 'shoe']; - if (game.me.storage.zhuSkill_shanli) listi = ['yuxisx', 'jiasuo']; - for (var i = 0; i < listi.length; i++) { - td = ui.create.div('.menubutton.reduce_radius.pointerdiv.tdnode'); - ui.throwEmotion.add(td); - if (_status.throwEmotionWait) td.classList.add('exclude'); - td.link = listi[i]; - table.appendChild(td); - td.innerHTML = '' + get.translation(listi[i]) + ''; - td.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', click); - } - uiintro.content.appendChild(table); - } - var modepack = lib.characterPack['mode_' + get.mode()]; - if (lib.config.show_favourite && lib.character[node.name] && game.players.includes(node) && - (!modepack || !modepack[node.name]) && (!simple || get.is.phoneLayout())) { - var addFavourite = ui.create.div('.text.center.pointerdiv'); - addFavourite.link = node.name; - if (lib.config.favouriteCharacter.includes(node.name)) { - addFavourite.innerHTML = '移除收藏'; - } - else { - addFavourite.innerHTML = '添加收藏'; - } - addFavourite.listen(ui.click.favouriteCharacter); - uiintro.add(addFavourite); - } - if (!simple || get.is.phoneLayout()) { - if ((lib.config.change_skin || lib.skin) && !node.isUnseen()) { - var num = 1; - var introadded = false; - var createButtons = function (num, avatar2) { - if (!introadded) { - introadded = true; - uiintro.add('
更改皮肤
'); - } - var buttons = ui.create.div('.buttons.smallzoom.scrollbuttons'); - lib.setMousewheel(buttons); - var nameskin = (avatar2 ? node.name2 : node.name1); - var nameskin2 = nameskin; - var gzbool = false; - if (nameskin.startsWith('gz_shibing')) { - nameskin = nameskin.slice(3, 11); - } - else if (nameskin.startsWith('gz_')) { - nameskin = nameskin.slice(3); - gzbool = true; - } - for (var i = 0; i <= num; i++) { - var button = ui.create.div('.button.character.pointerdiv', buttons, function () { - if (this._link) { - if (avatar2) { - lib.config.skin[nameskin] = this._link; - node.node.avatar2.style.backgroundImage = this.style.backgroundImage; - } - else { - lib.config.skin[nameskin] = this._link; - node.node.avatar.style.backgroundImage = this.style.backgroundImage; - } - } - else { - delete lib.config.skin[nameskin]; - if (avatar2) { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.node.avatar2.setBackground(nameskin2, 'character'); - else node.node.avatar2.setBackground(nameskin, 'character'); - } - else { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.node.avatar.setBackground(nameskin2, 'character'); - else node.node.avatar.setBackground(nameskin, 'character'); - } - } - game.saveConfig('skin', lib.config.skin); - }); - button._link = i; - if (i) { - button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); - } - else { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); - else button.setBackground(nameskin, 'character', 'noskin'); - } - } - uiintro.add(buttons); - }; - var loadImage = function (avatar2) { - var img = new Image(); - img.onload = function () { - num++; - loadImage(avatar2); - }; - img.onerror = function () { - num--; - if (num) { - createButtons(num, avatar2); - } - if (!avatar2) { - if (!node.classList.contains('unseen2') && node.name2) { - num = 1; - loadImage(true); - } - } - }; - var nameskin = (avatar2 ? node.name2 : node.name1); - var nameskin2 = nameskin; - var gzbool = false; - if (nameskin.startsWith('gz_shibing')) { - nameskin = nameskin.slice(3, 11); - } - else if (nameskin.startsWith('gz_')) { - nameskin = nameskin.slice(3); - gzbool = true; - } - img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; - }; - if (lib.config.change_skin) { - if (!node.isUnseen(0)) { - loadImage(); - } - else if (node.name2) { - loadImage(true); - } - } - else { - setTimeout(function () { - var nameskin1 = node.name1; - var nameskin2 = node.name2; - if (nameskin1 && nameskin1.startsWith('gz_')) { - nameskin1 = nameskin1.slice(3); - } - if (nameskin2 && nameskin2.startsWith('gz_')) { - nameskin2 = nameskin2.slice(3); - } - if (!node.isUnseen(0) && lib.skin[nameskin1]) { - createButtons(lib.skin[nameskin1]); - } - if (!node.isUnseen(1) && lib.skin[nameskin2]) { - createButtons(lib.skin[nameskin2], true); - } - }); - } - } - } - - uiintro.add(ui.create.div('.placeholder.slim')); - } - else if (node.classList.contains('mark') && node.info && - node.parentNode && node.parentNode.parentNode && node.parentNode.parentNode.classList.contains('player')) { - var info = node.info; - var player = node.parentNode.parentNode; - if (info.name) { - if (typeof info.name == 'function') { - var named = info.name(player.storage[node.skill], player); - if (named) { - uiintro.add(named); - } - } - else { - uiintro.add(info.name); - } - } - else if (info.name !== false) { - uiintro.add(get.translation(node.skill)); - } - if (typeof info.id == 'string' && info.id.startsWith('subplayer') && - player.isUnderControl(true) && player.storage[info.id] && !_status.video) { - var storage = player.storage[info.id]; - uiintro.addText('当前体力:' + storage.hp + '/' + storage.maxHp); - if (storage.hs.length) { - uiintro.addText('手牌区'); - uiintro.addSmall(storage.hs); - } - if (storage.es.length) { - uiintro.addText('装备区'); - uiintro.addSmall(storage.es); - } - } - if (typeof info.mark == 'function') { - var stint = info.mark(uiintro, player.storage[node.skill], player); - if (stint) { - var placetext = uiintro.add('
' + stint + '
'); - if (!stint.startsWith('
'+stint+'
'); - // } - // else{ - // uiintro.add('
'+stint+'
'); - // } - } - } - else { - var stint = get.storageintro(info.content, player.storage[node.skill], player, uiintro, node.skill); - if (stint) { - if (stint[0] == '@') { - uiintro.add('
' + stint.slice(1) + '
'); - } - else { - var placetext = uiintro.add('
' + stint + '
'); - if (!stint.startsWith('
'+stint+'
'); - // } - // else{ - // uiintro.add('
'+stint+'
'); - // } - } - } - uiintro.add(ui.create.div('.placeholder.slim')); - } - else if (node.classList.contains('card')) { - //卡牌长按介绍 - if (ui.arena.classList.contains('observe') && node.parentNode.classList.contains('handcards')) { - return; - } - var name = node.name; - if (node.parentNode.cardMod) { - var moded = false; - for (var i in node.parentNode.cardMod) { - var item = node.parentNode.cardMod[i](node); - if (Array.isArray(item)) { - moded = true; - uiintro.add(item[0]); - uiintro._place_text = uiintro.add('
' + item[1] + '
'); - } - } - if (moded) return uiintro; - } - if (node.link && node.link.name && lib.card[node.link.name]) { - name = node.link.name; - } - if (get.position(node) == 'j' && node.viewAs && node.viewAs != name) { - uiintro.add(get.translation(node.viewAs)); - uiintro.add('
(' + get.translation(get.translation(node)) + ')
'); - // uiintro.add(get.translation(node.viewAs)+'
('+get.translation(node)+')
'); - uiintro.nosub = true; - name = node.viewAs; - } - else { - uiintro.add(get.translation(node)); - } - if (node._banning) { - var clickBanned = function () { - var banned = lib.config[this.bannedname] || []; - if (banned.includes(name)) { - banned.remove(name); - } - else { - banned.push(name); - } - game.saveConfig(this.bannedname, banned); - this.classList.toggle('on'); - if (node.updateBanned) { - node.updateBanned(); - } - }; - var modeorder = lib.config.modeorder || []; - for (var i in lib.mode) { - modeorder.add(i); - } - var list = []; - uiintro.contentContainer.listen(function (e) { - ui.click.touchpop(); - e.stopPropagation(); - }); - for (var i = 0; i < modeorder.length; i++) { - if (node._banning == 'online') { - if (!lib.mode[modeorder[i]].connect) continue; - } - else if (modeorder[i] == 'connect' || modeorder[i] == 'brawl') { - continue; - } - if (lib.config.all.mode.includes(modeorder[i])) { - list.push(modeorder[i]); - } - } - if (lib.card[name] && lib.card[name].type == 'trick') list.push('zhinang_tricks'); - var page = ui.create.div('.menu-buttons.configpopped', uiintro.content); - var banall = false; - for (var i = 0; i < list.length; i++) { - var cfg = ui.create.div('.config', list[i] == 'zhinang_tricks' ? '设为智囊' : (lib.translate[list[i]] + '模式'), page); - cfg.classList.add('toggle'); - if (list[i] == 'zhinang_tricks') { - cfg.bannedname = ((node._banning == 'offline') ? '' : 'connect_') + 'zhinang_tricks'; - } - else if (node._banning == 'offline') { - cfg.bannedname = list[i] + '_bannedcards'; - } - else { - cfg.bannedname = 'connect_' + list[i] + '_bannedcards'; - } - cfg.listen(clickBanned); - ui.create.div(ui.create.div(cfg)); - var banned = lib.config[cfg.bannedname] || []; - if (banned.includes(name) == (list[i] == 'zhinang_tricks')) { - cfg.classList.add('on'); - banall = true; - } - } - ui.create.div('.menubutton.pointerdiv', banall ? '全部禁用' : '全部启用', uiintro.content, function () { - if (this.innerHTML == '全部禁用') { - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].bannedname.indexOf('zhinang_tricks') == -1 && page.childNodes[i].bannedname && page.childNodes[i].classList.contains('on')) { - clickBanned.call(page.childNodes[i]); - } - } - this.innerHTML = '全部启用'; - } - else { - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].bannedname.indexOf('zhinang_tricks') == -1 && page.childNodes[i].bannedname && !page.childNodes[i].classList.contains('on')) { - clickBanned.call(page.childNodes[i]); - } - } - this.innerHTML = '全部禁用'; - } - }).style.marginTop = '-10px'; - ui.create.div('.placeholder.slim', uiintro.content); - } - else { - if (lib.translate[name + '_info']) { - if (!uiintro.nosub) { - if (lib.card[name] && lib.card[name].derivation) { - if (typeof lib.card[name].derivation == 'string') { - uiintro.add('
来源:' + get.translation(lib.card[name].derivation) + '
'); - } - else if (lib.card[name].derivationpack) { - uiintro.add('
来源:' + get.translation(lib.card[name].derivationpack + '_card_config') + '包
'); - } - } - let typeinfo = ''; - if (lib.card[name] && lib.card[name].unique) { - typeinfo += ('特殊' + get.translation(lib.card[name].type) + '牌'); - } - else if (lib.card[name] && lib.card[name].type && lib.translate[lib.card[name].type]) { - typeinfo += (get.translation(lib.card[name].type) + '牌'); - } - if (get.subtype(name, false)) { - typeinfo += ('-' + get.translation(get.subtype(name, false))); - } - if (typeinfo) { - uiintro.add('
' + typeinfo + '
'); - } - if (lib.card[name].unique && lib.card[name].type == 'equip') { - if (lib.cardPile.guozhan && lib.cardPack.guozhan.includes(name)) { - uiintro.add('
专属装备
').style.marginTop = '-5px'; - } - else { - uiintro.add('
特殊装备
').style.marginTop = '-5px'; - } - } - if (lib.card[name] && lib.card[name].addinfomenu) { - uiintro.add('
' + lib.card[name].addinfomenu + '
'); - } - if (get.subtype(name, false) == 'equip1') { - var added = false; - if (lib.card[node.name] && lib.card[node.name].distance) { - var dist = lib.card[node.name].distance; - if (dist.attackFrom) { - added = true; - uiintro.add('
攻击范围:' + (-dist.attackFrom + 1) + '
'); - } - } - if (!added) { - uiintro.add('
攻击范围:1
'); - } - } - } - if (lib.card[name].cardPrompt) { - var str = lib.card[name].cardPrompt(node.link || node), placetext = uiintro.add('
' + str + '
'); - if (!str.startsWith('
' + lib.translate[name + '_info'] + '
'); - if (!lib.translate[name + '_info'].startsWith('
应变:${yingbianEffects.map(value => lib.yingbian.prompt.get(value)).join(';')}
`); - } - if (lib.translate[name + '_append']) { - uiintro.add('
' + lib.translate[name + '_append'] + '
'); - } - } - uiintro.add(ui.create.div('.placeholder.slim')); - } - } - else if (node.classList.contains('character')) { - const character = node.link, characterInfo = get.character(node.link); - let capt = get.translation(character); - if (characterInfo) { - const infoSex = characterInfo[0]; - if (infoSex && lib.config.show_sex) capt += `  ${infoSex == 'none' ? '无' : lib.translate[infoSex]}`; - const infoGroup = characterInfo[1]; - if (infoGroup && lib.config.show_group) { - const group = get.is.double(character, true); - if (group) capt += `  ${group.map(value => get.translation(value)).join('/')}`; - else capt += `  ${lib.translate[infoGroup]}`; - } - } - uiintro.add(capt); - - if (lib.characterTitle[node.link]) { - uiintro.addText(get.colorspan(lib.characterTitle[node.link])); - } - - if (node._banning) { - var clickBanned = function () { - var banned = lib.config[this.bannedname] || []; - if (banned.includes(character)) { - banned.remove(character); - } - else { - banned.push(character); - } - game.saveConfig(this.bannedname, banned); - this.classList.toggle('on'); - if (node.updateBanned) { - node.updateBanned(); - } - }; - var modeorder = lib.config.modeorder || []; - for (var i in lib.mode) { - modeorder.add(i); - } - var list = []; - uiintro.contentContainer.listen(function (e) { - ui.click.touchpop(); - e.stopPropagation(); - }); - for (var i = 0; i < modeorder.length; i++) { - if (node._banning == 'online') { - if (!lib.mode[modeorder[i]].connect) continue; - if (!lib.config['connect_' + modeorder[i] + '_banned']) { - lib.config['connect_' + modeorder[i] + '_banned'] = []; - } - } - else if (modeorder[i] == 'connect' || modeorder[i] == 'brawl') { - continue; - } - if (lib.config.all.mode.includes(modeorder[i])) { - list.push(modeorder[i]); - } - } - var page = ui.create.div('.menu-buttons.configpopped', uiintro.content); - var banall = false; - for (var i = 0; i < list.length; i++) { - var cfg = ui.create.div('.config', lib.translate[list[i]] + '模式', page); - cfg.classList.add('toggle'); - if (node._banning == 'offline') { - cfg.bannedname = list[i] + '_banned'; - } - else { - cfg.bannedname = 'connect_' + list[i] + '_banned'; - } - cfg.listen(clickBanned); - ui.create.div(ui.create.div(cfg)); - var banned = lib.config[cfg.bannedname] || []; - if (!banned.includes(character)) { - cfg.classList.add('on'); - banall = true; - } - } - if (node._banning == 'offline') { - var cfg = ui.create.div('.config', '随机选将可用', page); - cfg.classList.add('toggle'); - cfg.listen(function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - lib.config.forbidai_user.remove(character); - } - else { - lib.config.forbidai_user.add(character); - } - game.saveConfig('forbidai_user', lib.config.forbidai_user); - }); - ui.create.div(ui.create.div(cfg)); - if (!lib.config.forbidai_user.includes(character)) { - cfg.classList.add('on'); - } - } - ui.create.div('.menubutton.pointerdiv', banall ? '全部禁用' : '全部启用', uiintro.content, function () { - if (this.innerHTML == '全部禁用') { - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].bannedname && page.childNodes[i].classList.contains('on')) { - clickBanned.call(page.childNodes[i]); - } - } - this.innerHTML = '全部启用'; - } - else { - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].bannedname && !page.childNodes[i].classList.contains('on')) { - clickBanned.call(page.childNodes[i]); - } - } - this.innerHTML = '全部禁用'; - } - }).style.marginTop = '-10px'; - ui.create.div('.placeholder.slim', uiintro.content); - } - else { - var infoitem = get.character(character); - var skills = infoitem[3]; - for (i = 0; i < skills.length; i++) { - if (lib.translate[skills[i] + '_info']) { - if (lib.translate[skills[i] + '_ab']) translation = lib.translate[skills[i] + '_ab']; - else { - translation = get.translation(skills[i]); - if (!lib.skill[skills[i]].nobracket) translation = `【${translation.slice(0, 2)}】`; - } - - uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i]) + '
'); - - if (lib.translate[skills[i] + '_append']) { - uiintro._place_text = uiintro.add('
' + lib.translate[skills[i] + '_append'] + '
'); - } - } - } - var modepack = lib.characterPack['mode_' + get.mode()]; - if (lib.config.show_favourite && - lib.character[node.link] && (!modepack || !modepack[node.link]) && (!simple || get.is.phoneLayout())) { - var addFavourite = ui.create.div('.text.center.pointerdiv'); - addFavourite.link = node.link; - addFavourite.style.marginBottom = '15px'; - if (lib.config.favouriteCharacter.includes(node.link)) { - addFavourite.innerHTML = '移除收藏'; - } - else { - addFavourite.innerHTML = '添加收藏'; - } - addFavourite.listen(ui.click.favouriteCharacter); - uiintro.add(addFavourite); - } - else { - uiintro.add(ui.create.div('.placeholder.slim')); - } - var addskin = false; - if (node.parentNode.classList.contains('menu-buttons')) { - addskin = !lib.config.show_charactercard; - } - else { - addskin = lib.config.change_skin || lib.skin; - } - if (addskin && (!simple || get.is.phoneLayout())) { - var num = 1; - var introadded = false; - var nameskin = node.link; - var nameskin2 = nameskin; - var gzbool = false; - if (nameskin.startsWith('gz_shibing')) { - nameskin = nameskin.slice(3, 11); - } - else if (nameskin.startsWith('gz_')) { - nameskin = nameskin.slice(3); - gzbool = true; - } - var createButtons = function (num) { - if (!num) return; - if (!introadded) { - introadded = true; - uiintro.add('
更改皮肤
'); - } - var buttons = ui.create.div('.buttons.smallzoom.scrollbuttons'); - lib.setMousewheel(buttons); - for (var i = 0; i <= num; i++) { - var button = ui.create.div('.button.character.pointerdiv', buttons, function () { - if (this._link) { - lib.config.skin[nameskin] = this._link; - node.style.backgroundImage = this.style.backgroundImage; - game.saveConfig('skin', lib.config.skin); - } - else { - delete lib.config.skin[nameskin]; - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.setBackground(nameskin2, 'character'); - else node.setBackground(nameskin, 'character'); - game.saveConfig('skin', lib.config.skin); - } - }); - button._link = i; - if (i) { - button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); - } - else { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); - else button.setBackground(nameskin, 'character', 'noskin'); - } - } - uiintro.add(buttons); - }; - var loadImage = function () { - var img = new Image(); - img.onload = function () { - num++; - loadImage(); - }; - img.onerror = function () { - num--; - createButtons(num); - }; - img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; - }; - if (lib.config.change_skin) { - loadImage(); - } - else { - setTimeout(function () { - createButtons(lib.skin[nameskin]); - }); - } - } - } - } - else if (node.classList.contains('equips') && ui.arena.classList.contains('selecting')) { - (function () { - uiintro.add('选择装备'); - uiintro.addSmall(Array.from(node.childNodes).filter(node => !node.classList.contains('feichu')), true); - uiintro.clickintro = true; - ui.control.hide(); - uiintro._onclose = function () { - ui.control.show(); - }; - var confirmbutton; - for (var i = 0; i < uiintro.buttons.length; i++) { - var button = uiintro.buttons[i]; - button.classList.add('pointerdiv'); - if (button.link.classList.contains('selected')) { - button.classList.add('selected'); - } - button.listen(function (e) { - ui.click.card.call(this.link, 'popequip'); - ui.click.window.call(ui.window, e); - if (this.link.classList.contains('selected')) { - this.classList.add('selected'); - } - else { - this.classList.remove('selected'); - } - if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { - confirmbutton.classList.remove('disabled'); - } - else { - confirmbutton.classList.add('disabled'); - } - }); - } - var buttoncontainer = uiintro.add(ui.create.div()); - buttoncontainer.style.display = 'block'; - confirmbutton = ui.create.div('.menubutton.large.pointerdiv', '确定', function () { - if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { - uiintro._clickintro(); - ui.click.ok(ui.confirm.firstChild); - } - }, buttoncontainer); - confirmbutton.style.position = 'relative'; - setTimeout(function () { - if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { - confirmbutton.classList.remove('disabled'); - } - else { - confirmbutton.classList.add('disabled'); - } - }, 300); - }()); - } - else if (node.classList.contains('identity') && node.dataset.career) { - var career = node.dataset.career; - uiintro.add(get.translation(career)); - uiintro.add('
' + lib.translate['_' + career + '_skill_info'] + '
'); - } - else if (node.classList.contains('skillbar')) { - if (node == ui.friendBar) { - uiintro.add('友方怒气值'); - uiintro.add('
' + _status.friendRage + '/100
'); - } - else if (node == ui.enemyBar) { - uiintro.add('敌方怒气值'); - uiintro.add('
' + _status.enemyRage + '/100
'); - } - } - else if (node.parentNode == ui.historybar) { - if (node.dead) { - if (!node.source || node.source == node.player) { - uiintro.add('
' + get.translation(node.player) + '阵亡
'); - uiintro.addSmall([node.player]); - } - else { - uiintro.add('
' + get.translation(node.player) + '被' + get.translation(node.source) + '杀害
'); - uiintro.addSmall([node.source]); - } - } - if (node.skill) { - uiintro.add('
' + get.translation(node.skill, 'skill') + '
'); - uiintro._place_text = uiintro.add('
' + get.translation(node.skill, 'info') + '
'); - } - if (node.targets && get.itemtype(node.targets) == 'players') { - uiintro.add('
目标
'); - uiintro.addSmall(node.targets); - } - if (node.players && node.players.length > 1) { - uiintro.add('
使用者
'); - uiintro.addSmall(node.players); - } - if (node.cards && node.cards.length) { - uiintro.add('
卡牌
'); - uiintro.addSmall(node.cards); - } - for (var i = 0; i < node.added.length; i++) { - uiintro.add(node.added[i]); - } - if (node.added.length) { - uiintro.add(ui.create.div('.placeholder.slim')); - } - if (uiintro.content.firstChild) { - uiintro.content.firstChild.style.paddingTop = '3px'; - } - } - if (lib.config.touchscreen) { - lib.setScroll(uiintro.contentContainer); - } - return uiintro; - } - static linkintro(dialog, content, player) { - dialog.content.firstChild.remove(); - dialog.add('
已横置
'); - var list = []; - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isLinked() && game.players[i].name && !game.players[i].name.startsWith('unknown')) { - list.push(game.players[i]); - } - } - if (list.length) { - dialog.add(list, true, true); - } - } - static groups() { return ['wei', 'shu', 'wu', 'qun', 'jin', 'western', 'key']; } - static types() { - var types = []; - for (var i in lib.card) { - if (lib.card[i].mode && lib.card[i].mode.includes(lib.config.mode) == false) continue; - if (lib.card[i].forbid && lib.card[i].forbid.includes(lib.config.mode)) continue; - if (lib.card[i].type) { - if (lib.card[i].type == 'delay') types.add('trick'); - else types.add(lib.card[i].type); - } - } - return types; - } - static links(buttons) { - var links = []; - for (var i = 0; i < buttons.length; i++) { - if (buttons[i].link != undefined) links.push(buttons[i].link); - } - return links; - } - static threaten(target, player, hp) { - var threaten = 1; - var skills = target.getSkills(); - if (!player && player !== false) { - player = _status.event.player; - } - for (var i = 0; i < skills.length; i++) { - var info = get.info(skills[i]); - if (info && info.ai && info.ai.threaten) { - if (typeof info.ai.threaten == 'function' && player) { - var tmp = info.ai.threaten(player, target); - if (typeof tmp == 'number') { - threaten *= tmp; - } - } - else if (typeof info.ai.threaten == 'number') { - threaten *= info.ai.threaten; - } - } - } - if (hp) { - switch (target.hp) { - case 0: threaten *= 1.5; break; - case 1: threaten *= 1.2; break; - } - switch (target.countCards('h')) { - case 0: threaten *= 1.5; break; - case 1: threaten *= 1.2; break; - } - } - return threaten; - } - static condition(player) { - var num = player.hp; - if (num > 4) { - num = 4 + Math.sqrt(num - 4); - } - else { - if (player.isHealthy()) { - if (player.hp == 3) { - num += 0.5; - } - else if (player.hp < 3) { - num++; - } - } - } - num += player.countCards('h') / 2; - var es = player.getCards('e'); - for (var i = 0; i < es.length; i++) { - var val = get.equipValueNumber(es[i]); - if (val >= 7) num += 0.8; - if (val >= 5) num += 0.5; - if (val >= 3) num += 0.2; - } - return num; - } - static attitude(from, to) { - if (!from || !to) return 0; - from = from._trueMe || from; - arguments[0] = from; - var att = get.rawAttitude.apply(this, arguments); - if (from.isMad()) att = -att; - if (to.isMad() && att > 0) { - if (to.identity == 'zhu') { - att = 1; - } - else { - att = 0; - } - } - if (!_status.tempnofake) { - _status.tempnofake = true; - if (from.ai.modAttitudeFrom) { - att = from.ai.modAttitudeFrom(from, to, att); - } - if (to.ai.modAttitudeTo) { - att = to.ai.modAttitudeTo(from, to, att); - } - delete _status.tempnofake; - } - return att; - } - static sgnAttitude() { - return get.sgn(get.attitude.apply(this, arguments)); - } - static useful_raw(card, player) { - if (get.position(card) == 'j') return -1; - if (get.position(card) == 'e') return get.equipValue(card); - if (card._modUseful) { - return card._modUseful(); - } - var i = 0; - if (!player) player = _status.event.player; - if (player) { - if (_status.event.useCache) { - i = game.callFuncUseStepCache("player.getCardsInUseful", function (player, position, cardname) { - return player.getCards(position, cardname); - }, [player, 'h', card.name]).indexOf(card); - } else { - i = player.getCards('h', card.name).indexOf(card); - } - if (i < 0) i = 0; - } - var aii = get.info(card).ai; - var useful; - if (aii && aii.useful) useful = aii.useful; - else if (aii && aii.basic) useful = aii.basic.useful; - var result; - if (useful == undefined) result = -1; - else if (typeof useful == 'function') { - result = useful(card, i); - } - else if (typeof useful == 'number') result = useful; - else if (i < useful.length) { - result = useful[i]; - } - else result = useful[useful.length - 1]; - result = game.checkMod(player, card, result, 'aiUseful', player); - return result; - } - static useful(card, player) { - if (_status.event.useCache) { - return game.callFuncUseStepCache("get.useful_raw", get.useful_raw, [card, player]); - } - return get.useful_raw(card, player); - } - static unuseful(card) { return -get.useful(card); } - static unuseful2(card) { return 10 - get.useful(card); } - static unuseful3(card) { - if (card.name == 'du') return 20; - return 10 - get.useful(card); - } - static value(card, player, method) { - var result = 0; - var value; - if (Array.isArray(card)) { - if (!card.length) return 0; - value = 0; - for (var i = 0; i < card.length; i++) { - value += get.value(card[i], player, method); - } - return value / Math.sqrt(card.length); - } - if (card._modValue) { - return card._modValue(player, method); - } - var aii = get.info(card).ai; - if (aii && aii.value) value = aii.value; - else if (aii && aii.basic) value = aii.basic.value; - if (player == undefined || get.itemtype(player) != 'player') player = _status.event.player; - var geti = function () { - var num = 0, i; - var cards = player.getCards('hs', card.name); - if (cards.includes(card)) { - return cards.indexOf(card); - } - return cards.length; - }; - if (typeof value == 'function') { - result = value(card, player, geti(), method); - } - if (typeof value == 'number') result = value; - if (Array.isArray(value)) { - if (method == 'raw') result = value[0]; - var num = geti(); - if (num < value.length) result = value[num]; - else result = value[value.length - 1]; - } - result = game.checkMod(player, card, result, 'aiValue', player); - return result; - } - static equipResult(player, target, name) { - var card = get.card(); - if (!card || card.name != name) { - card = { name: name }; - } - var value1 = get.equipValue(card, target); - var value2 = 0; - if (!player.canEquip(card)) { - if (!player.canEquip(card, true)) return 0; - var current = target.getEquip(card); - if (current && current != card) { - value2 = get.equipValue(current, target); - if (value2 > 0 && !target.needsToDiscard() && !get.tag(card, 'valueswap')) { - return 0; - } - } - } - return Math.max(0, value1 - value2) / 5; - } - static equipValue(card, player) { - if (player == undefined || get.itemtype(player) != 'player') player = get.owner(card); - if (player == undefined || get.itemtype(player) != 'player') player = _status.event.player; - var info = get.info(card); - if (!info.ai) return 0; - var value = info.ai.equipValue; - if (value == undefined) { - if (info.ai.basic && info.ai.basic.equipValue != undefined) { - value = info.ai.basic.equipValue; - } - else return 0; - } - if (typeof value == 'number') return value; - if (typeof value == 'function') return value(card, player, null, 'raw2'); - return 0; - } - static equipValueNumber(card) { - var info = get.info(card); - if (info.ai) { - if (typeof info.ai.equipValue == 'number') return info.ai.equipValue; - if (info.ai.basic && typeof info.ai.basic.equipValue == 'number') return info.ai.basic.equipValue; - } - return 0; - } - static disvalue(card, player) { return -get.value(card, player); } - static disvalue2(card, player) { return -get.value(card, player, 'raw'); } - static skillthreaten(skill, player, target) { - if (!lib.skill[skill]) return 1; - if (!lib.skill[skill].ai) return 1; - var threaten = lib.skill[skill].ai.threaten; - if (typeof threaten == 'number') return threaten; - if (typeof threaten == 'function') { - player = player || _status.event.player; - target = target || player; - return threaten(player, target); - } - return 1; - } - static order(item) { - var info = get.info(item); - if (!info) return -1; - var aii = info.ai; - var order; - if (aii && aii.order) order = aii.order; - else if (aii && aii.basic) order = aii.basic.order; - if (order == undefined) return -1; - var num = order; - if (typeof (order) == 'function') { - num = order(item, _status.event.player); - } - if (typeof item == 'object' && _status.event.player) { - var player = _status.event.player; - num = game.checkMod(player, item, num, 'aiOrder', player); - } - return num; - } - static result(item, skill) { - var result; - var info = get.info(item); - if (info.ai) result = get.copy(info.ai.result); - if (typeof (result) == 'function') result = result(item); - if (!result) result = {}; - if (skill) { - var info2 = get.info(skill); - if (info2.ai) { - info2 = info2.ai.result; - for (var i in info2) { - result[i] = info2[i]; - } - } - } - return result; - } - static effect_use(target, card, player, player2, isLink) { - var event = _status.event; - var eventskill = null; - if (player == undefined) player = _status.event.player; - if (card && typeof card == 'object' && 'name' in card) card = get.autoViewAs(card); - if (typeof card != 'string' && (typeof card != 'object' || !card.name)) { - var skillinfo = get.info(event.skill); - if (event.skill && skillinfo.viewAs == undefined) card = _status.event.skill; - else { - card = get.card(); - if (skillinfo && skillinfo.viewAs && card.name === skillinfo.viewAs.name) { - eventskill = event.skill; - } - } - } - var info = get.info(card); - if (typeof card == 'object' && info && info.changeTarget) { - var targets = [target]; - info.changeTarget(player, targets); - var eff = 0; - for (var i of targets) { - eff += get.effect(i, card, player, player2, isLink); - } - return eff; - } - var result = get.result(card, eventskill); - var result1 = result.player_use || result.player, result2 = result.target_use || result.target; - if (typeof result1 == 'function') result1 = result1(player, target, card, isLink); - if (typeof result2 == 'function') result2 = result2(player, target, card, isLink); - - if (typeof result1 != 'number') result1 = 0; - if (typeof result2 != 'number') result2 = 0; - var temp1, temp2, temp3, temp01 = 0, temp02 = 0, threaten = 1; - var skills1 = player.getSkills().concat(lib.skill.global); - game.expandSkills(skills1); - var zerotarget = false, zeroplayer = false; - for (var i = 0; i < skills1.length; i++) { - temp1 = get.info(skills1[i]).ai; - if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player_use == 'function') { - temp1 = temp1.effect.player_use(card, player, target, result1, isLink); - } - else if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player == 'function') { - temp1 = temp1.effect.player(card, player, target, result1, isLink); - } - else temp1 = undefined; - if (typeof temp1 == 'object') { - if (temp1.length == 2 || temp1.length == 4) { - result1 *= temp1[0]; - temp01 += temp1[1]; - } - if (temp1.length == 4) { - result2 *= temp1[2]; - temp02 += temp1[3]; - } - } - else if (typeof temp1 == 'number') { - result1 *= temp1; - } - else if (temp1 == 'zeroplayer') { - zeroplayer = true; - } - else if (temp1 == 'zerotarget') { - zerotarget = true; - } - else if (temp1 == 'zeroplayertarget') { - zeroplayer = true; - zerotarget = true; - } - } - if (target) { - var skills2 = target.getSkills().concat(lib.skill.global); - game.expandSkills(skills2); - for (var i = 0; i < skills2.length; i++) { - temp2 = get.info(skills2[i]).ai; - if (temp2 && temp2.threaten) temp3 = temp2.threaten; - else temp3 = undefined; - if (temp2 && typeof temp2.effect == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = temp2.effect(card, player, target, result2, isLink); - else temp2 = undefined; - } - else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target_use == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = temp2.effect.target_use(card, player, target, result2, isLink); - else temp2 = undefined; - } - else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = temp2.effect.target(card, player, target, result2, isLink); - else temp2 = undefined; - } - else temp2 = undefined; - if (typeof temp2 == 'object') { - if (temp2.length == 2 || temp2.length == 4) { - result2 *= temp2[0]; - temp02 += temp2[1]; - } - if (temp2.length == 4) { - result1 *= temp2[2]; - temp01 += temp2[3]; - } - } - else if (typeof temp2 == 'number') { - result2 *= temp2; - } - else if (temp2 == 'zeroplayer') { - zeroplayer = true; - } - else if (temp2 == 'zerotarget') { - zerotarget = true; - } - else if (temp2 == 'zeroplayertarget') { - zeroplayer = true; - zerotarget = true; - } - if (typeof temp3 == 'function' && temp3(player, target) != undefined) { - threaten *= temp3(player, target); - } - else if (typeof temp3 == 'object') { - if (typeof temp3.target == 'number') { - threaten *= temp3; - } - else if (typeof temp3.target == 'function' && temp3(player, target) != undefined) { - threaten *= temp3(player, target); - } - } - else if (typeof temp3 == 'number') { - threaten *= temp3; - } - } - result2 += temp02; - result1 += temp01; - if (typeof card == 'object' && !result.ignoreStatus) { - if (get.attitude(player, target) < 0) { - result2 *= Math.sqrt(threaten); - } - else { - result2 *= Math.sqrt(Math.sqrt(threaten)); - } - if (target.hp == 1) result2 *= 2.5; - if (target.hp == 2) result2 *= 1.8; - if (target.countCards('h') == 0) { - if (get.tag(card, 'respondSha') || get.tag(card, 'respondShan')) { - result2 *= 1.7; - } - else { - result2 *= 1.5; - } - } - if (target.countCards('h') == 1) result2 *= 1.3; - if (target.countCards('h') == 2) result2 *= 1.1; - if (target.countCards('h') > 3) result2 *= 0.5; - if (target.hp == 4) result2 *= 0.9; - if (target.hp == 5) result2 *= 0.8; - if (target.hp > 5) result2 *= 0.6; - } - } - else { - result2 += temp02; - result1 += temp01; - } - if (zeroplayer) result1 = 0; - if (zerotarget) result2 = 0; - var final = 0; - if (player2) { - final = (result1 * get.attitude(player2, player) + (target ? result2 * get.attitude(player2, target) : 0)); - } - else final = (result1 * get.attitude(player, player) + (target ? result2 * get.attitude(player, target) : 0)); - if (!isLink && get.tag(card, 'natureDamage') && !zerotarget) { - var info = get.info(card); - if (!info || !info.ai || !info.ai.canLink) { - if (target.isLinked()) game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); - }); - } - else if (info.ai.canLink(player, target, card)) { - game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); - }); - } - } - return final; - } - static effect(target, card, player, player2, isLink) { - var event = _status.event; - var eventskill = null; - if (player == undefined) player = _status.event.player; - if (card && typeof card == 'object' && 'name' in card) card = get.autoViewAs(card); - if (typeof card != 'string' && (typeof card != 'object' || !card.name)) { - var skillinfo = get.info(event.skill); - if (event.skill && skillinfo.viewAs == undefined) card = _status.event.skill; - else { - card = get.card(); - if (skillinfo && skillinfo.viewAs && card.name === skillinfo.viewAs.name) { - eventskill = event.skill; - } - } - } - var result = get.result(card, eventskill); - var result1 = result.player, result2 = result.target; - if (typeof result1 == 'function') result1 = result1(player, target, card, isLink); - if (typeof result2 == 'function') result2 = result2(player, target, card, isLink); - - if (typeof result1 != 'number') result1 = 0; - if (typeof result2 != 'number') result2 = 0; - var temp1, temp2, temp3, temp01 = 0, temp02 = 0, threaten = 1; - var skills1 = player.getSkills().concat(lib.skill.global); - game.expandSkills(skills1); - var zerotarget = false, zeroplayer = false; - for (var i = 0; i < skills1.length; i++) { - temp1 = get.info(skills1[i]).ai; - if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player == 'function') { - temp1 = temp1.effect.player(card, player, target, result1, isLink); - } - else temp1 = undefined; - if (typeof temp1 == 'object') { - if (temp1.length == 2 || temp1.length == 4) { - result1 *= temp1[0]; - temp01 += temp1[1]; - } - if (temp1.length == 4) { - result2 *= temp1[2]; - temp02 += temp1[3]; - } - } - else if (typeof temp1 == 'number') { - result1 *= temp1; - } - else if (temp1 == 'zeroplayer') { - zeroplayer = true; - } - else if (temp1 == 'zerotarget') { - zerotarget = true; - } - else if (temp1 == 'zeroplayertarget') { - zeroplayer = true; - zerotarget = true; - } - } - if (target) { - var skills2 = target.getSkills().concat(lib.skill.global); - game.expandSkills(skills2); - for (var i = 0; i < skills2.length; i++) { - temp2 = get.info(skills2[i]).ai; - if (temp2 && temp2.threaten) temp3 = temp2.threaten; - else temp3 = undefined; - if (temp2 && typeof temp2.effect == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = temp2.effect(card, player, target, result2, isLink); - else temp2 = undefined; - } - else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = temp2.effect.target(card, player, target, result2, isLink); - else temp2 = undefined; - } - else temp2 = undefined; - if (typeof temp2 == 'object') { - if (temp2.length == 2 || temp2.length == 4) { - result2 *= temp2[0]; - temp02 += temp2[1]; - } - if (temp2.length == 4) { - result1 *= temp2[2]; - temp01 += temp2[3]; - } - } - else if (typeof temp2 == 'number') { - result2 *= temp2; - } - else if (temp2 == 'zeroplayer') { - zeroplayer = true; - } - else if (temp2 == 'zerotarget') { - zerotarget = true; - } - else if (temp2 == 'zeroplayertarget') { - zeroplayer = true; - zerotarget = true; - } - if (typeof temp3 == 'function' && temp3(player, target) != undefined) { - threaten *= temp3(player, target); - } - else if (typeof temp3 == 'object') { - if (typeof temp3.target == 'number') { - threaten *= temp3; - } - else if (typeof temp3.target == 'function' && temp3(player, target) != undefined) { - threaten *= temp3(player, target); - } - } - else if (typeof temp3 == 'number') { - threaten *= temp3; - } - } - result2 += temp02; - result1 += temp01; - if (typeof card == 'object' && !result.ignoreStatus) { - if (get.attitude(player, target) < 0) { - result2 *= Math.sqrt(threaten); - } - else { - result2 *= Math.sqrt(Math.sqrt(threaten)); - } - // *** continue here *** - if (target.hp == 1) result2 *= 2.5; - if (target.hp == 2) result2 *= 1.8; - if (target.countCards('h') == 0) { - if (get.tag(card, 'respondSha') || get.tag(card, 'respondShan')) { - result2 *= 1.7; - } - else { - result2 *= 1.5; - } - } - if (target.countCards('h') == 1) result2 *= 1.3; - if (target.countCards('h') == 2) result2 *= 1.1; - if (target.countCards('h') > 3) result2 *= 0.5; - if (target.hp == 4) result2 *= 0.9; - if (target.hp == 5) result2 *= 0.8; - if (target.hp > 5) result2 *= 0.6; - } - } - else { - result2 += temp02; - result1 += temp01; - } - if (zeroplayer) result1 = 0; - if (zerotarget) result2 = 0; - var final = 0; - if (player2) { - final = (result1 * get.attitude(player2, player) + (target ? result2 * get.attitude(player2, target) : 0)); - } - else final = (result1 * get.attitude(player, player) + (target ? result2 * get.attitude(player, target) : 0)); - if (!isLink && get.tag(card, 'natureDamage') && !zerotarget) { - var info = get.info(card); - if (!info || !info.ai || !info.ai.canLink) { - if (target.isLinked()) game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); - }); - } - else if (info.ai.canLink(player, target, card)) { - game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); - }); - } - } - return final; - } - static damageEffect(target, player, viewer, nature) { - if (get.itemtype(nature) == 'natures') { - var natures = get.natureList(nature); - return natures.map(n => get.damageEffect(target, player, viewer, n)).reduce((p, c) => p + c, 0) / (natures.length || 1); - } - if (!player) { - player = target; - } - if (!viewer) { - viewer = target; - } - var name = 'damage'; - if (nature == 'fire') { - name = 'firedamage'; - } - else if (nature == 'thunder') { - name = 'thunderdamage'; - } - else if (nature == 'ice') { - name = 'icedamage'; - } - var eff = get.effect(target, { name: name }, player, viewer); - if (eff > 0 && target.hujia > 0) return eff / 1.3; - return eff; - } - static recoverEffect(target, player, viewer) { - if (target.hp == target.maxHp) return 0; - if (!player) { - player = target; - } - if (!viewer) { - viewer = target; - } - return get.effect(target, { name: 'recover' }, player, viewer); - } - static buttonValue(button) { - var card = button.link; - var player = get.owner(card); - if (!player) player = _status.event.player; - if (player.getCards('j').includes(card)) { - var efff = get.effect(player, { - name: card.viewAs || card.name, - cards: [card], - }, player, player); - if (efff > 0) return 0.5; - if (efff == 0) return 0; - return -1.5; - } - if (player.getCards('e').includes(card)) { - var evalue = get.value(card, player); - if (player.hasSkillTag('noe')) { - if (evalue >= 7) { - return evalue / 6; - } - return evalue / 10; - } - return evalue / 3; - } - if (player.hasSkillTag('noh')) return 0.1; - var nh = player.countCards('h'); - switch (nh) { - case 1: return 2; - case 2: return 1.6; - case 3: return 1; - case 4: return 0.8; - case 5: return 0.6; - default: return 0.4; - } - } - static attitude2(to) { return get.attitude(_status.event.player, to); } -} - -export const get = Get; - -export { - Is -}; +import { userAgent, Uninstantable, GeneratorFunction, AsyncFunction } from "../util/index.js"; +import { AI as ai } from '../ai/index.js'; +import { Game as game } from '../game/index.js'; +import { Library as lib } from '../library/index.js'; +import { status as _status } from '../status/index.js'; +import { UI as ui } from '../ui/index.js'; +import { GNC as gnc } from '../gnc/index.js'; + +import { Is } from "./is.js"; + +export class Get extends Uninstantable { + static is = Is; + /** + * 获取当前内核版本信息 + * + * 目前仅考虑`chrome`, `firefox`和`safari`三种浏览器的信息,其余均归于其他范畴 + * + * > 其他后续或许会增加,但`IE`永无可能 + * + * @returns {["firefox" | "chrome" | "safari" | "other", number]} + */ + static coreInfo() { + const regex = /(firefox|chrome|safari)\/([\d.]+)/; + let result; + if (!(result = userAgent.match(regex))) return ["other", NaN]; + if (result[1] != "safari") return [result[1], parseInt(result[2])]; + result = userAgent.match(/version\/([\d.]+).*safari/); + return ["safari", parseInt(result[1])]; + } + /** + * 返回 VCard[] 形式的所有牌,用于印卡将遍历 + * @param {Function} filter + * @returns {string[][]} + */ + static inpileVCardList(filter) { + let list = []; + for (const name of lib.inpile) { + const type = get.type(name); + const info = [type, '', name]; + if (!filter || filter(info)) list.push(info); + if (name == 'sha') { + for (const nature of lib.inpile_nature) { + const info = [type, '', name, nature]; + if (!filter || filter(info)) list.push(info); + } + } + } + return list; + } + /** + * 根据座次数n(从0开始)获取对应的“n+1号位”翻译 + * @param {number} seat + */ + static seatTranslation(seat) { return `${get.cnNumber(seat + 1, true)}号位`; } + /** + * @param {number} numberOfPlayers + * @returns {string[]} + */ + static identityList(numberOfPlayers) { + const modeConfig = lib.config.mode_config; + if (modeConfig) { + const identityConfig = modeConfig.identity; + if (identityConfig) { + const identityLists = identityConfig.identity; + if (identityLists) { + const identityList = identityLists[numberOfPlayers - 2]; + if (Array.isArray(identityList)) return identityList.slice(); + } + } + } + const numberOfPlayersExceptLord = numberOfPlayers - 1, numberOfLoyalists = Math.round(numberOfPlayersExceptLord * 3 / 9), numberOfSpys = Math.round(numberOfPlayersExceptLord * 2 / 9); + return ['zhu'].concat(Array.from({ + length: numberOfLoyalists + }, () => 'zhong'), Array.from({ + length: numberOfSpys + }, () => 'nei'), Array.from({ + length: numberOfPlayersExceptLord - numberOfLoyalists - numberOfSpys + }, () => 'fan')); + } + /** + * Generate an object URL from the Base64-encoded octet stream + * + * 从Base64编码的八位字节流生成对象URL + */ + static objectURL(octetStream) { + const objectURLMap = lib.objectURL; + if (objectURLMap.has(octetStream)) return objectURLMap.get(octetStream); + const objectURL = URL.createObjectURL(new Blob([Uint8Array.from(atob(octetStream.replace(/^data:[\s\S]*\/[\s\S]*;base64,/, '')), character => character.charCodeAt())])); + objectURLMap.set(octetStream, objectURL); + return objectURL; + } + /** + * Get the card name length + * + * 获取此牌的字数 + */ + static cardNameLength(card, player) { + const actualCardName = lib.actualCardName, name = get.translation(typeof card == 'string' ? card : get.name(card, player)); + return (actualCardName.has(name) ? actualCardName.get(name) : name).length; + } + //Yingbian + //应变 + /** + * Get the Yingbian conditions (of the card) + * + * 获取(此牌的)应变条件 + */ + static yingbianConditions(card) { return get.complexYingbianConditions(card).concat(get.simpleYingbianConditions(card)); } + static complexYingbianConditions(card) { + const complexYingbianConditions = Array.from(lib.yingbian.condition.complex.keys()); + return card ? complexYingbianConditions.filter(value => get.cardtag(card, `yingbian_${value}`)) : complexYingbianConditions; + } + static simpleYingbianConditions(card) { + const simpleYingbianConditions = Array.from(lib.yingbian.condition.simple.keys()); + return card ? simpleYingbianConditions.filter(value => get.cardtag(card, `yingbian_${value}`)) : simpleYingbianConditions; + } + /** + * Get the Yingbian effects (of the card) + * + * 获取(此牌的)应变效果 + */ + static yingbianEffects(card) { + const yingbianEffects = Array.from(lib.yingbian.effect.keys()); + return card ? yingbianEffects.filter(value => get.cardtag(card, `yingbian_${value}`)) : yingbianEffects; + } + /** + * Get the default Yingbian effect of the card + * + * 获取此牌的默认应变效果 + */ + static defaultYingbianEffect(card) { + const info = get.info(card); + return info && info.defaultYingbianEffect || null; + } + /** + * 优先度判断 + */ + static priority(skill) { + const info = get.info(skill); + if (!info) return 0; + if ('_priority' in info) return info._priority; + let priority = 0; + if (info.priority) { + priority = info.priority * 100; + } + if (info.silent) { + priority++; + } + if (info.equipSkill) priority -= 25; + if (info.cardSkill) priority -= 50; + if (info.ruleSkill) priority -= 75; + info._priority = priority; + return priority; + } + /** + * 新装备栏相关 + * + * 获取一张装备牌实际占用的装备栏(君曹操六龙) + * + * 用法同get.subtype,返回数组 + */ + static subtypes(obj, player) { + if (typeof obj == 'string') obj = { name: obj }; + if (typeof obj != 'object') return; + var name = get.name(obj, player); + if (!lib.card[name]) return []; + if (lib.card[name].subtypes) { + const subtypes = get.copy(lib.card[name].subtypes); + return subtypes; + } + else if (lib.card[name].subtype) { + const subtype = lib.card[name].subtype; + return [subtype]; + } + return []; + } + //装备栏 END + /** + * @returns { string[] } + */ + static pinyin(chinese, withTone) { + const pinyinUtilx = window.pinyinUtilx; + if (!pinyinUtilx) return []; + const pinyins = lib.pinyins; + if (pinyins) { + const pinyin = pinyins[chinese]; + if (Array.isArray(pinyin)) return withTone === false ? pinyin.map(pinyinUtilx.removeTone) : pinyin.slice(); + } + return pinyinUtilx.getPinyin(chinese, null, withTone, true); + } + static yunmu(str) { + //部分整体认读音节特化处理 + const util = window.pinyinUtilx; + if (util && lib.pinyins._metadata.zhengtirendu.includes(util.removeTone(str))) { + return '-' + str[str.length - 1]; + } + //排除声母 + for (let i of lib.pinyins._metadata.shengmu) { + if (str.startsWith(i)) { + str = str.slice(i.length); + if (str[0] == 'u' && lib.pinyins._metadata.special_shengmu.includes(i)) str = 'ü' + str.slice(1); + break; + } + } + //排除介母 + if (str.length > 0) { + for (let i in lib.pinyins._metadata.feijiemu) { + if (str[0] == i) { + let goon = false; + for (let j of lib.pinyins._metadata.feijiemu[i]) { + if (str.startsWith(j)) goon = true; + } + if (!goon) str = str.slice(1); + break; + } + } + } + return str; + } + /** + * 用于将参数转换为字符串,作为缓存的key。 + */ + static paramToCacheKey() { + var str = ""; + for (var arg of arguments) { + if (arg === null || arg === undefined) { + str += (arg + "-"); + continue; + } + if (arg.playerid) { + str += "p:" + arg.playerid; + } else if (arg.cardid) { + str += "c:" + arg.cardid; + } else if (arg.name) { + str += "n:" + arg.name; + } else { + str += "s:" + arg; + } + str += "-"; + } + return str; + } + static yunjiao(str) { + const util = window.pinyinUtilx; + if (util) str = util.removeTone(str); + if (lib.pinyins._metadata.zhengtirendu.includes(str)) { + str = ('-' + str[str.length - 1]); + } + else { + for (let i of lib.pinyins._metadata.shengmu) { + if (str.startsWith(i)) { + str = str.slice(i.length); + if (str[0] == 'u' && lib.pinyins._metadata.special_shengmu.includes(i)) str = 'ü' + str.slice(1); + break; + } + } + } + for (let i in lib.pinyins._metadata.yunjiao) { + if (lib.pinyins._metadata.yunjiao[i].includes(str)) return i; + } + return null; + } + static skillCategoriesOf(skill, player) { + var list = [], info = get.info(skill); + if (!info) return list; + if (get.is.locked(skill, player)) list.add('锁定技'); + if (info.zhuSkill) list.add('主公技'); + if (info.limited) list.add('限定技'); + if (info.juexingji) list.add('觉醒技'); + if (info.zhuanhuanji) list.add('转换技'); + if (info.hiddenSkill) list.add('隐匿技'); + if (info.clanSkill) list.add('宗族技'); + if (info.groupSkill) list.add('势力技'); + if (info.dutySkill) list.add('使命技'); + if (info.chargeSkill) list.add('蓄力技'); + if (info.zhenfa) list.add('阵法技'); + if (info.mainSkill) list.add('主将技'); + if (info.viceSkill) list.add('副将技'); + if (info.lordSkill) list.add('君主技'); + if (info.chargingSkill) list.add('蓄能技'); + if (info.charlotte) list.add('Charlotte'); + if (info.sunbenSkill) list.add('昂扬技'); + if (info.categories) list.addArray(info.categories(skill, player)); + return list; + } + static numOf(obj, item) { return obj.filter(element => element == item).length; } + static connectNickname() { return typeof lib.config.connect_nickname == 'string' ? (lib.config.connect_nickname.slice(0, 12)) : "无名玩家"; } + static zhinangs(filter) { + var list = (_status.connectMode ? lib.configOL : lib.config).zhinang_tricks; + if (!list || !list.filter || !list.length) return get.inpile('trick', 'trick').randomGets(3); + if (filter === false) return list.slice(0); + list = list.filter(card => lib.inpile.includes(card)); + if (list.length) return list; + return get.inpile('trick', 'trick').randomGets(3); + } + static sourceCharacter(str) { + if (str) { + for (var i in lib.characterReplace) { + if (lib.characterReplace[i].includes(str)) return i; + } + } + return str; + } + static isLuckyStar(player) { + if (player && player.hasSkillTag('luckyStar')) return true; + if (_status.connectMode) return false; + return (!player || player == game.me || player.isUnderControl()) && lib.config.lucky_star == true; + } + static infoHp(hp) { + if (typeof hp == 'number') return hp; + else if (typeof hp == 'string' && hp.includes('/')) { + return parseInt(hp.split('/')[0]); + } + return 0; + } + static infoMaxHp(hp) { + if (typeof hp == 'number') return hp; + else if (typeof hp == 'string' && hp.includes('/')) { + return parseInt(hp.split('/')[1]); + } + return 0; + } + static infoHujia(hp) { + if (typeof hp == 'string' && hp.includes('/')) { + var splited = hp.split('/'); + if (splited.length > 2) return parseInt(splited[2]); + } + return 0; + } + static bottomCards(num, putBack) { + if (_status.waitingForCards) { + ui.create.cards.apply(ui.create, _status.waitingForCards); + delete _status.waitingForCards; + } + var list = []; + var card = false; + if (typeof num != 'number') num = 1; + if (num == 0) { card = true; num = 1; } + if (num < 0) num = 1; + while (num--) { + if (ui.cardPile.hasChildNodes() == false) { + game.washCard(); + } + if (ui.cardPile.hasChildNodes() == false) { + game.over('平局'); + return []; + } + var cardx = ui.cardPile.removeChild(ui.cardPile.lastChild); + cardx.original = 'c'; + list.push(cardx); + } + if (putBack) { + for (let i = list.length - 1; i >= 0; i--) { + ui.cardPile.appendChild(list[i]); + } + } + game.updateRoundNumber(); + if (card) return list[0]; + return list; + } + static discarded() { return _status.discarded.filter(item => item.parentNode == ui.discardPile); } + static cardOffset() { + var x = ui.arena.getBoundingClientRect(); + var y = ui.window.getBoundingClientRect(); + return -y.width / 2 + (x.left + x.width / 2); + } + static colorspan(str) { + if (str[0] == '#') { + var color; + switch (str[1]) { + case 'r': color = 'fire'; break; + case 'p': color = 'legend'; break; + case 'b': color = 'blue'; break; + case 'g': color = 'green'; break; + default: return str.slice(2); + } + return '' + str.slice(2) + ''; + } + return str; + } + static evtprompt(next, str) { + if (next.prompt) { + next.set('prompt2', str); + } + else { + if (str.startsWith('###')) { + var prompts = str.slice(3).split('###'); + if (prompts[0]) next.set('prompt', prompts[0]); + if (prompts[1]) next.set('prompt2', prompts[1]); + } + else { + next.set('prompt', str); + } + } + } + static autoViewAs(card, cards) { return new lib.element.VCard(card, cards); } + /** + * @deprecated + */ + static _autoViewAs(card, cards) { + var info = get.info(card); + if (info.autoViewAs) { + if (cards === false) { + return { + name: info.autoViewAs, + }; + } + else if (Array.isArray(cards)) { + return { + name: info.autoViewAs, + cards: cards.slice(0), + }; + } + else if (get.itemtype(card) == 'card') { + return { + name: info.autoViewAs, + cards: [card], + }; + } + else { + return { + name: info.autoViewAs, + suit: card.suit, + number: card.number, + nature: card.nature, + }; + } + } + else { + if (card.isCard || get.itemtype(card) == 'card') { + var next = { + name: get.name(card), + suit: get.suit(card), + number: get.number(card), + nature: get.nature(card), + isCard: true, + cardid: card.cardid, + wunature: card.wunature, + storage: get.copy(card.storage), + cards: get.copy(card.cards), + }; + if (get.itemtype(cards) == 'cards' && !card.cards) next.cards = cards.slice(0); + else if (get.itemtype(card) == 'card') next.cards = [card]; + return next; + } + else if (get.is.object(card) && get.itemtype(cards) == 'cards' && !card.cards) { + card = get.copy(card); + card.cards = cards.slice(0); + } + return card; + } + } + static max(list, func, type) { + list = list.slice(0); + if (typeof func == 'string') { + var key = func; + func = function (item) { + return item[key]; + }; + } + list.sort(function (a, b) { + return func(b) - func(a); + }); + if (type == 'list') { + var list2 = []; + for (var i = 0; i < list.length; i++) { + if (func(list[i]) == func(list[0])) { + list2.push(list[i]); + } + } + return list2; + } + else if (type == 'item') { + return list[0]; + } + else { + return func(list[0]); + } + } + static min(list, func, type) { + list = list.slice(0); + if (typeof func == 'string') { + var key = func; + func = function (item) { + return item[key]; + }; + } + list.sort(function (a, b) { + return func(a) - func(b); + }); + if (type == 'list') { + var list2 = []; + for (var i = 0; i < list.length; i++) { + if (func(list[i]) == func(list[0])) { + list2.push(list[i]); + } + } + return list2; + } + else if (type == 'item') { + return list[0]; + } + else { + return func(list[0]); + } + } + /** + * @overload + * @param { string } name + * @returns { Character } + */ + /** + * @template { 0 | 1 | 2 | 3 | 4 } T + * @overload + * @param { string } name + * @param { T } num + * @returns { Character[T] } + */ + static character(name, num) { + let info = lib.character[name]; + if (!info) { + const pack = Object.keys(lib.characterPack).find(pack => name in lib.characterPack[pack]); + if (pack) info = lib.characterPack[pack][name]; + } + if (typeof num === 'number') { + if (!info) info = []; + if (info[num]) return info[num]; + if (num === 3 || num === 4) return []; + return; + } + return info; + } + static characterIntro(name) { + if (lib.characterIntro[name]) return lib.characterIntro[name]; + var tags = get.character(name, 4); + if (tags) { + for (var i = 0; i < tags.length; i++) { + if (tags[i].startsWith('des:')) { + return tags[i].slice(4); + } + } + } + while (name.includes('_') && !lib.characterIntro[name]) { + name = name.slice(name.indexOf('_') + 1); + } + if (lib.characterIntro[name]) return lib.characterIntro[name]; + return '暂无武将介绍'; + } + static bordergroup(info, raw) { + if (!Array.isArray(info)) { + info = lib.character[info]; + if (!info) return ''; + } + if (Array.isArray(info[4])) for (const str of info[4]) { + if (typeof str == 'string' && str.startsWith('border:')) return str.slice(7); + } + return raw ? '' : info[1] || ''; + } + static groupnature(group, method) { + var nature = lib.groupnature[group]; + if (!nature) return ''; + if (method == 'raw') { + return nature; + } + return nature + 'mm'; + } + static sgn(num) { + if (num > 0) return 1; + if (num < 0) return -1; + return 0; + } + static rand(num, num2) { + if (typeof num2 == 'number') { + return num + Math.floor(Math.random() * (num2 - num + 1)); + } + else { + return Math.floor(Math.random() * num); + } + } + static sort(arr, method, arg) { return method == "seat" ? arr.sortBySeat(arg) : void 0; } + static sortSeat(arr, target) { return arr.sortBySeat(target); } + static zip(callback) { + if (!window.JSZip) { + lib.init.js(lib.assetURL + 'game', 'jszip', function () { + callback(new JSZip()); + }); + } + else { + callback(new JSZip()); + } + } + static delayx(num, max) { + if (typeof num != 'number') num = 1; + if (typeof max != 'number') max = Infinity; + switch (lib.config.game_speed) { + case 'vslow': return Math.min(max, 2.5 * num); + case 'slow': return Math.min(max, 1.5 * num); + case 'fast': return Math.min(max, 0.7 * num); + case 'vfast': return Math.min(max, 0.4 * num); + case 'vvfast': return Math.min(max, 0.2 * num); + default: return Math.min(max, num); + } + } + static prompt(skill, target, player) { + player = player || _status.event.player; + if (target) { + var str = get.translation(target); + if (target == player) { + str += '(你)'; + } + return '是否对' + str + '发动【' + get.skillTranslation(skill, player) + '】?'; + } + else { + return '是否发动【' + get.skillTranslation(skill, player) + '】?'; + } + } + static prompt2(skill, target, player) { + var str = get.prompt.apply(this, arguments); + if (!lib.translate[skill + '_info']) return str; + return '###' + str + '###' + lib.translate[skill + '_info']; + } + static url(master) { + var url = lib.config.updateURL || lib.updateURL; + if (url[url.length - 1] != '/') { + url += '/'; + } + if (master != 'nodev') { + return url + 'master/'; + } + else { + return url + 'v' + lib.version + '/'; + } + } + static round(num, f) { + var round = Math.pow(10, f); + return Math.round(num * round) / round; + } + static playerNumber() { + var num; + if (_status.brawl && _status.brawl.playerNumber) { + num = _status.brawl.playerNumber; + } + else { + num = get.config('player_number'); + } + return parseInt(num) || 2; + } + static benchmark(func1, func2, iteration, arg) { + var tic, toc; + var key1, key2; + if (!arg) arg = []; + if (Array.isArray(func2)) { + key1 = func2[0]; + key2 = func2[1]; + } + else if (typeof func2 == 'string') { + key1 = func2; + func2 = iteration || 100; + } + else if (typeof func2 == 'number') { + arg = iteration || arg; + iteration = func2; + } + tic = get.utc(); + for (var i = 0; i < iteration; i++) { + if (key1) { + func1[key1](arg.randomGet()); + } + else { + func1(arg.randomGet()); + } + } + toc = get.utc(); + if (typeof func2 == 'number') { + return toc - tic; + } + console.log('time1: ' + (toc - tic)); + tic = get.utc(); + for (var i = 0; i < iteration; i++) { + if (key2) { + func1[key2](arg.randomGet()); + } + else { + func2(arg.randomGet()); + } + } + toc = get.utc(); + console.log('time2: ' + (toc - tic)); + } + static stringify(obj, level) { + level = level || 0; + var indent = ''; + var str; + for (var i = 0; i < level; i++) { + indent += ' '; + } + if (get.objtype(obj) == 'object') { + str = '{\n'; + for (var i in obj) { + var insertDefaultString; + var insertFunctionString = indent + ' ' + get.stringify(obj[i], level + 1) + ',\n'; + var parseFunction = i => { + var string = obj[i].toString(); + var execResult; + if (obj[i] instanceof GeneratorFunction) { + // *content(){} + execResult = new RegExp(`\\*\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]); + if (execResult && execResult.index === 0) { + return insertFunctionString; + } + // content:function*(){} + else { + return insertDefaultString; + } + } + else if (obj[i] instanceof AsyncFunction) { + execResult = new RegExp(`async\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]); + // async content(){} + if (execResult && execResult.index === 0) { + return insertFunctionString; + } + // content:async function(){} + else { + return insertDefaultString; + } + } else { + execResult = new RegExp(`${i}[\\s\\S]*?\\(`).exec(obj[i]); + // content(){} + if (execResult && execResult.index === 0) { + return insertFunctionString; + } + // content:function(){} + else { + return insertDefaultString; + } + } + }; + if (/[^a-zA-Z]/.test(i)) { + insertDefaultString = indent + ' "' + i + '":' + get.stringify(obj[i], level + 1) + ',\n'; + if (typeof obj[i] !== 'function') { + str += insertDefaultString; + } else { + str += parseFunction(i); + } + } + else { + insertDefaultString = indent + ' ' + i + ':' + get.stringify(obj[i], level + 1) + ',\n'; + if (typeof obj[i] !== 'function') { + str += insertDefaultString; + } else { + str += parseFunction(i); + } + } + } + str += indent + '}'; + return str; + } + else { + if (typeof obj == 'function') { + str = obj.toString(); + str = str.replace(/\t/g, ' '); + var i = str.lastIndexOf('\n'); + var num = 0; + for (var j = i + 1; j < str.length && str[j] == ' '; j++) { + num++; + } + num = Math.floor(num / 4); + for (i = 0; i < num - level; i++) { + str = str.replace(/\n {4}/g, '\n'); + } + } + else { + try { + if (Array.isArray(obj) && obj.includes(Infinity)) { + obj = obj.slice(0); + var rand = get.id(); + for (var i = 0; i < obj.length; i++) { + if (obj[i] === Infinity) { + obj[i] = parseInt(rand); + } + } + str = JSON.stringify(obj).replace(new RegExp(rand, 'g'), 'Infinity'); + } + else { + str = JSON.stringify(obj) || ''; + } + } + catch (e) { + str = ''; + } + } + return str; + } + } + /** + * 深拷贝函数(虽然只处理了部分情况) + * + * 除了普通的Object和NullObject,均不考虑自行赋值的数据,但会原样将Symbol复制过去 + * + * @template T + * @param {T} obj - 要复制的对象,若不是对象则直接返回原值 + * @param {boolean} [copyKeyDeep = false] - 是否深复制`Map`的`key` + * @param {WeakMap} [map] - 拷贝用的临时存储,用于处理循环引用(请勿自行赋值) + * @returns {T} - 深拷贝后的对象,若传入值不是对象则为传入值 + */ + static copy(obj, copyKeyDeep = false, map = new WeakMap()) { + // 参考[这里](https://juejin.cn/post/7315612852890026021)实现深拷贝 + // 不再判断是否能structuredClone是因为structuredClone会把Symbol给毙了 + const getType = (obj) => Object.prototype.toString.call(obj); + + const canTranverse = { + "[object Map]": true, + "[object Set]": true, + "[object Object]": true, + "[object Array]": true, + "[object Arguments]": true, + }; + + if (typeof obj !== "object" || obj === null || !canTranverse[getType(obj)]) + return obj; + + // @ts-ignore + if (map.has(obj)) return map.get(obj); + + const constructor = obj.constructor; + // @ts-ignore + const target = + constructor + ? ( + // 这三类数据处理单独处理 + // (实际上需要处理的只有Map和Set) + // 除此之外的就只能祝愿有拷贝构造函数了 + (Array.isArray(obj) || obj instanceof Map || obj instanceof Set) + // @ts-ignore + ? new constructor() + // @ts-ignore + : new constructor(obj) + ) + : Object.create(null); + map.set(obj, target); + + if (obj instanceof Map) { + obj.forEach((value, key) => { + target.set(copyKeyDeep ? get.copy(key, copyKeyDeep, map) : key, get.copy(value, copyKeyDeep, map)); + }); + } else if (obj instanceof Set) { + obj.forEach((value) => { + target.add(get.copy(value, copyKeyDeep, map)); + }); + } + + const descriptors = Object.getOwnPropertyDescriptors(obj); + if (descriptors) { + for (const [key, descriptor] of Object.entries(descriptors)) { + const { enumerable, configurable } = descriptor; + if (obj.hasOwnProperty(key)) { + const result = { enumerable, configurable }; + if (descriptor.hasOwnProperty('value')) { + result.value = get.copy(descriptor.value, copyKeyDeep, map); + result.writable = descriptor.writable; + } else { + const { get, set } = descriptor; + result.get = get; + result.set = set; + } + Reflect.defineProperty(target, key, result); + } + } + } + + const symbols = Object.getOwnPropertySymbols(obj); + symbols.forEach((symbol) => { + target[symbol] = get.copy(obj[symbol], copyKeyDeep, map); + }); + + return target; + } + static inpilefull(type) { + var list = []; + for (var i in lib.cardPile) { + for (var j = 0; j < lib.cardPile[i].length; j++) { + var info = lib.cardPile[i][j]; + if (lib.inpile.includes(info[2]) && get.type(info[2]) == type) { + list.push({ + name: info[2], + suit: info[0], + number: info[1], + nature: info[3] + }); + } + } + } + return list; + } + static inpile(type, filter) { + var list = []; + if (filter == 'trick') { + for (var i = 0; i < lib.inpile.length; i++) { + if (get.type(lib.inpile[i], 'trick') == type) list.push(lib.inpile[i]); + } + } + else { + for (var i = 0; i < lib.inpile.length; i++) { + if (typeof type == 'function') { + if (type(lib.inpile[i])) { + list.push(lib.inpile[i]); + } + } + else { + if (typeof filter == 'function' && !filter(lib.inpile[i])) continue; + if (type.startsWith('equip') && type.length == 6) { + if (get.subtype(lib.inpile[i]) == type) list.push(lib.inpile[i]); + } + else { + if (get.type(lib.inpile[i]) == type) list.push(lib.inpile[i]); + } + } + } + } + return list; + } + static inpile2(type) { return get.inpile(type, 'trick'); } + static typeCard(type, filter) { + var list = []; + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(get.mode()) == false) continue; + // if(lib.card[i].vanish||lib.card[i].destroy) continue; + if (lib.card[i].destroy) continue; + if (typeof filter == 'function' && !filter(i)) continue; + if (lib.config.bannedcards.includes(i)) continue; + if (!lib.translate[i + '_info']) continue; + if ((type.startsWith('equip') && type.length == 6) || + (type.startsWith('hslingjian') && type.length == 11) || + (type.startsWith('spell_'))) { + if (get.subtype(i) == type) list.push(i); + } + else { + if (get.type(i) == type) list.push(i); + } + } + return list; + } + static libCard(filter) { + var list = []; + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(get.mode()) == false) continue; + // if(lib.card[i].vanish||lib.card[i].destroy) continue; + if (lib.card[i].destroy) continue; + if (lib.config.bannedcards.includes(i)) continue; + if (!lib.translate[i + '_info']) continue; + if (filter(lib.card[i], i)) { + list.push(i); + } + } + return list; + } + static ip() { + if (!require) return ''; + var interfaces = require('os').networkInterfaces(); + for (var devName in interfaces) { + var iface = interfaces[devName]; + for (var i = 0; i < iface.length; i++) { + var alias = iface[i]; + if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { + return alias.address; + } + } + } + } + static modetrans(config, server) { + if (config.mode == 'doudizhu') { + switch (config.doudizhu_mode) { + case 'kaihei': return '开黑斗地主'; + case 'huanle': return '欢乐斗地主'; + case 'binglin': return '兵临城下'; + case 'online': return '智斗三国'; + default: return '休闲' + (config.double_character ? '双将' : '') + '斗地主'; + } + } + if (config.mode == 'versus') { + switch (config.versus_mode) { + case '1v1': return '单人对决'; + case '2v2': return '欢乐成双'; + case '3v3': return '血战到底'; + case '4v4': return '四人对决'; + case 'guandu': return '官渡之战'; + } + } + if (config.mode == 'single') { + switch (config.single_mode) { + case 'normal': return '新1v1'; + case 'changban': return '血战长坂坡'; + case 'dianjiang': return '点将单挑'; + } + } + if (config.mode == 'identity') { + switch (config.identity_mode) { + case 'purple': return '三对三对二'; + case 'zhong': return (config.double_character ? '双将' : '') + '忠胆英杰'; + case 'stratagem': return get.cnNumber(parseInt(config.number)) + '人' + (config.double_character ? '双将' : '') + '谋攻'; + default: return `${get.cnNumber(parseInt(config.number))}人${config.double_nei ? '双内' : ''}${config.enable_commoner ? '带民' : ''}${config.double_character ? '双将' : ''}身份`; + } + } + if (config.mode == 'guozhan') { + if (config.separatism) return '群雄割据'; + if (config.guozhan_mode != 'normal') switch (config.guozhan_mode) { + case 'yingbian': return '应变国战'; + case 'old': return '怀旧国战'; + } + } + if (server) { + return get.translation(config.mode) + '模式'; + } + else { + return get.cnNumber(parseInt(config.number)) + '人' + get.translation(config.mode); + } + } + static charactersOL(func) { + var list = []; + var libCharacter = {}; + for (var i = 0; i < lib.configOL.characterPack.length; i++) { + var pack = lib.characterPack[lib.configOL.characterPack[i]]; + for (var j in pack) { + if (typeof func == 'function' && func(j)) continue; + if (lib.connectBanned.includes(j)) continue; + if (lib.character[j]) libCharacter[j] = pack[j]; + } + } + for (i in libCharacter) { + if (lib.filter.characterDisabled(i, libCharacter)) continue; + list.push(i); + } + return list; + } + static trimip(str) { + var len = str.length - 5; + if (str.lastIndexOf(':8080') == len) { + str = str.slice(0, len); + } + return str; + } + static mode() { return lib[_status.connectMode ? 'configOL' : 'config'].mode; } + static idDialog(id) { return ui.dialogs.find(dialog => dialog.videoId == id) || null; } + static arenaState() { + var state = { + number: ui.arena.dataset.number, + players: {}, + mode: _status.mode, + dying: _status.dying, + servermode: window.isNonameServer, + roomId: game.roomId, + over: _status.over, + inpile: lib.inpile, + inpile_nature: lib.inpile_nature, + renku: _status.renku, + }; + for (var i in lib.playerOL) { + state.players[i] = lib.playerOL[i].getState(); + } + return state; + } + static skillState(player) { + var skills = { + global: lib.skill.global + }; + var skillinfo = {}; + for (var i in lib.playerOL) { + skills[i] = { + skills: lib.playerOL[i].skills, + hiddenSkills: lib.playerOL[i].hiddenSkills, + invisibleSkills: lib.playerOL[i].invisibleSkills, + additionalSkills: lib.playerOL[i].additionalSkills, + disabledSkills: lib.playerOL[i].disabledSkills, + tempSkills: lib.playerOL[i].tempSkills, + storage: lib.playerOL[i].storage, + }; + } + //for(var i in lib.skill){ + // if(lib.skill[i].chooseButton&&lib.skill[i].enable){ + // skillinfo[i]=lib.skill[i].chooseButton; + // } + //} + skills.skillinfo = skillinfo; + if (player) { + skills.stat = player.getStat(); + } + return skills; + } + static id() { return (Math.floor(1000000 + 9000000 * Math.random())).toString() + (10 + lib.status.globalId++); } + static zhu(player, skill, group) { + if (typeof player == 'string') { + skill = player; + player = null; + } + var mode = get.mode(); + if (mode == 'identity') { + if (_status.mode == 'purple') { + if (!player) return null; + var zhu = game[player.identity.slice(0, 1) + 'Zhu']; + if (!zhu) return null; + if (skill && !zhu.hasSkill(skill)) return null; + return zhu; + } + if (!game.zhu) return null; + if (skill && !game.zhu.hasSkill(skill)) return null; + if (game.zhu.isZhu) return game.zhu; + } + else if (mode == 'versus' && (_status.mode == 'four' || _status.mode == 'guandu')) { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isZhu) { + if (skill && !(game.players[i].hasSkill(skill))) continue; + if (!player) return game.players[i]; + if (player.side == game.players[i].side) { + return game.players[i]; + } + } + } + } + else if (mode == 'guozhan') { + for (var i = 0; i < game.players.length; i++) { + if (get.is.jun(game.players[i]) && !game.players[i].isUnseen()) { + if (skill && !game.players[i].hasSkill(skill)) continue; + if (!player) return game.players[i]; + if (player.identity == game.players[i].identity) { + return game.players[i]; + } + else if (group && group == game.players[i].identity) { + return game.players[i]; + } + } + } + } + return null; + } + static config(item, mode) { + mode = mode || lib.config.mode; + if (!lib.config.mode_config[mode]) return; + return lib.config.mode_config[mode][item]; + } + static coinCoeff(list) { + var num = 0; + for (var i = 0; i < list.length; i++) { + var rank = get.rank(list[i]); + switch (rank) { + case 'sp': return 0.1; + case 's': num += 0.4; break; + case 'ap': num += 0.6; break; + case 'a': num += 0.8; break; + case 'am': num += 0.95; break; + case 'bp': num += 1.05; break; + case 'b': num += 1.2; break; + case 'bm': num += 1.4; break; + case 'c': num += 1.6; break; + case 'd': num += 1.8; break; + } + } + return num / list.length; + } + static rank(name, num) { + if (typeof name == 'object' && name.name) { + name = name.name; + } + if (num == true) num = 9; + if (typeof num != 'number') num = false; + if (name == _status.lord) return num ? Math.round(7 * (num - 1) / 8 + 1) : 'ap'; + var rank = lib.rank; + if (lib.characterPack.standard[name] || lib.characterPack.shenhua[name]) { + var skills; + if (lib.character[name]) { + skills = lib.character[name][3]; + } + else { + var tmpinfo = get.character(name); + if (tmpinfo) { + skills = tmpinfo[3]; + } + else { + skills = []; + } + } + for (var i = 0; i < skills.length; i++) { + if (skills[i].alter && !lib.config.vintageSkills.includes(skills[i])) { + name = lib.rank.a[0]; break; + } + } + } + if (rank.s.includes(name)) return num ? Math.round(8 * (num - 1) / 8 + 1) : 's'; + if (rank.ap.includes(name)) return num ? Math.round(7 * (num - 1) / 8 + 1) : 'ap'; + if (rank.a.includes(name)) return num ? Math.round(6 * (num - 1) / 8 + 1) : 'a'; + if (rank.am.includes(name)) return num ? Math.round(5 * (num - 1) / 8 + 1) : 'am'; + if (rank.bp.includes(name)) return num ? Math.round(4 * (num - 1) / 8 + 1) : 'bp'; + if (rank.b.includes(name)) return num ? Math.round(3 * (num - 1) / 8 + 1) : 'b'; + if (rank.bm.includes(name)) return num ? Math.round(2 * (num - 1) / 8 + 1) : 'bm'; + if (rank.c.includes(name)) return num ? Math.round(1 * (num - 1) / 8 + 1) : 'c'; + if (rank.d.includes(name)) return num ? Math.round(0 * (num - 1) / 8 + 1) : 'd'; + if (lib.character[name] && lib.character[name][4]) { + if (lib.character[name][4].includes('boss') || + lib.character[name][4].includes('bossallowed') || + lib.character[name][4].includes('hiddenboss')) { + return num ? Math.round(9 * (num - 1) / 8 + 1) : 'sp'; + } + } + return num ? Math.round(9 * (num - 1) / 8 + 1) : 'x'; + } + static skillRank(skill, type, grouped) { + var info = lib.skill[skill]; + var player = _status.event.skillRankPlayer || _status.event.player; + if (!info) return 0; + if (info.ai) { + if (info.ai.halfneg) return 0; + if (typeof info.ai.combo == 'string' && player && !player.hasSkill(info.ai.combo)) { + return 0; + } + if (info.ai.neg) return -1; + } + var num = 1; + var threaten = 1; + if (info.ai && info.ai.threaten) { + if (typeof info.ai.threaten == 'number') { + threaten = info.ai.threaten; + } + else if (typeof info.ai.threaten == 'function' && player) { + threaten = info.ai.threaten(player, player); + } + } + if (type && type.includes('in')) { + if (info.enable == 'phaseUse') num += 0.5; + if (info.trigger && info.trigger.player) { + var list = Array.isArray(info.trigger.player) ? info.trigger.player : [info.trigger.player]; + var add = false; + for (var i of list) { + if (i.startsWith('phase')) { + num += 0.5; + add = true; + } + else { + for (var j of lib.phaseName) { + if (i.indexOf[j] == 0) { + num += 0.5; + add = true; + break; + } + } + } + if (add) break; + } + } + if (info.trigger && ((typeof info.trigger.player == 'string' && info.trigger.player.startsWith('use')) || info.trigger.source)) { + num += 0.3; + } + if (num > 1 && threaten > 1) { + num += Math.sqrt(threaten) - 1; + } + } + if (type && type.includes('out')) { + if (threaten < 1) { + num *= 1 / Math.sqrt(threaten); + } + if (info.trigger) { + if (info.trigger.global) { + var list = Array.isArray(info.trigger.global) ? info.trigger.global : [info.trigger.global]; + num += Math.min(3, list.length) / 10; + for (var i of list) { + if (i.startsWith('lose') || i.startsWith('use')) num += 0.3; + if (i.startsWith('cardsDiscard')) num += 0.4; + } + } + if (info.trigger.target || (typeof info.trigger.player == 'string' && + (info.trigger.player.startsWith('damage') || info.trigger.player.startsWith('lose')))) num += 0.1; + } + if (info.ai) { + if (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend) { + num += 0.5; + } + if (info.ai.nolose || info.ai.noh || info.ai.noe || info.ai.nodiscard) { + num += 0.3; + } + } + } + if (!grouped) { + var groups = game.expandSkills([skill]); + groups.remove(skill); + var ggt = []; + for (var i = 0; i < groups.length; i++) { + var gi = get.skillRank(groups[i], type, true); + if (gi < 0) { + num -= 0.5; + } + else if (gi > 1) { + ggt.push(gi); + } + } + if (ggt.length) { + num += Math.max.apply(this, ggt) - 1 + ggt.length / 20; + } + } + return num; + } + static targetsInfo(targets) { + var info = []; + for (var i = 0; i < targets.length; i++) { + info.push(targets[i].dataset.position); + } + return info; + } + static infoTargets(infos) { return Array.from(infos || []).map(info => game.playerMap[info]); } + static cardInfo(card) { return [card.suit, card.number, card.name, card.nature]; } + static cardsInfo(cards) { return Array.from(cards || []).map(get.cardInfo); } + static infoCard(info) { + var card = ui.create.card(); + if (info[0]) { + card.init(info); + } + return card; + } + static infoCards(infos) { return Array.from(infos || []).map(get.infoCard); } + static cardInfoOL(card) { return '_noname_card:' + JSON.stringify([card.cardid, card.suit, card.number, card.name, card.nature]); } + static infoCardOL(info) { + if (!lib.cardOL) return info; + var card; + try { + var info = JSON.parse(info.slice(13)); + var id = info.shift(); + if (!id) { + card = ui.create.card(); + if (info && info[2]) card.init(info); + } + else if (lib.cardOL[id]) { + if (lib.cardOL[id].name != info[2]) { + if (info && info[2]) lib.cardOL[id].init(info); + } + card = lib.cardOL[id]; + } + else if (game.online) { + card = ui.create.card(); + card.cardid = id; + if (info && info[2]) card.init(info); + lib.cardOL[id] = card; + } + } + catch (e) { + console.log(e); + } + return card || info; + } + static cardsInfoOL(cards) { return Array.from(cards || []).map(get.cardInfoOL); } + static infoCardsOL(infos) { return Array.from(infos || []).map(get.infoCardOL); } + static playerInfoOL(player) { return '_noname_player:' + player.playerid; } + static infoPlayerOL(info) { return lib.playerOL ? (lib.playerOL[info.slice(15)] || info) : info; } + static playersInfoOL(players) { return Array.from(players || []).map(get.playerInfoOL); } + static infoPlayersOL(infos) { return Array.from(infos || []).map(get.infoPlayerOL); } + static funcInfoOL(func) { + if (typeof func == 'function') { + if (func._filter_args) { + return '_noname_func:' + JSON.stringify(get.stringifiedResult(func._filter_args, 3)); + } + return '_noname_func:' + func.toString(); + } + return ''; + } + static infoFuncOL(info) { + var func; + try { + eval('func=(' + info.slice(13) + ');'); + } + catch (e) { + return function () { }; + } + if (Array.isArray(func)) { + func = get.filter.apply(this, get.parsedResult(func)); + } + return func; + } + static eventInfoOL(item, level, noMore) { + return get.itemtype(item) == 'event' ? `_noname_event:${JSON.stringify(Object.entries(item).reduce((stringifying, entry) => { + const key = entry[0]; + if (key == '_trigger') { + if (noMore !== false) stringifying[key] = get.eventInfoOL(entry[1], null, false); + } + else if (!lib.element.GameEvent.prototype[key] && key != 'content' && get.itemtype(entry[1]) != 'event') stringifying[key] = get.stringifiedResult(entry[1], null, false); + return stringifying; + }, {}))}` : ''; + } + /** + * @param {string} item + */ + static infoEventOL(item) { + const evt = new lib.element.GameEvent(); + try { + Object.entries(JSON.parse(item.slice(14))).forEach(entry => { + const key = entry[0]; + if (typeof evt[key] != 'function') evt[key] = get.parsedResult(entry[1]); + }); + } + catch (error) { + console.log(error); + } + return evt || item; + } + static stringifiedResult(item, level, nomore) { + if (!item) return item; + if (typeof item == 'function') { + return get.funcInfoOL(item); + } + else if (typeof item == 'object') { + switch (get.itemtype(item)) { + case 'card': return get.cardInfoOL(item); + case 'cards': return get.cardsInfoOL(item); + case 'player': return get.playerInfoOL(item); + case 'players': return get.playersInfoOL(item); + case 'event': + if (nomore === false) return ''; + return get.eventInfoOL(item); + default: + if (typeof level != 'number') { + level = 8; + } + if (Array.isArray(item)) { + if (level == 0) { + return []; + } + var item2 = []; + for (var i = 0; i < item.length; i++) { + item2.push(get.stringifiedResult(item[i], level - 1, nomore)); + } + return item2; + } + else if (Object.prototype.toString.call(item) == '[object Object]') { + if (level == 0) { + return {}; + } + var item2 = {}; + for (var i in item) { + item2[i] = get.stringifiedResult(item[i], level - 1, nomore); + } + return item2; + } + else { + return {}; + } + } + } + else if (item === Infinity) { + return '_noname_infinity'; + } + else { + return item; + } + } + static parsedResult(item) { + if (!item) return item; + if (typeof item == 'string') { + if (item.startsWith('_noname_func:')) { + return get.infoFuncOL(item); + } + else if (item.startsWith('_noname_card:')) { + return get.infoCardOL(item); + } + else if (item.startsWith('_noname_player:')) { + return get.infoPlayerOL(item); + } + else if (item.startsWith('_noname_event:')) { + return get.infoEventOL(item); + } + else if (item == '_noname_infinity') { + return Infinity; + } + else { + return item; + } + } + else if (Array.isArray(item)) { + var item2 = []; + for (var i = 0; i < item.length; i++) { + item2.push(get.parsedResult(item[i])); + } + return item2; + } + else if (typeof item == 'object') { + var item2 = {}; + for (var i in item) { + item2[i] = get.parsedResult(item[i]); + } + return item2; + } + else { + return item; + } + } + static verticalStr(str, sp) { + if (typeof str != 'string') return ''; + return Array.from(str).filter(value => value != '`').join(''); + } + static numStr(num, method) { + if (num == Infinity) { + if (method == 'card') return get.selectableCards().length + ui.selected.cards.length; + if (method == 'target') return get.selectableTargets().length + ui.selected.targets.length; + return '∞'; + } + return num.toString(); + } + static rawName(str) { + let str2 = lib.translate[str]; + if (lib.translate[str + '_ab']) str2 = lib.translate[str + '_ab']; + if (!str2) return ''; + if (lib.translate[str + '_prefix'] && str2.startsWith(lib.translate[str + '_prefix'])) { + return str2.slice(lib.translate[str + '_prefix'].length); + } + return str2; + } + /** + * 作用修改:只读前缀 不读_ab + */ + static rawName2(str) { + let str2 = lib.translate[str]; + if (!str2) return ''; + if (lib.translate[str + '_prefix'] && str2.startsWith(lib.translate[str + '_prefix'])) { + return str2.slice(lib.translate[str + '_prefix'].length); + } + return str2; + } + static slimNameHorizontal(str) { + const slimName = lib.translate[`${str}_ab`] || lib.translate[str]; + if (!slimName) return ''; + const prefix = lib.translate[`${str}_prefix`]; + if (prefix && slimName.startsWith(prefix)) { + //兼容版特化处理 + if (lib.compatibleEdition) return `${get.prefixSpan(prefix, str)}${slimName.slice(prefix.length)} `; + return `${get.prefixSpan(prefix, str)}${slimName.slice(prefix.length)}`; + } + return slimName; + } + /** + * @param {string} prefix + * @param {string} name + * @returns {string} + */ + static prefixSpan(prefix, name) { + const config = lib.config.buttoncharacter_prefix; + if (config == 'off') return ''; + if (config == 'simple') { + const span = document.createElement('span'); + span.innerHTML = prefix; + return span.outerHTML; + } + const namePrefix = lib.namePrefix.get(prefix), exists = Boolean(namePrefix); + if (exists && 'getSpan' in namePrefix) return namePrefix.getSpan(prefix, name); + const span = document.createElement('span'); + if (exists) { + if ('color' in namePrefix) span.style.color = namePrefix.color; + if ('nature' in namePrefix) span.dataset.nature = namePrefix.nature; + if ('showName' in namePrefix) prefix = namePrefix.showName; + } + else span.style.color = '#ffffff'; + span.innerHTML = prefix; + return span.outerHTML; + } + static slimName(str) { return get.verticalStr(get.slimNameHorizontal(str), true); } + static time() { + if (lib.status.dateDelaying) { + return lib.getUTC(lib.status.dateDelaying) - lib.getUTC(lib.status.date) - lib.status.dateDelayed; + } + else { + return lib.getUTC(new Date()) - lib.getUTC(lib.status.date) - lib.status.dateDelayed; + } + } + static utc() { return (new Date()).getTime(); } + static evtDistance(e1, e2) { + var dx = (e1.clientX - e2.clientX) / game.documentZoom; + var dy = (e1.clientY - e2.clientY) / game.documentZoom; + return Math.sqrt(dx * dx + dy * dy); + } + static xyDistance(from, to) { return Math.sqrt((from[0] - to[0]) * (from[0] - to[0]) + (from[1] - to[1]) * (from[1] - to[1])); } + /** + * @overload + * @returns { void } + */ + /** + * @overload + * @param { string } obj + * @returns { 'position' | 'natures' | 'nature' } + */ + /** + * @overload + * @param { Player[] } obj + * @returns { 'players' } + */ + /** + * @overload + * @param { Card[] } obj + * @returns { 'cards' } + */ + /** + * @overload + * @param { [number, number] } obj + * @returns { 'select' } + */ + /** + * @overload + * @param { [number, number, number, number] } obj + * @returns { 'divposition' } + */ + /** + * @overload + * @param { Button } obj + * @returns { 'button' } + */ + /** + * @overload + * @param { Card } obj + * @returns { 'card' } + */ + /** + * @overload + * @param { Player } obj + * @returns { 'player' } + */ + /** + * @overload + * @param { Dialog } obj + * @returns { 'dialog' } + */ + /** + * @overload + * @param { GameEvent | GameEventPromise } obj + * @returns { 'event' } + */ + static itemtype(obj) { + if (typeof obj == 'string') { + if (obj.length <= 5) { + let bool = true; + for (let i = 0; i < obj.length; i++) { + if (/h|e|j|s|x/.test(obj[i]) == false) { + bool = false; break; + } + } + if (bool) return 'position'; + } + if (obj.includes(lib.natureSeparator) && obj.split(lib.natureSeparator).every(n => lib.nature.has(n))) return 'natures'; + if (lib.nature.has(obj)) return 'nature'; + } + if (Array.isArray(obj) && obj.length > 0) { + if (obj.every(p => p instanceof lib.element.Player)) return 'players'; + if (obj.every(p => p instanceof lib.element.Card)) return 'cards'; + if (obj.length == 2) { + if (typeof obj[0] == 'number' && typeof obj[1] == 'number') { + if (obj[0] <= obj[1] || obj[1] <= -1) return 'select'; + } + } + if (obj.length == 4) { + if (obj.every(p => typeof p == 'number')) { + return 'divposition'; + } + } + } + if (obj instanceof lib.element.Button) return 'button'; + if (obj instanceof lib.element.Card) return 'card'; + if (obj instanceof lib.element.Player) return 'player'; + if (obj instanceof lib.element.Dialog) return 'dialog'; + if (obj instanceof lib.element.GameEvent || + obj instanceof lib.element.GameEventPromise) return 'event'; + + if (typeof obj !== 'object' || obj === null) return; + + if (lib.experimental.symbol.itemType in obj) + return obj[lib.experimental.symbol.itemType]; + } + static equipNum(card) { + if (get.type(card) == 'equip') { + return parseInt(get.subtype(card)[5]); + } + return 0; + } + static objtype(obj) { + if (Object.prototype.toString.call(obj) === '[object Array]') return 'array'; + if (Object.prototype.toString.call(obj) === '[object Object]') return 'object'; + if (Object.prototype.toString.call(obj) === '[object HTMLDivElement]') return 'div'; + if (Object.prototype.toString.call(obj) === '[object HTMLTableElement]') return 'table'; + if (Object.prototype.toString.call(obj) === '[object HTMLTableRowElement]') return 'tr'; + if (Object.prototype.toString.call(obj) === '[object HTMLTableCellElement]') return 'td'; + if (Object.prototype.toString.call(obj) === '[object HTMLBodyElement]') return 'td'; + if (Object.prototype.toString.call(obj) === '[object DocumentFragment]') return 'fragment'; + } + static type(obj, method, player) { + if (typeof obj == 'string') obj = { name: obj }; + if (typeof obj != 'object') return; + var name = get.name(obj, player); + if (!lib.card[name]) { + if (!name.startsWith('sha_')) return; + if (name.slice(4).split('_').every(n => lib.nature.has(n))) return lib.card['sha'].type; + } + if (method == 'trick' && lib.card[name].type == 'delay') return 'trick'; + return lib.card[name].type; + } + static type2(card, player) { return get.type(card, 'trick', player); } + static subtype(obj, player) { + if (typeof obj == 'string') obj = { name: obj }; + if (typeof obj != 'object') return; + const name = get.name(obj, player); + if (!lib.card[name]) return; + let subtype = lib.card[name].subtype; + return subtype; + } + static equiptype(card, player) { + var subtype = get.subtype(card, player); + if (subtype.startsWith('equip')) return parseInt(subtype[5]); + return 0; + } + /** + * + * @param {Card | VCard} card + * @param {false | Player} [player] + * @returns {string} + */ + static name(card, player) { + if (get.itemtype(player) == 'player' || (player !== false && get.position(card) == 'h')) { + var owner = player || get.owner(card); + if (owner) { + return game.checkMod(card, owner, card.name, 'cardname', owner); + } + } + return card.name; + } + /** + * @param {Card | VCard | Card[] | VCard[]} card + * @param {false | Player} [player] + * @returns {string} + */ + static suit(card, player) { + if (!card) return; + if (Array.isArray(card)) { + if (card.length == 1) return get.suit(card[0], player); + return 'none'; + } + else if (!('suit' in card) && Array.isArray(card.cards)) { + return get.suit(card.cards, player); + } + else { + if (player !== false) { + const owner = player || get.owner(card); + if (owner) { + return game.checkMod(card, owner, game.checkMod(card, card.suit, 'suit', owner), 'cardsuit', owner); + } + } + if (lib.suits.includes(card.suit)) return card.suit; + return 'none'; + } + } + /** + * @param {Card | VCard | Card[] | VCard[]} card + * @param {false | Player} [player] + * @returns {string} + */ + static color(card, player) { + if (!card) return; + if (Array.isArray(card)) { + if (!card.length) return 'none'; + const cards = card.slice(), color = get.color(cards.shift(), player); + for (const anotherCard of cards) { + if (get.color(anotherCard, player) != color) return 'none'; + } + return color; + } + else if (Object.keys(lib.color).includes(card.color)) { + return card.color; + } + else if (Array.isArray(card.cards) && !lib.suit.includes(card.suit)) { + return get.color(card.cards, player); + } + else { + const suit = get.suit(card, player); + for (const entry of Object.entries(lib.color)) { + if (entry[1].includes(suit)) return entry[0]; + } + return 'none'; + } + } + /** + * @param {Card | VCard} card + * @param {false | Player} [player] + * @returns {number} + */ + static number(card, player) { + if (!card) return; + //狗卡你是真敢出啊 + var number = null; + if ('number' in card) { + number = card.number; + if (typeof number != 'number') number = null; + } + else { + if (card.cards && card.cards.length == 1) number = get.number(card.cards[0], false); + } + if (player !== false) { + var owner = player || get.owner(card); + if (owner) { + return game.checkMod(card, owner, number, 'cardnumber', owner); + } + } + return number; + } + /** + * 返回一张杀的属性。如有多种属性则用`lib.natureSeparator`分割开来。例:火雷【杀】的返回值为`fire|thunder` + * @param {string | string[] | Card | VCard} card + * @param {false | Player} [player] + * @returns {string} + */ + static nature(card, player) { + if (typeof card == 'string') return card.split(lib.natureSeparator).sort(lib.sort.nature).join(lib.natureSeparator); + if (Array.isArray(card)) return card.sort(lib.sort.nature).join(lib.natureSeparator); + var nature = card.nature; + if (get.itemtype(player) == 'player' || player !== false) { + var owner = get.owner(card); + if (owner) { + return game.checkMod(card, owner, nature, 'cardnature', owner); + } + } + return nature; + } + /** + * 返回包含所有属性的数组 + * @param {string[] | string} card + * @param {false | Player} [player] + * @returns {string[]} + */ + static natureList(card, player) { + if (!card) return []; + if (get.itemtype(card) == 'natures') return card.split(lib.natureSeparator); + if (get.itemtype(card) == 'nature') return [card]; + const natures = get.nature(card, player); + if (typeof natures != 'string') return []; + return natures.split(lib.natureSeparator); + } + static cards(num, putBack) { + if (_status.waitingForCards) { + ui.create.cards.apply(ui.create, _status.waitingForCards); + delete _status.waitingForCards; + } + var list = []; + var card = false; + if (typeof num != 'number') num = 1; + if (num == 0) { card = true; num = 1; } + if (num < 0) num = 1; + while (num--) { + if (ui.cardPile.hasChildNodes() == false) { + game.washCard(); + } + if (ui.cardPile.hasChildNodes() == false) { + game.over('平局'); + return []; + } + var cardx = ui.cardPile.removeChild(ui.cardPile.firstChild); + cardx.original = 'c'; + list.push(cardx); + } + if (putBack) { + for (let i = list.length - 1; i >= 0; i--) { + ui.cardPile.insertBefore(list[i], ui.cardPile.firstChild); + } + } + game.updateRoundNumber(); + if (card) return list[0]; + return list; + } + static judge(card) { return card.viewAs ? lib.card[card.viewAs].judge : get.info(card).judge; } + static judge2(card) { return card.viewAs ? lib.card[card.viewAs].judge2 : get.info(card).judge2; } + static distance(from, to, method) { + if (from == to) return 0; + if (!game.players.includes(from) && !game.dead.includes(from)) return Infinity; + if (!game.players.includes(to) && !game.dead.includes(to)) return Infinity; + let n = 1; + if (game.chess) { + let fxy = from.getXY(), txy = to.getXY(); + n = Math.abs(fxy[0] - txy[0]) + Math.abs(fxy[1] - txy[1]); + if (method == 'raw' || method == 'pure' || method == 'absolute') return n; + } + else if (to.isMin(true) || from.isMin(true)) { + if (method == 'raw' || method == 'pure' || method == 'absolute') return n; + } + else { + let player = from, length = game.players.length; + const totalPopulation = game.players.length + game.dead.length + 1; + for (let iwhile = 0; iwhile < totalPopulation; iwhile++) { + if (player.nextSeat != to) { + player = player.nextSeat; + if (player.isAlive() && !player.isOut() && !player.hasSkill('undist') && !player.isMin(true)) n++; + } + else { + break; + } + } + for (let i = 0; i < game.players.length; i++) { + if (game.players[i].isOut() || game.players[i].hasSkill('undist') || game.players[i].isMin(true)) length--; + } + if (method == 'absolute') return n; + if (from.isDead()) length++; + if (to.isDead()) length++; + const left = from.hasSkillTag('left_hand'), right = from.hasSkillTag('right_hand'); + if (left === right) n = Math.min(n, length - n); + else if (left == true) n = length - n; + if (method == 'raw' || method == 'pure') return n; + } + n = game.checkMod(from, to, n, 'globalFrom', from); + n = game.checkMod(from, to, n, 'globalTo', to); + const equips1 = from.getCards('e', function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }), equips2 = to.getCards('e', function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }); + for (let i = 0; i < equips1.length; i++) { + let info = get.info(equips1[i]).distance; + if (!info) continue; + if (info.globalFrom) { + n += info.globalFrom; + } + } + for (let i = 0; i < equips2.length; i++) { + let info = get.info(equips2[i]).distance; + if (!info) continue; + if (info.globalTo) { + n += info.globalTo; + } + if (info.attaclTo) { + m += info.attaclTo; + } + } + if (method == 'attack') { + let m = n; + m = game.checkMod(from, to, m, 'attackFrom', from); + m = game.checkMod(from, to, m, 'attackTo', to); + return m; + // const attakRange=from.getEquipRange(); + // m+=(1-attakRange); + // for(let i=0;i[number, number]) } [select] + * @returns { [number, number] } + */ + static select(select) { + if (typeof select == 'function') return get.select(select()); + else if (typeof select == 'number') return [select, select]; + else if (select && get.itemtype(select) == 'select') return select; + return [1, 1]; + } + static card(original) { + if (_status.event.skill) { + var card = get.info(_status.event.skill).viewAs; + if (typeof card == 'function') card = card(ui.selected.cards, _status.event.player); + if (card) { + return get.autoViewAs(card, ui.selected.cards); + } + } + if (_status.event._get_card) { + return _status.event._get_card; + } + var card = ui.selected.cards[0]; + if (original) return card; + if (card) { + card = get.autoViewAs(card, ui.selected.cards); + } + return card; + } + /** + * @template T + * @overload + * @param {T} key + * @returns {GameEvent[T]} + */ + /** + * @overload + * @returns {GameEvent} + */ + static event(key) { return key ? _status.event[key] : _status.event; } + static player() { return _status.event.player; } + static players(sort, dead, out) { + var players = game.players.slice(0); + if (sort != false) { + if (typeof sort == 'function') players.sort(sort); + else players.sortBySeat(get.itemtype(sort) == "player" ? sort : _status.event.player); + } + if (dead) players = players.concat(game.dead); + if (!out) players = players.filter(current => !current.isOut()); + return players; + } + static position(card, ordering) { + if (get.itemtype(card) == 'player') return parseInt(card.dataset.position); + if (card.timeout && card.destiny && card.destiny.classList) { + if (card.destiny.classList.contains('equips')) return 'e'; + if (card.destiny.classList.contains('judges')) return 'j'; + if (card.destiny.classList.contains('expansions')) return 'x'; + if (card.destiny.classList.contains('handcards')) return card.classList.contains('glows') ? 's' : 'h'; + if (card.destiny.id == 'cardPile') return 'c'; + if (card.destiny.id == 'discardPile') return 'd'; + if (card.destiny.id == 'special') return 's'; + if (card.destiny.id == 'ordering') return ordering ? 'o' : 'd'; + return null; + } + if (!card.parentNode || !card.parentNode.classList) return; + if (card.parentNode.classList.contains('equips')) return 'e'; + if (card.parentNode.classList.contains('judges')) return 'j'; + if (card.parentNode.classList.contains('expansions')) return 'x'; + if (card.parentNode.classList.contains('handcards')) return card.classList.contains('glows') ? 's' : 'h'; + if (card.parentNode.id == 'cardPile') return 'c'; + if (card.parentNode.id == 'discardPile') return 'd'; + if (card.parentNode.id == 'special') return 's'; + if (card.parentNode.id == 'ordering') return ordering ? 'o' : 'd'; + return null; + } + static skillTranslation(str, player) { + var str2; + if (str.startsWith('re')) { + str2 = str.slice(2); + if (str2) { + if (lib.translate[str] == lib.translate[str2]) { + if (player.hasSkill(str2)) { + return '界' + lib.translate[str]; + } + } + } + } + else if (str.startsWith('xin')) { + str2 = str.slice(3); + if (str2) { + if (lib.translate[str] == lib.translate[str2]) { + if (player.hasSkill(str2)) { + return '新' + lib.translate[str]; + } + } + } + } + return get.translation(str); + } + static skillInfoTranslation(name, player) { + if (player && lib.dynamicTranslate[name]) return lib.dynamicTranslate[name](player, name); + var str = lib.translate[name + '_info']; + if (!str) return ''; + return str; + // return str.replace(/锁定技/g,'锁定技'). + // replace(/限定技/g,'限定技'). + // replace(/觉醒技/g,'觉醒技'). + // replace(/主将技/g,'主将技'). + // replace(/副将技/g,'副将技'). + // replace(/阵法技/g,'阵法技'). + // replace(/主公技/g,'主公技'); + } + /** + * @returns {string} + */ + static translation(str, arg) { + if (str && typeof str == 'object' && (str.name || str._tempTranslate)) { + if (str._tempTranslate) return str._tempTranslate; + var str2; + if (arg == 'viewAs' && str.viewAs) { + str2 = get.translation(str.viewAs); + } + else { + str2 = get.translation(str.name); + } + if (str2 == '杀') { + str2 = ''; + if (typeof str.nature == 'string') { + let natures = str.nature.split(lib.natureSeparator).sort(lib.sort.nature); + for (let nature of natures) { + str2 += lib.translate['nature_' + nature] || lib.translate[nature] || ''; + } + } + str2 += '杀'; + } + if (get.itemtype(str) == 'card' || str.isCard) { + if (_status.cardtag && str.cardid) { + var tagstr = ''; + for (var i in _status.cardtag) { + if (_status.cardtag[i].includes(str.cardid)) { + tagstr += lib.translate[i + '_tag']; + } + } + if (tagstr) { + str2 += '·' + tagstr; + } + } + if (str.suit && str.number || str.isCard) { + var cardnum = get.number(str, false) || ''; + if ([1, 11, 12, 13].includes(cardnum)) { + cardnum = { '1': 'A', '11': 'J', '12': 'Q', '13': 'K' }[cardnum]; + } + if (arg == 'viewAs' && str.viewAs != str.name && str.viewAs) { + str2 += '(' + get.translation(str) + ')'; + } + else { + str2 += '【' + get.translation(get.suit(str, false)) + cardnum + '】'; + // var len=str2.length-1; + // str2=str2.slice(0,len)+''+str2[len]+'·'+get.translation(str.suit)+str.number; + } + } + } + return str2; + } + if (Array.isArray(str)) { + var str2 = get.translation(str[0], arg); + for (var i = 1; i < str.length; i++) { + str2 += '、' + get.translation(str[i], arg); + } + return str2; + } + if (get.itemtype(str) == 'natures') { + let natures = str.split(lib.natureSeparator).sort(lib.sort.nature); + var str2 = ''; + for (var nature of natures) { + str2 += lib.translate['nature_' + nature] || lib.translate[nature] || ''; + } + return str2; + } + if (arg == 'skill') { + if (lib.translate[str + '_ab']) return lib.translate[str + '_ab']; + if (lib.translate[str]) return lib.translate[str].slice(0, 2); + return str; + } + else if (arg == 'info') { + if (lib.translate[str + '_info']) return lib.translate[str + '_info']; + var str2 = str.slice(0, str.length - 1); + if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; + if (str.lastIndexOf('_') > 0) { + str2 = str.slice(0, str.lastIndexOf('_')); + if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; + } + str2 = str.slice(0, str.length - 2); + if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; + if (lib.skill[str] && lib.skill[str].prompt) return lib.skill[str].prompt; + } + if (lib.translate[str]) { + return lib.translate[str]; + } + if (typeof str == 'string') { + if (lib.translate['nature_' + str]) return lib.translate['nature_' + str]; + return str; + } + if (typeof str == 'number' || typeof str == 'boolean') { + return str.toString(); + } + if (str && str.toString) { + return str.toString(); + } + return ''; + } + static strNumber(num) { + switch (num) { + case 1: return 'A'; + case 11: return 'J'; + case 12: return 'Q'; + case 13: return 'K'; + default: return num.toString(); + } + } + static cnNumber(num, two) { + if (num == Infinity) return '∞'; + if (typeof num != 'number' && typeof num != 'string') return num; + if (isNaN(num)) return ''; + let numStr = num.toString(); + if (!/^\d+$/.test(numStr)) return num; + + const chars = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; + const units = ['', '十', '百', '千']; + + if (numStr.length <= 2) {//两位数以下单独处理保证效率 + if (numStr.length == 1) return !two && num == 2 ? '两' : chars[num]; + return (numStr[0] == '1' ? '' : chars[numStr[0]]) + '十' + (numStr[1] == '0' ? '' : chars[numStr[1]]); + } + + numStr = numStr.replace(/(?=(\d{4})+$)/g, ',').split(',').filter(Boolean); + const handleZero = str => str.replace(/零{2,}/g, '零').replace(/零+$/g, ''); + const _transform = str => { + if (str === '0000') return '零'; + if (!two && str === '2') return '两'; + let result = ''; + for (let i = 0; i < str.length; i++) { + let char = chars[+str[i]]; + const unitIndex = str.length - 1 - i; + let unit = units[unitIndex]; + if (!two && char === '二' && unitIndex > 1) char = '两'; + if (char === '零') unit = ''; + result += char + unit; + } + result = handleZero(result); + return result; + }; + let result = ''; + for (let i = 0; i < numStr.length; i++) { + const part = numStr[i]; + let char = _transform(part); + const unitIndex = numStr.length - 1 - i; + let unit = unitIndex % 2 ? '万' : '亿'.repeat(unitIndex / 2); + if (char === '零') unit = ''; + result += char + unit; + } + result = handleZero(result); + return result; + } + /** + * @param {((a: Button, b: Button) => number)} [sort] 排序函数 + * @returns { Button[] } + */ + static selectableButtons(sort) { + if (!_status.event.player) return []; + var buttons = _status.event.dialog.buttons; + var selectable = []; + for (var i = 0; i < buttons.length; i++) { + if (buttons[i].classList.contains('selectable') && + buttons[i].classList.contains('selected') == false) { + selectable.push(buttons[i]); + } + } + if (sort) { + selectable.sort(sort); + } + return selectable; + } + /** + * @param {((a: Card, b: Card) => number)} [sort] 排序函数 + * @returns { Card[] } + */ + static selectableCards(sort) { + if (!_status.event.player) return []; + var cards = _status.event.player.getCards('hes'); + var selectable = []; + for (var i = 0; i < cards.length; i++) { + if (cards[i].classList.contains('selectable') && + cards[i].classList.contains('selected') == false) { + selectable.push(cards[i]); + } + } + if (sort) { + selectable.sort(sort); + } + return selectable; + } + /** + * @returns { string[] } 技能名数组 + */ + static skills() { + var skills = []; + if (ui.skills) { + skills = skills.concat(ui.skills.skills); + } + if (ui.skills2) { + skills = skills.concat(ui.skills2.skills); + } + if (ui.skills3) { + skills = skills.concat(ui.skills3.skills); + } + return skills; + } + static gainableSkills(func, player) { + var list = []; + for (var i in lib.character) { + if (lib.filter.characterDisabled(i)) continue; + if (lib.filter.characterDisabled2(i)) continue; + if (lib.character[i][4]) { + if (lib.character[i][4].includes('boss')) continue; + if (lib.character[i][4].includes('hiddenboss')) continue; + if (lib.character[i][4].includes('minskin')) continue; + if (lib.character[i][4].includes('unseen')) continue; + } + for (var j = 0; j < lib.character[i][3].length; j++) { + var skill = lib.character[i][3][j]; + var info = lib.skill[skill]; + if (lib.filter.skillDisabled(skill)) continue; + if (func && !func(info, skill, i)) continue; + if (player && player.hasSkill && info.ai && info.ai.combo && !player.hasSkill(info.ai.combo)) continue; + list.add(skill); + } + } + return list; + } + static gainableSkillsName(name, func) { + var list = []; + if (name && lib.character[name]) { + if (lib.character[name][4]) { + if (lib.character[name][4].includes('boss')) return list; + if (lib.character[name][4].includes('hiddenboss')) return list; + if (lib.character[name][4].includes('minskin')) return list; + if (lib.character[name][4].includes('unseen')) return list; + } + for (var j = 0; j < lib.character[name][3].length; j++) { + var skill = lib.character[name][3][j]; + var info = lib.skill[skill]; + if (lib.filter.skillDisabled(skill)) continue; + if (func && !func(info, skill, name)) continue; + list.add(skill); + } + } + return list; + } + static gainableCharacters(func) { + var list = []; + for (var i in lib.character) { + var info = lib.character[i]; + if (!info) continue; + if (typeof func == 'function' && !func(info, i)) continue; + if (lib.filter.characterDisabled(i)) continue; + if (lib.filter.characterDisabled2(i)) continue; + list.push(i); + } + if (func === true) { + var players = game.players.concat(game.dead); + for (var i = 0; i < players.length; i++) { + list.remove(players[i].name); + list.remove(players[i].name1); + list.remove(players[i].name2); + } + } + return list; + } + /** + * @param {((a: Player, b: Player) => number)} [sort] 排序函数 + * @returns { Player[] } + */ + static selectableTargets(sort) { + var selectable = []; + var players = game.players.slice(0); + if (_status.event.deadTarget) players.addArray(game.dead); + for (var i = 0; i < players.length; i++) { + if (players[i].classList.contains('selectable') && + players[i].classList.contains('selected') == false) { + selectable.push(players[i]); + } + } + selectable.randomSort(); + if (sort) { + selectable.sort(sort); + } + return selectable; + } + static filter(filter, i) { + if (typeof filter == 'function') return filter; + if (i == undefined) i = 0; + var result = function () { + if (filter == arguments[i]) return true; + for (var j in filter) { + if (Object.prototype.hasOwnProperty.call(filter, j)) { + if (get.itemtype(arguments[i]) == 'card') { + if (j == 'name') { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.name(arguments[i])) == false) return false; + } + else if (typeof filter[j] == 'string') { + if (get.name(arguments[i]) != filter[j]) return false; + } + } + else if (j == 'type') { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.type(arguments[i])) == false) return false; + } + else if (typeof filter[j] == 'string') { + if (get.type(arguments[i]) != filter[j]) return false; + } + } + else if (j == 'subtype') { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.subtype(arguments[i])) == false) return false; + } + else if (typeof filter[j] == 'string') { + if (get.subtype(arguments[i]) != filter[j]) return false; + } + } + else if (j == 'color') { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.color(arguments[i])) == false) return false; + } + else if (typeof filter[j] == 'string') { + if (get.color(arguments[i]) != filter[j]) return false; + } + } + else if (j == 'suit') { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.suit(arguments[i])) == false) return false; + } + else if (typeof filter[j] == 'string') { + if (get.suit(arguments[i]) != filter[j]) return false; + } + } + else if (j == 'number') { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.number(arguments[i])) == false) return false; + } + else if (typeof filter[j] == 'string') { + if (get.number(arguments[i]) != filter[j]) return false; + } + } + else if (Array.isArray(filter[j])) { + if (filter[j].includes(arguments[i][j]) == false) return false; + } + else if (typeof filter[j] == 'string') { + if (arguments[i][j] != filter[j]) return false; + } + } + else { + if (arguments[i][j] != filter[j]) return false; + } + } + } + return true; + }; + result._filter_args = [filter, i]; + return result; + } + static cardCount(card, player) { + var num; + if (player == undefined) player = _status.event.player; + if (card == true) { + num = 0; + var stat = player.getStat('card'); + for (var i in stat) { + if (typeof stat[i] == 'number') num += stat[i]; + } + return num; + } + if (typeof card == 'object') { + card = card.name; + } + num = player.getStat('card')[card]; + if (num == undefined) return 0; + return num; + } + static skillCount(skill, player) { + if (player == undefined) player = _status.event.player; + var num = player.getStat('skill')[skill]; + if (num == undefined) return 0; + return num; + } + static owner(card, method) { + return game.players.concat(game.dead).find(current => + current.getCards("hejsx").includes(card) || (current.judging[0] == card && method != "judge")); + } + static noSelected() { return ui.selected.buttons.length + ui.selected.cards.length + ui.selected.targets.length == 0; } + static population(identity) { + return identity == undefined ? + game.players.length + game.dead.length : + game.players.filter(current => current.identity == identity).length; + } + static totalPopulation(identity) { + return identity == undefined ? + game.players.length + game.dead.length : + game.players.concat(game.dead).filter(current => current.identity == identity).length; + } + /** + * @param { Card | VCard } item + */ + static cardtag(item, tag) { + return (item.cardid && (get.itemtype(item) == 'card' || !item.cards || !item.cards.length || item.name == item.cards[0].name) && _status.cardtag && _status.cardtag[tag] && _status.cardtag[tag].includes(item.cardid)) + || (item.cardtags && item.cardtags.includes(tag)); + } + static tag(item, tag, item2, bool) { + var result; + if (get.info(item, bool) && get.info(item, bool).ai && get.info(item, bool).ai.tag) { + result = get.info(item, bool).ai.tag[tag]; + } + if (typeof result == 'function') return result(item, item2); + return result; + } + static sortCard(sort) { + var func; + if (sort == 'type_sort') { + func = function (card) { + var type = get.type(card, null, false); + var subtype = get.subtype(card, false); + if (lib.cardType[subtype]) { + return lib.cardType[subtype]; + } + if (lib.cardType[type]) { + return lib.cardType[type]; + } + switch (type) { + case 'basic': return 2; + case 'chess': return 1.5; + case 'trick': return -1; + case 'delay': return -2; + case 'equip': return -3; + default: return -4; + } + }; + } + else if (sort == 'suit_sort') { + func = function (card) { + if (get.suit(card) == 'heart') return 2; + if (get.suit(card) == 'diamond') return 1; + if (get.suit(card) == 'spade') return -1; + if (get.suit(card) == 'club') return -2; + }; + } + else if (sort == 'number_sort') { + func = function (card) { + return get.number(card) - 7 + 0.5; + }; + } + return func; + } + static difficulty() { + switch (get.config('difficulty')) { + case 'easy': return 1; + case 'normal': return 2; + case 'hard': return 3; + default: return 1; + } + } + static cardPile(name, create) { + var filter = function (card) { + if (typeof name == 'string') { + if (card.name == name) { + return true; + } + } + else if (typeof name == 'function') { + if (name(card)) { + return true; + } + } + return false; + }; + if (create != 'discardPile') { + var num = get.rand(0, ui.cardPile.childNodes.length - 1); + for (var i = 0; i < ui.cardPile.childNodes.length; i++) { + var j = i; + if (j >= ui.cardPile.childNodes.length) j -= ui.cardPile.childNodes.length; + if (filter(ui.cardPile.childNodes[j])) { + return ui.cardPile.childNodes[j]; + } + } + } + if (create != 'cardPile') { + for (var i = 0; i < ui.discardPile.childNodes.length; i++) { + var j = i; + if (j >= ui.discardPile.childNodes.length) j -= ui.discardPile.childNodes.length; + if (filter(ui.discardPile.childNodes[j])) { + return ui.discardPile.childNodes[j]; + } + } + } + if (create == 'field') { + var found = null; + game.findPlayer(function (current) { + var ej = current.getCards('ej'); + for (var i = 0; i < ej.length; i++) { + if (filter(ej[i])) { + found = ej[i]; + return true; + } + } + }); + return found; + } + if (create && !['cardPile', 'discardPile', 'field'].includes(create)) { + return game.createCard(name); + } + return null; + } + static cardPile2(name) { return get.cardPile(name, 'cardPile'); } + static discardPile(name) { return get.cardPile(name, 'discardPile'); } + static aiStrategy() { + switch (get.config('ai_strategy')) { + case 'ai_strategy_1': return 1; + case 'ai_strategy_2': return 2; + case 'ai_strategy_3': return 3; + case 'ai_strategy_4': return 4; + case 'ai_strategy_5': return 5; + case 'ai_strategy_6': return 6; + default: return 1; + } + } + static skillintro(name, learn, learn2) { + var str = ''; + var infoitem = lib.character[name]; + if (!infoitem) { + for (var itemx in lib.characterPack) { + if (lib.characterPack[itemx][name]) { + infoitem = lib.characterPack[itemx][name]; break; + } + } + } + var skills = infoitem[3]; + var opacity; + for (var i = 0; i < skills.length; i++) { + if (lib.translate[skills[i]] && lib.translate[skills[i] + '_info'] && lib.skill[skills[i]]) { + if (learn && lib.skill[skills[i]].unique && (learn2 || !lib.skill[skills[i]].gainable)) { + opacity = 'opacity:0.5'; + } + else { + opacity = ''; + } + var skilltrans = get.translation(skills[i]).slice(0, 2); + str += '
【' + skilltrans + '】
' + + get.skillInfoTranslation(skills[i]) + '
'; + } + } + return str; + } + static intro(name) { + var info = lib.character[name]; + var str = '性别:' + get.translation(info[0]) + '
'; + str += '势力:' + get.translation(info[1]) + '
'; + str += '体力:' + get.translation(info[2]) + '
'; + str += '技能:'; + if (info[3].length) { + str += get.translation(info[3][0]); + for (var i = 1; i < info[3].length; i++) { + str += '、' + get.translation(info[3][i]); + } + } + return str; + } + static storageintro(type, content, player, dialog, skill) { + switch (type) { + case 'mark': { + if (content > 0) { + return '共有' + content + '个标记'; + } + return false; + } + case 'turn': { + if (content > 0) { + return '剩余' + content + '个回合'; + } + return false; + } + case 'time': { + if (content > 0) { + return '剩余' + content + '次'; + } + return false; + } + case 'limited': { + if (content) { + return '已发动'; + } + return '未发动'; + } + case 'info': { + return lib.translate[skill + '_info']; + } + case 'cardCount': { + if (Array.isArray(content)) { + return '共有' + get.cnNumber(content.length) + '张牌'; + } + return false; + } + case 'expansion': { + content = player.getCards('x', function (card) { + return card.hasGaintag(skill); + }); + if (dialog && content.length) { + dialog.addAuto(content); + } + else { + return '没有卡牌'; + } + return false; + } + case 'card': case 'cards': { + if (get.itemtype(content) == 'card') { + content = [content]; + } + if (dialog && get.itemtype(content) == 'cards') { + dialog.addAuto(content); + } + else { + if (content && content.length) { + return get.translation(content); + } + } + if (Array.isArray(content) && !content.length) { + return '没有卡牌'; + } + return false; + } + case 'player': case 'players': { + if (get.itemtype(content) == 'player') { + content = [content]; + } + if (dialog && get.itemtype(content) == 'players') { + dialog.addAuto(content); + return false; + } + else { + if (content && content.length) { + return get.translation(content); + } + return false; + } + } + case 'character': case 'characters': { + if (typeof content == 'string') { + content = [content]; + } + if (dialog && Array.isArray(content)) { + dialog.addAuto([content, 'character']); + return false; + } + else { + if (content && content.length) { + return get.translation(content); + } + return false; + } + } + default: { + if (typeof type == 'string') { + type = type.replace(/#/g, content); + type = type.replace(/&/g, get.cnNumber(content)); + type = type.replace(/\$/g, get.translation(content)); + return type; + } + else if (typeof type == 'function') { + return type(content, player, skill); + } + return false; + } + } + } + static nodeintro(node, simple, evt) { + var uiintro = ui.create.dialog('hidden', 'notouchscroll'); + if (node.classList.contains('player') && !node.name) { + return uiintro; + } + var i, translation, intro, str; + if (node._nointro) return; + if (typeof node._customintro == 'function') { + if (node._customintro(uiintro, evt) === false) return; + if (evt) lib.placePoppedDialog(uiintro, evt); + } + else if (Array.isArray(node._customintro)) { + var caption = node._customintro[0]; + var content = node._customintro[1]; + if (typeof caption == 'function') { + caption = caption(node); + } + if (typeof content == 'function') { + content = content(node); + } + uiintro.add(caption); + uiintro.add('
' + content + '
'); + } + else if (node.classList.contains('player') || node.linkplayer) { + if (node.linkplayer) { + node = node.link; + } + let capt = get.translation(node.name); + const characterInfo = get.character(node.name), sex = node.sex || characterInfo[0]; + if (sex && sex != 'unknown' && lib.config.show_sex) capt += `  ${sex == 'none' ? '无' : get.translation(sex)}`; + const group = node.group; + if (group && group != 'unknown' && lib.config.show_group) capt += `  ${get.translation(group)}`; + uiintro.add(capt); + + if (lib.characterTitle[node.name]) { + uiintro.addText(get.colorspan(lib.characterTitle[node.name])); + } + + if (!node.noclick) { + const allShown = (node.isUnderControl() || (!game.observe && game.me && game.me.hasSkillTag('viewHandcard', null, node, true))); + const shownHs = node.getShownCards(); + if (shownHs.length) { + uiintro.add('
明置的手牌
'); + uiintro.addSmall(shownHs); + if (allShown) { + var hs = node.getCards('h'); + hs.removeArray(shownHs); + if (hs.length) { + uiintro.add('
其他手牌
'); + uiintro.addSmall(hs); + } + } + } + else if (allShown) { + var hs = node.getCards('h'); + if (hs.length) { + uiintro.add('
手牌
'); + uiintro.addSmall(hs); + } + } + } + + var skills = node.getSkills(null, false, false).slice(0); + var skills2 = game.filterSkills(skills, node); + if (node == game.me && node.hiddenSkills.length) { + skills.addArray(node.hiddenSkills); + } + for (var i in node.disabledSkills) { + if (node.disabledSkills[i].length == 1 && + node.disabledSkills[i][0] == i + '_awake' && + !node.hiddenSkills.includes(i)) { + skills.add(i); + } + } + for (i = 0; i < skills.length; i++) { + if (lib.skill[skills[i]] && (lib.skill[skills[i]].nopop || lib.skill[skills[i]].equipSkill)) continue; + if (lib.translate[skills[i] + '_info']) { + if (lib.translate[skills[i] + '_ab']) translation = lib.translate[skills[i] + '_ab']; + else { + translation = get.translation(skills[i]); + if (!lib.skill[skills[i]].nobracket) translation = `【${translation.slice(0, 2)}】`; + } + + if (node.forbiddenSkills[skills[i]]) { + var forbidstr = '
' + translation + '
'; + if (node.forbiddenSkills[skills[i]].length) { + forbidstr += '(与' + get.translation(node.forbiddenSkills[skills[i]]) + '冲突)
'; + } + else { + forbidstr += '(双将禁用)
'; + } + forbidstr += get.skillInfoTranslation(skills[i], node) + '
'; + uiintro.add(forbidstr); + } + else if (!skills2.includes(skills[i])) { + if (lib.skill[skills[i]].preHidden && get.mode() == 'guozhan') { + uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
预亮技能
'); + var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); + if (_status.prehidden_skills.includes(skills[i])) { + underlinenode.classList.remove('on'); + } + underlinenode.link = skills[i]; + underlinenode.listen(ui.click.hiddenskill); + } + else uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
'); + } + else if (lib.skill[skills[i]].temp || !node.skills.includes(skills[i]) || lib.skill[skills[i]].thundertext) { + if (lib.skill[skills[i]].frequent || lib.skill[skills[i]].subfrequent) { + uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
自动发动
'); + var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); + if (lib.skill[skills[i]].frequent) { + if (lib.config.autoskilllist.includes(skills[i])) { + underlinenode.classList.remove('on'); + } + } + if (lib.skill[skills[i]].subfrequent) { + for (var j = 0; j < lib.skill[skills[i]].subfrequent.length; j++) { + if (lib.config.autoskilllist.includes(skills[i] + '_' + lib.skill[skills[i]].subfrequent[j])) { + underlinenode.classList.remove('on'); + } + } + } + if (lib.config.autoskilllist.includes(skills[i])) { + underlinenode.classList.remove('on'); + } + underlinenode.link = skills[i]; + underlinenode.listen(ui.click.autoskill2); + } + else { + uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
'); + } + } + else if (lib.skill[skills[i]].frequent || lib.skill[skills[i]].subfrequent) { + uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
自动发动
'); + var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); + if (lib.skill[skills[i]].frequent) { + if (lib.config.autoskilllist.includes(skills[i])) { + underlinenode.classList.remove('on'); + } + } + if (lib.skill[skills[i]].subfrequent) { + for (var j = 0; j < lib.skill[skills[i]].subfrequent.length; j++) { + if (lib.config.autoskilllist.includes(skills[i] + '_' + lib.skill[skills[i]].subfrequent[j])) { + underlinenode.classList.remove('on'); + } + } + } + if (lib.config.autoskilllist.includes(skills[i])) { + underlinenode.classList.remove('on'); + } + underlinenode.link = skills[i]; + underlinenode.listen(ui.click.autoskill2); + } + else if (lib.skill[skills[i]].clickable && node.isIn() && node.isUnderControl(true)) { + var intronode = uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
').querySelector('.skillbutton'); + if (!_status.gameStarted || (lib.skill[skills[i]].clickableFilter && !lib.skill[skills[i]].clickableFilter(node))) { + intronode.classList.add('disabled'); + intronode.style.opacity = 0.5; + } + else { + intronode.link = node; + intronode.func = lib.skill[skills[i]].clickable; + intronode.classList.add('pointerdiv'); + intronode.listen(ui.click.skillbutton); + } + } + else { + uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i], node) + '
'); + } + if (lib.translate[skills[i] + '_append']) { + uiintro._place_text = uiintro.add('
' + lib.translate[skills[i] + '_append'] + '
'); + } + } + } + // if(get.is.phoneLayout()){ + // var storage=node.storage; + // for(i in storage){ + // if(get.info(i)&&get.info(i).intro){ + // intro=get.info(i).intro; + // if(node.getSkills().concat(lib.skill.global).includes(i)==false&&!intro.show) continue; + // var name=intro.name?intro.name:get.translation(i); + // if(typeof name=='function'){ + // name=name(storage[i],node); + // } + // translation='
『'+name.slice(0,2)+'』
'; + // var stint=get.storageintro(intro.content,storage[i],node,null,i); + // if(stint){ + // translation+=stint+'
'; + // uiintro.add(translation); + // } + // } + // } + // } + + if (lib.config.right_range && _status.gameStarted) { + uiintro.add(ui.create.div('.placeholder')); + var table, tr, td; + table = document.createElement('table'); + tr = document.createElement('tr'); + table.appendChild(tr); + td = document.createElement('td'); + td.innerHTML = '距离'; + tr.appendChild(td); + td = document.createElement('td'); + td.innerHTML = '手牌'; + tr.appendChild(td); + td = document.createElement('td'); + td.innerHTML = '行动'; + tr.appendChild(td); + td = document.createElement('td'); + td.innerHTML = '伤害'; + tr.appendChild(td); + + tr = document.createElement('tr'); + table.appendChild(tr); + td = document.createElement('td'); + if (node == game.me || !game.me || !game.me.isIn()) { + td.innerHTML = '-'; + } + else { + var dist1 = get.numStr(Math.max(1, game.me.distanceTo(node))); + var dist2 = get.numStr(Math.max(1, node.distanceTo(game.me))); + if (dist1 == dist2) { + td.innerHTML = dist1; + } + else { + td.innerHTML = dist1 + '/' + dist2; + } + } + tr.appendChild(td); + td = document.createElement('td'); + let handcardLimit = node.getHandcardLimit(); + td.innerHTML = `${node.countCards('h')}/${handcardLimit >= 114514 ? '∞' : handcardLimit}`; + tr.appendChild(td); + td = document.createElement('td'); + td.innerHTML = node.phaseNumber; + tr.appendChild(td); + td = document.createElement('td'); + + (function () { + num = 0; + for (var j = 0; j < node.stat.length; j++) { + if (typeof node.stat[j].damage == 'number') num += node.stat[j].damage; + } + td.innerHTML = num; + }()); + tr.appendChild(td); + table.style.width = 'calc(100% - 20px)'; + table.style.marginLeft = '10px'; + + uiintro.content.appendChild(table); + if (!lib.config.show_favourite) { + table.style.paddingBottom = '5px'; + } + } + if (!simple || get.is.phoneLayout()) { + var es = node.getCards('e'); + for (var i = 0; i < es.length; i++) { + var cardinfo = lib.card[es[i].name]; + if (cardinfo && cardinfo.cardPrompt) uiintro.add('
' + es[i].outerHTML + '
' + cardinfo.cardPrompt(es[i]) + '
'); + else uiintro.add('
' + es[i].outerHTML + '
' + lib.translate[es[i].name + '_info'] + '
'); + uiintro.content.lastChild.querySelector('.skill>.card').style.transform = ''; + + if (lib.translate[es[i].name + '_append']) { + uiintro.add('
' + lib.translate[es[i].name + '_append'] + '
'); + } + } + var js = node.getCards('j'); + for (var i = 0; i < js.length; i++) { + if (js[i].viewAs && js[i].viewAs != js[i].name) { + uiintro.add('
' + js[i].outerHTML + '
' + lib.translate[js[i].viewAs] + ':' + lib.translate[js[i].viewAs + '_info'] + '
'); + } + else { + uiintro.add('
' + js[i].outerHTML + '
' + lib.translate[js[i].name + '_info'] + '
'); + } + uiintro.content.lastChild.querySelector('.skill>.card').style.transform = ''; + } + if (get.is.phoneLayout()) { + var markCoutainer = ui.create.div('.mark-container.marks'); + for (var i in node.marks) { + var nodemark = node.marks[i].cloneNode(true); + nodemark.classList.add('pointerdiv'); + nodemark.link = node.marks[i]; + nodemark.style.transform = ''; + markCoutainer.appendChild(nodemark); + nodemark.listen(function () { + uiintro.noresume = true; + var rect = this.link.getBoundingClientRect(); + ui.click.intro.call(this.link, { + clientX: rect.left + rect.width, + clientY: rect.top + rect.height / 2, + }); + if (lib.config.touchscreen) { + uiintro._close(); + } + }); + } + if (markCoutainer.childElementCount) { + uiintro.addText('标记'); + uiintro.add(markCoutainer); + } + } + } + if (!game.observe && _status.gameStarted && game.me && node != game.me) { + ui.throwEmotion = []; + uiintro.addText('发送交互表情'); + var click = function () { + if (_status.dragged) return; + if (_status.justdragged) return; + if (_status.throwEmotionWait) return; + var emotion = this.link; + if (game.online) { + game.send('throwEmotion', node, emotion); + } + else game.me.throwEmotion(node, emotion); + uiintro._close(); + _status.throwEmotionWait = true; + setTimeout(function () { + _status.throwEmotionWait = false; + if (ui.throwEmotion) { + for (var i of ui.throwEmotion) i.classList.remove('exclude'); + } + }, (emotion == 'flower' || emotion == 'egg') ? 500 : 5000); + }; + var td; + var table = document.createElement('div'); + table.classList.add('add-setting'); + table.style.margin = '0'; + table.style.width = '100%'; + table.style.position = 'relative'; + var listi = ['flower', 'egg']; + for (var i = 0; i < listi.length; i++) { + td = ui.create.div('.menubutton.reduce_radius.pointerdiv.tdnode'); + ui.throwEmotion.add(td); + if (_status.throwEmotionWait) td.classList.add('exclude'); + td.link = listi[i]; + table.appendChild(td); + td.innerHTML = '' + get.translation(listi[i]) + ''; + td.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', click); + } + uiintro.content.appendChild(table); + table = document.createElement('div'); + table.classList.add('add-setting'); + table.style.margin = '0'; + table.style.width = '100%'; + table.style.position = 'relative'; + var listi = ['wine', 'shoe']; + if (game.me.storage.zhuSkill_shanli) listi = ['yuxisx', 'jiasuo']; + for (var i = 0; i < listi.length; i++) { + td = ui.create.div('.menubutton.reduce_radius.pointerdiv.tdnode'); + ui.throwEmotion.add(td); + if (_status.throwEmotionWait) td.classList.add('exclude'); + td.link = listi[i]; + table.appendChild(td); + td.innerHTML = '' + get.translation(listi[i]) + ''; + td.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', click); + } + uiintro.content.appendChild(table); + } + var modepack = lib.characterPack['mode_' + get.mode()]; + if (lib.config.show_favourite && lib.character[node.name] && game.players.includes(node) && + (!modepack || !modepack[node.name]) && (!simple || get.is.phoneLayout())) { + var addFavourite = ui.create.div('.text.center.pointerdiv'); + addFavourite.link = node.name; + if (lib.config.favouriteCharacter.includes(node.name)) { + addFavourite.innerHTML = '移除收藏'; + } + else { + addFavourite.innerHTML = '添加收藏'; + } + addFavourite.listen(ui.click.favouriteCharacter); + uiintro.add(addFavourite); + } + if (!simple || get.is.phoneLayout()) { + if ((lib.config.change_skin || lib.skin) && !node.isUnseen()) { + var num = 1; + var introadded = false; + var createButtons = function (num, avatar2) { + if (!introadded) { + introadded = true; + uiintro.add('
更改皮肤
'); + } + var buttons = ui.create.div('.buttons.smallzoom.scrollbuttons'); + lib.setMousewheel(buttons); + var nameskin = (avatar2 ? node.name2 : node.name1); + var nameskin2 = nameskin; + var gzbool = false; + if (nameskin.startsWith('gz_shibing')) { + nameskin = nameskin.slice(3, 11); + } + else if (nameskin.startsWith('gz_')) { + nameskin = nameskin.slice(3); + gzbool = true; + } + for (var i = 0; i <= num; i++) { + var button = ui.create.div('.button.character.pointerdiv', buttons, function () { + if (this._link) { + if (avatar2) { + lib.config.skin[nameskin] = this._link; + node.node.avatar2.style.backgroundImage = this.style.backgroundImage; + } + else { + lib.config.skin[nameskin] = this._link; + node.node.avatar.style.backgroundImage = this.style.backgroundImage; + } + } + else { + delete lib.config.skin[nameskin]; + if (avatar2) { + if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.node.avatar2.setBackground(nameskin2, 'character'); + else node.node.avatar2.setBackground(nameskin, 'character'); + } + else { + if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.node.avatar.setBackground(nameskin2, 'character'); + else node.node.avatar.setBackground(nameskin, 'character'); + } + } + game.saveConfig('skin', lib.config.skin); + }); + button._link = i; + if (i) { + button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); + } + else { + if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); + else button.setBackground(nameskin, 'character', 'noskin'); + } + } + uiintro.add(buttons); + }; + var loadImage = function (avatar2) { + var img = new Image(); + img.onload = function () { + num++; + loadImage(avatar2); + }; + img.onerror = function () { + num--; + if (num) { + createButtons(num, avatar2); + } + if (!avatar2) { + if (!node.classList.contains('unseen2') && node.name2) { + num = 1; + loadImage(true); + } + } + }; + var nameskin = (avatar2 ? node.name2 : node.name1); + var nameskin2 = nameskin; + var gzbool = false; + if (nameskin.startsWith('gz_shibing')) { + nameskin = nameskin.slice(3, 11); + } + else if (nameskin.startsWith('gz_')) { + nameskin = nameskin.slice(3); + gzbool = true; + } + img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; + }; + if (lib.config.change_skin) { + if (!node.isUnseen(0)) { + loadImage(); + } + else if (node.name2) { + loadImage(true); + } + } + else { + setTimeout(function () { + var nameskin1 = node.name1; + var nameskin2 = node.name2; + if (nameskin1 && nameskin1.startsWith('gz_')) { + nameskin1 = nameskin1.slice(3); + } + if (nameskin2 && nameskin2.startsWith('gz_')) { + nameskin2 = nameskin2.slice(3); + } + if (!node.isUnseen(0) && lib.skin[nameskin1]) { + createButtons(lib.skin[nameskin1]); + } + if (!node.isUnseen(1) && lib.skin[nameskin2]) { + createButtons(lib.skin[nameskin2], true); + } + }); + } + } + } + + uiintro.add(ui.create.div('.placeholder.slim')); + } + else if (node.classList.contains('mark') && node.info && + node.parentNode && node.parentNode.parentNode && node.parentNode.parentNode.classList.contains('player')) { + var info = node.info; + var player = node.parentNode.parentNode; + if (info.name) { + if (typeof info.name == 'function') { + var named = info.name(player.storage[node.skill], player); + if (named) { + uiintro.add(named); + } + } + else { + uiintro.add(info.name); + } + } + else if (info.name !== false) { + uiintro.add(get.translation(node.skill)); + } + if (typeof info.id == 'string' && info.id.startsWith('subplayer') && + player.isUnderControl(true) && player.storage[info.id] && !_status.video) { + var storage = player.storage[info.id]; + uiintro.addText('当前体力:' + storage.hp + '/' + storage.maxHp); + if (storage.hs.length) { + uiintro.addText('手牌区'); + uiintro.addSmall(storage.hs); + } + if (storage.es.length) { + uiintro.addText('装备区'); + uiintro.addSmall(storage.es); + } + } + if (typeof info.mark == 'function') { + var stint = info.mark(uiintro, player.storage[node.skill], player); + if (stint) { + var placetext = uiintro.add('
' + stint + '
'); + if (!stint.startsWith('
'+stint+'
'); + // } + // else{ + // uiintro.add('
'+stint+'
'); + // } + } + } + else { + var stint = get.storageintro(info.content, player.storage[node.skill], player, uiintro, node.skill); + if (stint) { + if (stint[0] == '@') { + uiintro.add('
' + stint.slice(1) + '
'); + } + else { + var placetext = uiintro.add('
' + stint + '
'); + if (!stint.startsWith('
'+stint+'
'); + // } + // else{ + // uiintro.add('
'+stint+'
'); + // } + } + } + uiintro.add(ui.create.div('.placeholder.slim')); + } + else if (node.classList.contains('card')) { + //卡牌长按介绍 + if (ui.arena.classList.contains('observe') && node.parentNode.classList.contains('handcards')) { + return; + } + var name = node.name; + if (node.parentNode.cardMod) { + var moded = false; + for (var i in node.parentNode.cardMod) { + var item = node.parentNode.cardMod[i](node); + if (Array.isArray(item)) { + moded = true; + uiintro.add(item[0]); + uiintro._place_text = uiintro.add('
' + item[1] + '
'); + } + } + if (moded) return uiintro; + } + if (node.link && node.link.name && lib.card[node.link.name]) { + name = node.link.name; + } + if (get.position(node) == 'j' && node.viewAs && node.viewAs != name) { + uiintro.add(get.translation(node.viewAs)); + uiintro.add('
(' + get.translation(get.translation(node)) + ')
'); + // uiintro.add(get.translation(node.viewAs)+'
('+get.translation(node)+')
'); + uiintro.nosub = true; + name = node.viewAs; + } + else { + uiintro.add(get.translation(node)); + } + if (node._banning) { + var clickBanned = function () { + var banned = lib.config[this.bannedname] || []; + if (banned.includes(name)) { + banned.remove(name); + } + else { + banned.push(name); + } + game.saveConfig(this.bannedname, banned); + this.classList.toggle('on'); + if (node.updateBanned) { + node.updateBanned(); + } + }; + var modeorder = lib.config.modeorder || []; + for (var i in lib.mode) { + modeorder.add(i); + } + var list = []; + uiintro.contentContainer.listen(function (e) { + ui.click.touchpop(); + e.stopPropagation(); + }); + for (var i = 0; i < modeorder.length; i++) { + if (node._banning == 'online') { + if (!lib.mode[modeorder[i]].connect) continue; + } + else if (modeorder[i] == 'connect' || modeorder[i] == 'brawl') { + continue; + } + if (lib.config.all.mode.includes(modeorder[i])) { + list.push(modeorder[i]); + } + } + if (lib.card[name] && lib.card[name].type == 'trick') list.push('zhinang_tricks'); + var page = ui.create.div('.menu-buttons.configpopped', uiintro.content); + var banall = false; + for (var i = 0; i < list.length; i++) { + var cfg = ui.create.div('.config', list[i] == 'zhinang_tricks' ? '设为智囊' : (lib.translate[list[i]] + '模式'), page); + cfg.classList.add('toggle'); + if (list[i] == 'zhinang_tricks') { + cfg.bannedname = ((node._banning == 'offline') ? '' : 'connect_') + 'zhinang_tricks'; + } + else if (node._banning == 'offline') { + cfg.bannedname = list[i] + '_bannedcards'; + } + else { + cfg.bannedname = 'connect_' + list[i] + '_bannedcards'; + } + cfg.listen(clickBanned); + ui.create.div(ui.create.div(cfg)); + var banned = lib.config[cfg.bannedname] || []; + if (banned.includes(name) == (list[i] == 'zhinang_tricks')) { + cfg.classList.add('on'); + banall = true; + } + } + ui.create.div('.menubutton.pointerdiv', banall ? '全部禁用' : '全部启用', uiintro.content, function () { + if (this.innerHTML == '全部禁用') { + for (var i = 0; i < page.childElementCount; i++) { + if (page.childNodes[i].bannedname.indexOf('zhinang_tricks') == -1 && page.childNodes[i].bannedname && page.childNodes[i].classList.contains('on')) { + clickBanned.call(page.childNodes[i]); + } + } + this.innerHTML = '全部启用'; + } + else { + for (var i = 0; i < page.childElementCount; i++) { + if (page.childNodes[i].bannedname.indexOf('zhinang_tricks') == -1 && page.childNodes[i].bannedname && !page.childNodes[i].classList.contains('on')) { + clickBanned.call(page.childNodes[i]); + } + } + this.innerHTML = '全部禁用'; + } + }).style.marginTop = '-10px'; + ui.create.div('.placeholder.slim', uiintro.content); + } + else { + if (lib.translate[name + '_info']) { + if (!uiintro.nosub) { + if (lib.card[name] && lib.card[name].derivation) { + if (typeof lib.card[name].derivation == 'string') { + uiintro.add('
来源:' + get.translation(lib.card[name].derivation) + '
'); + } + else if (lib.card[name].derivationpack) { + uiintro.add('
来源:' + get.translation(lib.card[name].derivationpack + '_card_config') + '包
'); + } + } + let typeinfo = ''; + if (lib.card[name] && lib.card[name].unique) { + typeinfo += ('特殊' + get.translation(lib.card[name].type) + '牌'); + } + else if (lib.card[name] && lib.card[name].type && lib.translate[lib.card[name].type]) { + typeinfo += (get.translation(lib.card[name].type) + '牌'); + } + if (get.subtype(name, false)) { + typeinfo += ('-' + get.translation(get.subtype(name, false))); + } + if (typeinfo) { + uiintro.add('
' + typeinfo + '
'); + } + if (lib.card[name].unique && lib.card[name].type == 'equip') { + if (lib.cardPile.guozhan && lib.cardPack.guozhan.includes(name)) { + uiintro.add('
专属装备
').style.marginTop = '-5px'; + } + else { + uiintro.add('
特殊装备
').style.marginTop = '-5px'; + } + } + if (lib.card[name] && lib.card[name].addinfomenu) { + uiintro.add('
' + lib.card[name].addinfomenu + '
'); + } + if (get.subtype(name, false) == 'equip1') { + var added = false; + if (lib.card[node.name] && lib.card[node.name].distance) { + var dist = lib.card[node.name].distance; + if (dist.attackFrom) { + added = true; + uiintro.add('
攻击范围:' + (-dist.attackFrom + 1) + '
'); + } + } + if (!added) { + uiintro.add('
攻击范围:1
'); + } + } + } + if (lib.card[name].cardPrompt) { + var str = lib.card[name].cardPrompt(node.link || node), placetext = uiintro.add('
' + str + '
'); + if (!str.startsWith('
' + lib.translate[name + '_info'] + '
'); + if (!lib.translate[name + '_info'].startsWith('
应变:${yingbianEffects.map(value => lib.yingbian.prompt.get(value)).join(';')}
`); + } + if (lib.translate[name + '_append']) { + uiintro.add('
' + lib.translate[name + '_append'] + '
'); + } + } + uiintro.add(ui.create.div('.placeholder.slim')); + } + } + else if (node.classList.contains('character')) { + const character = node.link, characterInfo = get.character(node.link); + let capt = get.translation(character); + if (characterInfo) { + const infoSex = characterInfo[0]; + if (infoSex && lib.config.show_sex) capt += `  ${infoSex == 'none' ? '无' : lib.translate[infoSex]}`; + const infoGroup = characterInfo[1]; + if (infoGroup && lib.config.show_group) { + const group = get.is.double(character, true); + if (group) capt += `  ${group.map(value => get.translation(value)).join('/')}`; + else capt += `  ${lib.translate[infoGroup]}`; + } + } + uiintro.add(capt); + + if (lib.characterTitle[node.link]) { + uiintro.addText(get.colorspan(lib.characterTitle[node.link])); + } + + if (node._banning) { + var clickBanned = function () { + var banned = lib.config[this.bannedname] || []; + if (banned.includes(character)) { + banned.remove(character); + } + else { + banned.push(character); + } + game.saveConfig(this.bannedname, banned); + this.classList.toggle('on'); + if (node.updateBanned) { + node.updateBanned(); + } + }; + var modeorder = lib.config.modeorder || []; + for (var i in lib.mode) { + modeorder.add(i); + } + var list = []; + uiintro.contentContainer.listen(function (e) { + ui.click.touchpop(); + e.stopPropagation(); + }); + for (var i = 0; i < modeorder.length; i++) { + if (node._banning == 'online') { + if (!lib.mode[modeorder[i]].connect) continue; + if (!lib.config['connect_' + modeorder[i] + '_banned']) { + lib.config['connect_' + modeorder[i] + '_banned'] = []; + } + } + else if (modeorder[i] == 'connect' || modeorder[i] == 'brawl') { + continue; + } + if (lib.config.all.mode.includes(modeorder[i])) { + list.push(modeorder[i]); + } + } + var page = ui.create.div('.menu-buttons.configpopped', uiintro.content); + var banall = false; + for (var i = 0; i < list.length; i++) { + var cfg = ui.create.div('.config', lib.translate[list[i]] + '模式', page); + cfg.classList.add('toggle'); + if (node._banning == 'offline') { + cfg.bannedname = list[i] + '_banned'; + } + else { + cfg.bannedname = 'connect_' + list[i] + '_banned'; + } + cfg.listen(clickBanned); + ui.create.div(ui.create.div(cfg)); + var banned = lib.config[cfg.bannedname] || []; + if (!banned.includes(character)) { + cfg.classList.add('on'); + banall = true; + } + } + if (node._banning == 'offline') { + var cfg = ui.create.div('.config', '随机选将可用', page); + cfg.classList.add('toggle'); + cfg.listen(function () { + this.classList.toggle('on'); + if (this.classList.contains('on')) { + lib.config.forbidai_user.remove(character); + } + else { + lib.config.forbidai_user.add(character); + } + game.saveConfig('forbidai_user', lib.config.forbidai_user); + }); + ui.create.div(ui.create.div(cfg)); + if (!lib.config.forbidai_user.includes(character)) { + cfg.classList.add('on'); + } + } + ui.create.div('.menubutton.pointerdiv', banall ? '全部禁用' : '全部启用', uiintro.content, function () { + if (this.innerHTML == '全部禁用') { + for (var i = 0; i < page.childElementCount; i++) { + if (page.childNodes[i].bannedname && page.childNodes[i].classList.contains('on')) { + clickBanned.call(page.childNodes[i]); + } + } + this.innerHTML = '全部启用'; + } + else { + for (var i = 0; i < page.childElementCount; i++) { + if (page.childNodes[i].bannedname && !page.childNodes[i].classList.contains('on')) { + clickBanned.call(page.childNodes[i]); + } + } + this.innerHTML = '全部禁用'; + } + }).style.marginTop = '-10px'; + ui.create.div('.placeholder.slim', uiintro.content); + } + else { + var infoitem = get.character(character); + var skills = infoitem[3]; + for (i = 0; i < skills.length; i++) { + if (lib.translate[skills[i] + '_info']) { + if (lib.translate[skills[i] + '_ab']) translation = lib.translate[skills[i] + '_ab']; + else { + translation = get.translation(skills[i]); + if (!lib.skill[skills[i]].nobracket) translation = `【${translation.slice(0, 2)}】`; + } + + uiintro.add('
' + translation + '
' + get.skillInfoTranslation(skills[i]) + '
'); + + if (lib.translate[skills[i] + '_append']) { + uiintro._place_text = uiintro.add('
' + lib.translate[skills[i] + '_append'] + '
'); + } + } + } + var modepack = lib.characterPack['mode_' + get.mode()]; + if (lib.config.show_favourite && + lib.character[node.link] && (!modepack || !modepack[node.link]) && (!simple || get.is.phoneLayout())) { + var addFavourite = ui.create.div('.text.center.pointerdiv'); + addFavourite.link = node.link; + addFavourite.style.marginBottom = '15px'; + if (lib.config.favouriteCharacter.includes(node.link)) { + addFavourite.innerHTML = '移除收藏'; + } + else { + addFavourite.innerHTML = '添加收藏'; + } + addFavourite.listen(ui.click.favouriteCharacter); + uiintro.add(addFavourite); + } + else { + uiintro.add(ui.create.div('.placeholder.slim')); + } + var addskin = false; + if (node.parentNode.classList.contains('menu-buttons')) { + addskin = !lib.config.show_charactercard; + } + else { + addskin = lib.config.change_skin || lib.skin; + } + if (addskin && (!simple || get.is.phoneLayout())) { + var num = 1; + var introadded = false; + var nameskin = node.link; + var nameskin2 = nameskin; + var gzbool = false; + if (nameskin.startsWith('gz_shibing')) { + nameskin = nameskin.slice(3, 11); + } + else if (nameskin.startsWith('gz_')) { + nameskin = nameskin.slice(3); + gzbool = true; + } + var createButtons = function (num) { + if (!num) return; + if (!introadded) { + introadded = true; + uiintro.add('
更改皮肤
'); + } + var buttons = ui.create.div('.buttons.smallzoom.scrollbuttons'); + lib.setMousewheel(buttons); + for (var i = 0; i <= num; i++) { + var button = ui.create.div('.button.character.pointerdiv', buttons, function () { + if (this._link) { + lib.config.skin[nameskin] = this._link; + node.style.backgroundImage = this.style.backgroundImage; + game.saveConfig('skin', lib.config.skin); + } + else { + delete lib.config.skin[nameskin]; + if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.setBackground(nameskin2, 'character'); + else node.setBackground(nameskin, 'character'); + game.saveConfig('skin', lib.config.skin); + } + }); + button._link = i; + if (i) { + button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); + } + else { + if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); + else button.setBackground(nameskin, 'character', 'noskin'); + } + } + uiintro.add(buttons); + }; + var loadImage = function () { + var img = new Image(); + img.onload = function () { + num++; + loadImage(); + }; + img.onerror = function () { + num--; + createButtons(num); + }; + img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; + }; + if (lib.config.change_skin) { + loadImage(); + } + else { + setTimeout(function () { + createButtons(lib.skin[nameskin]); + }); + } + } + } + } + else if (node.classList.contains('equips') && ui.arena.classList.contains('selecting')) { + (function () { + uiintro.add('选择装备'); + uiintro.addSmall(Array.from(node.childNodes).filter(node => !node.classList.contains('feichu')), true); + uiintro.clickintro = true; + ui.control.hide(); + uiintro._onclose = function () { + ui.control.show(); + }; + var confirmbutton; + for (var i = 0; i < uiintro.buttons.length; i++) { + var button = uiintro.buttons[i]; + button.classList.add('pointerdiv'); + if (button.link.classList.contains('selected')) { + button.classList.add('selected'); + } + button.listen(function (e) { + ui.click.card.call(this.link, 'popequip'); + ui.click.window.call(ui.window, e); + if (this.link.classList.contains('selected')) { + this.classList.add('selected'); + } + else { + this.classList.remove('selected'); + } + if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { + confirmbutton.classList.remove('disabled'); + } + else { + confirmbutton.classList.add('disabled'); + } + }); + } + var buttoncontainer = uiintro.add(ui.create.div()); + buttoncontainer.style.display = 'block'; + confirmbutton = ui.create.div('.menubutton.large.pointerdiv', '确定', function () { + if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { + uiintro._clickintro(); + ui.click.ok(ui.confirm.firstChild); + } + }, buttoncontainer); + confirmbutton.style.position = 'relative'; + setTimeout(function () { + if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { + confirmbutton.classList.remove('disabled'); + } + else { + confirmbutton.classList.add('disabled'); + } + }, 300); + }()); + } + else if (node.classList.contains('identity') && node.dataset.career) { + var career = node.dataset.career; + uiintro.add(get.translation(career)); + uiintro.add('
' + lib.translate['_' + career + '_skill_info'] + '
'); + } + else if (node.classList.contains('skillbar')) { + if (node == ui.friendBar) { + uiintro.add('友方怒气值'); + uiintro.add('
' + _status.friendRage + '/100
'); + } + else if (node == ui.enemyBar) { + uiintro.add('敌方怒气值'); + uiintro.add('
' + _status.enemyRage + '/100
'); + } + } + else if (node.parentNode == ui.historybar) { + if (node.dead) { + if (!node.source || node.source == node.player) { + uiintro.add('
' + get.translation(node.player) + '阵亡
'); + uiintro.addSmall([node.player]); + } + else { + uiintro.add('
' + get.translation(node.player) + '被' + get.translation(node.source) + '杀害
'); + uiintro.addSmall([node.source]); + } + } + if (node.skill) { + uiintro.add('
' + get.translation(node.skill, 'skill') + '
'); + uiintro._place_text = uiintro.add('
' + get.translation(node.skill, 'info') + '
'); + } + if (node.targets && get.itemtype(node.targets) == 'players') { + uiintro.add('
目标
'); + uiintro.addSmall(node.targets); + } + if (node.players && node.players.length > 1) { + uiintro.add('
使用者
'); + uiintro.addSmall(node.players); + } + if (node.cards && node.cards.length) { + uiintro.add('
卡牌
'); + uiintro.addSmall(node.cards); + } + for (var i = 0; i < node.added.length; i++) { + uiintro.add(node.added[i]); + } + if (node.added.length) { + uiintro.add(ui.create.div('.placeholder.slim')); + } + if (uiintro.content.firstChild) { + uiintro.content.firstChild.style.paddingTop = '3px'; + } + } + if (lib.config.touchscreen) { + lib.setScroll(uiintro.contentContainer); + } + return uiintro; + } + static linkintro(dialog, content, player) { + dialog.content.firstChild.remove(); + dialog.add('
已横置
'); + var list = []; + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isLinked() && game.players[i].name && !game.players[i].name.startsWith('unknown')) { + list.push(game.players[i]); + } + } + if (list.length) { + dialog.add(list, true, true); + } + } + static groups() { return ['wei', 'shu', 'wu', 'qun', 'jin', 'western', 'key']; } + static types() { + var types = []; + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(lib.config.mode) == false) continue; + if (lib.card[i].forbid && lib.card[i].forbid.includes(lib.config.mode)) continue; + if (lib.card[i].type) { + if (lib.card[i].type == 'delay') types.add('trick'); + else types.add(lib.card[i].type); + } + } + return types; + } + static links(buttons) { + var links = []; + for (var i = 0; i < buttons.length; i++) { + if (buttons[i].link != undefined) links.push(buttons[i].link); + } + return links; + } + static threaten(target, player, hp) { + var threaten = 1; + var skills = target.getSkills(); + if (!player && player !== false) { + player = _status.event.player; + } + for (var i = 0; i < skills.length; i++) { + var info = get.info(skills[i]); + if (info && info.ai && info.ai.threaten) { + if (typeof info.ai.threaten == 'function' && player) { + var tmp = info.ai.threaten(player, target); + if (typeof tmp == 'number') { + threaten *= tmp; + } + } + else if (typeof info.ai.threaten == 'number') { + threaten *= info.ai.threaten; + } + } + } + if (hp) { + switch (target.hp) { + case 0: threaten *= 1.5; break; + case 1: threaten *= 1.2; break; + } + switch (target.countCards('h')) { + case 0: threaten *= 1.5; break; + case 1: threaten *= 1.2; break; + } + } + return threaten; + } + static condition(player) { + var num = player.hp; + if (num > 4) { + num = 4 + Math.sqrt(num - 4); + } + else { + if (player.isHealthy()) { + if (player.hp == 3) { + num += 0.5; + } + else if (player.hp < 3) { + num++; + } + } + } + num += player.countCards('h') / 2; + var es = player.getCards('e'); + for (var i = 0; i < es.length; i++) { + var val = get.equipValueNumber(es[i]); + if (val >= 7) num += 0.8; + if (val >= 5) num += 0.5; + if (val >= 3) num += 0.2; + } + return num; + } + static attitude(from, to) { + if (!from || !to) return 0; + from = from._trueMe || from; + arguments[0] = from; + var att = get.rawAttitude.apply(this, arguments); + if (from.isMad()) att = -att; + if (to.isMad() && att > 0) { + if (to.identity == 'zhu') { + att = 1; + } + else { + att = 0; + } + } + if (!_status.tempnofake) { + _status.tempnofake = true; + if (from.ai.modAttitudeFrom) { + att = from.ai.modAttitudeFrom(from, to, att); + } + if (to.ai.modAttitudeTo) { + att = to.ai.modAttitudeTo(from, to, att); + } + delete _status.tempnofake; + } + return att; + } + static sgnAttitude() { + return get.sgn(get.attitude.apply(this, arguments)); + } + static useful_raw(card, player) { + if (get.position(card) == 'j') return -1; + if (get.position(card) == 'e') return get.equipValue(card); + if (card._modUseful) { + return card._modUseful(); + } + var i = 0; + if (!player) player = _status.event.player; + if (player) { + if (_status.event.useCache) { + i = game.callFuncUseStepCache("player.getCardsInUseful", function (player, position, cardname) { + return player.getCards(position, cardname); + }, [player, 'h', card.name]).indexOf(card); + } else { + i = player.getCards('h', card.name).indexOf(card); + } + if (i < 0) i = 0; + } + var aii = get.info(card).ai; + var useful; + if (aii && aii.useful) useful = aii.useful; + else if (aii && aii.basic) useful = aii.basic.useful; + var result; + if (useful == undefined) result = -1; + else if (typeof useful == 'function') { + result = useful(card, i); + } + else if (typeof useful == 'number') result = useful; + else if (i < useful.length) { + result = useful[i]; + } + else result = useful[useful.length - 1]; + result = game.checkMod(player, card, result, 'aiUseful', player); + return result; + } + static useful(card, player) { + if (_status.event.useCache) { + return game.callFuncUseStepCache("get.useful_raw", get.useful_raw, [card, player]); + } + return get.useful_raw(card, player); + } + static unuseful(card) { return -get.useful(card); } + static unuseful2(card) { return 10 - get.useful(card); } + static unuseful3(card) { + if (card.name == 'du') return 20; + return 10 - get.useful(card); + } + static value(card, player, method) { + var result = 0; + var value; + if (Array.isArray(card)) { + if (!card.length) return 0; + value = 0; + for (var i = 0; i < card.length; i++) { + value += get.value(card[i], player, method); + } + return value / Math.sqrt(card.length); + } + if (card._modValue) { + return card._modValue(player, method); + } + var aii = get.info(card).ai; + if (aii && aii.value) value = aii.value; + else if (aii && aii.basic) value = aii.basic.value; + if (player == undefined || get.itemtype(player) != 'player') player = _status.event.player; + var geti = function () { + var num = 0, i; + var cards = player.getCards('hs', card.name); + if (cards.includes(card)) { + return cards.indexOf(card); + } + return cards.length; + }; + if (typeof value == 'function') { + result = value(card, player, geti(), method); + } + if (typeof value == 'number') result = value; + if (Array.isArray(value)) { + if (method == 'raw') result = value[0]; + var num = geti(); + if (num < value.length) result = value[num]; + else result = value[value.length - 1]; + } + result = game.checkMod(player, card, result, 'aiValue', player); + return result; + } + static equipResult(player, target, name) { + var card = get.card(); + if (!card || card.name != name) { + card = { name: name }; + } + var value1 = get.equipValue(card, target); + var value2 = 0; + if (!player.canEquip(card)) { + if (!player.canEquip(card, true)) return 0; + var current = target.getEquip(card); + if (current && current != card) { + value2 = get.equipValue(current, target); + if (value2 > 0 && !target.needsToDiscard() && !get.tag(card, 'valueswap')) { + return 0; + } + } + } + return Math.max(0, value1 - value2) / 5; + } + static equipValue(card, player) { + if (player == undefined || get.itemtype(player) != 'player') player = get.owner(card); + if (player == undefined || get.itemtype(player) != 'player') player = _status.event.player; + var info = get.info(card); + if (!info.ai) return 0; + var value = info.ai.equipValue; + if (value == undefined) { + if (info.ai.basic && info.ai.basic.equipValue != undefined) { + value = info.ai.basic.equipValue; + } + else return 0; + } + if (typeof value == 'number') return value; + if (typeof value == 'function') return value(card, player, null, 'raw2'); + return 0; + } + static equipValueNumber(card) { + var info = get.info(card); + if (info.ai) { + if (typeof info.ai.equipValue == 'number') return info.ai.equipValue; + if (info.ai.basic && typeof info.ai.basic.equipValue == 'number') return info.ai.basic.equipValue; + } + return 0; + } + static disvalue(card, player) { return -get.value(card, player); } + static disvalue2(card, player) { return -get.value(card, player, 'raw'); } + static skillthreaten(skill, player, target) { + if (!lib.skill[skill]) return 1; + if (!lib.skill[skill].ai) return 1; + var threaten = lib.skill[skill].ai.threaten; + if (typeof threaten == 'number') return threaten; + if (typeof threaten == 'function') { + player = player || _status.event.player; + target = target || player; + return threaten(player, target); + } + return 1; + } + static order(item) { + var info = get.info(item); + if (!info) return -1; + var aii = info.ai; + var order; + if (aii && aii.order) order = aii.order; + else if (aii && aii.basic) order = aii.basic.order; + if (order == undefined) return -1; + var num = order; + if (typeof (order) == 'function') { + num = order(item, _status.event.player); + } + if (typeof item == 'object' && _status.event.player) { + var player = _status.event.player; + num = game.checkMod(player, item, num, 'aiOrder', player); + } + return num; + } + static result(item, skill) { + var result; + var info = get.info(item); + if (info.ai) result = get.copy(info.ai.result); + if (typeof (result) == 'function') result = result(item); + if (!result) result = {}; + if (skill) { + var info2 = get.info(skill); + if (info2.ai) { + info2 = info2.ai.result; + for (var i in info2) { + result[i] = info2[i]; + } + } + } + return result; + } + static effect_use(target, card, player, player2, isLink) { + var event = _status.event; + var eventskill = null; + if (player == undefined) player = _status.event.player; + if (card && typeof card == 'object' && 'name' in card) card = get.autoViewAs(card); + if (typeof card != 'string' && (typeof card != 'object' || !card.name)) { + var skillinfo = get.info(event.skill); + if (event.skill && skillinfo.viewAs == undefined) card = _status.event.skill; + else { + card = get.card(); + if (skillinfo && skillinfo.viewAs && card.name === skillinfo.viewAs.name) { + eventskill = event.skill; + } + } + } + var info = get.info(card); + if (typeof card == 'object' && info && info.changeTarget) { + var targets = [target]; + info.changeTarget(player, targets); + var eff = 0; + for (var i of targets) { + eff += get.effect(i, card, player, player2, isLink); + } + return eff; + } + var result = get.result(card, eventskill); + var result1 = result.player_use || result.player, result2 = result.target_use || result.target; + if (typeof result1 == 'function') result1 = result1(player, target, card, isLink); + if (typeof result2 == 'function') result2 = result2(player, target, card, isLink); + + if (typeof result1 != 'number') result1 = 0; + if (typeof result2 != 'number') result2 = 0; + var temp1, temp2, temp3, temp01 = 0, temp02 = 0, threaten = 1; + var skills1 = player.getSkills().concat(lib.skill.global); + game.expandSkills(skills1); + var zerotarget = false, zeroplayer = false; + for (var i = 0; i < skills1.length; i++) { + temp1 = get.info(skills1[i]).ai; + if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player_use == 'function') { + temp1 = temp1.effect.player_use(card, player, target, result1, isLink); + } + else if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player == 'function') { + temp1 = temp1.effect.player(card, player, target, result1, isLink); + } + else temp1 = undefined; + if (typeof temp1 == 'object') { + if (temp1.length == 2 || temp1.length == 4) { + result1 *= temp1[0]; + temp01 += temp1[1]; + } + if (temp1.length == 4) { + result2 *= temp1[2]; + temp02 += temp1[3]; + } + } + else if (typeof temp1 == 'number') { + result1 *= temp1; + } + else if (temp1 == 'zeroplayer') { + zeroplayer = true; + } + else if (temp1 == 'zerotarget') { + zerotarget = true; + } + else if (temp1 == 'zeroplayertarget') { + zeroplayer = true; + zerotarget = true; + } + } + if (target) { + var skills2 = target.getSkills().concat(lib.skill.global); + game.expandSkills(skills2); + for (var i = 0; i < skills2.length; i++) { + temp2 = get.info(skills2[i]).ai; + if (temp2 && temp2.threaten) temp3 = temp2.threaten; + else temp3 = undefined; + if (temp2 && typeof temp2.effect == 'function') { + if (!player.hasSkillTag('ignoreSkill', true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + })) temp2 = temp2.effect(card, player, target, result2, isLink); + else temp2 = undefined; + } + else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target_use == 'function') { + if (!player.hasSkillTag('ignoreSkill', true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + })) temp2 = temp2.effect.target_use(card, player, target, result2, isLink); + else temp2 = undefined; + } + else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target == 'function') { + if (!player.hasSkillTag('ignoreSkill', true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + })) temp2 = temp2.effect.target(card, player, target, result2, isLink); + else temp2 = undefined; + } + else temp2 = undefined; + if (typeof temp2 == 'object') { + if (temp2.length == 2 || temp2.length == 4) { + result2 *= temp2[0]; + temp02 += temp2[1]; + } + if (temp2.length == 4) { + result1 *= temp2[2]; + temp01 += temp2[3]; + } + } + else if (typeof temp2 == 'number') { + result2 *= temp2; + } + else if (temp2 == 'zeroplayer') { + zeroplayer = true; + } + else if (temp2 == 'zerotarget') { + zerotarget = true; + } + else if (temp2 == 'zeroplayertarget') { + zeroplayer = true; + zerotarget = true; + } + if (typeof temp3 == 'function' && temp3(player, target) != undefined) { + threaten *= temp3(player, target); + } + else if (typeof temp3 == 'object') { + if (typeof temp3.target == 'number') { + threaten *= temp3; + } + else if (typeof temp3.target == 'function' && temp3(player, target) != undefined) { + threaten *= temp3(player, target); + } + } + else if (typeof temp3 == 'number') { + threaten *= temp3; + } + } + result2 += temp02; + result1 += temp01; + if (typeof card == 'object' && !result.ignoreStatus) { + if (get.attitude(player, target) < 0) { + result2 *= Math.sqrt(threaten); + } + else { + result2 *= Math.sqrt(Math.sqrt(threaten)); + } + if (target.hp == 1) result2 *= 2.5; + if (target.hp == 2) result2 *= 1.8; + if (target.countCards('h') == 0) { + if (get.tag(card, 'respondSha') || get.tag(card, 'respondShan')) { + result2 *= 1.7; + } + else { + result2 *= 1.5; + } + } + if (target.countCards('h') == 1) result2 *= 1.3; + if (target.countCards('h') == 2) result2 *= 1.1; + if (target.countCards('h') > 3) result2 *= 0.5; + if (target.hp == 4) result2 *= 0.9; + if (target.hp == 5) result2 *= 0.8; + if (target.hp > 5) result2 *= 0.6; + } + } + else { + result2 += temp02; + result1 += temp01; + } + if (zeroplayer) result1 = 0; + if (zerotarget) result2 = 0; + var final = 0; + if (player2) { + final = (result1 * get.attitude(player2, player) + (target ? result2 * get.attitude(player2, target) : 0)); + } + else final = (result1 * get.attitude(player, player) + (target ? result2 * get.attitude(player, target) : 0)); + if (!isLink && get.tag(card, 'natureDamage') && !zerotarget) { + var info = get.info(card); + if (!info || !info.ai || !info.ai.canLink) { + if (target.isLinked()) game.players.forEach(function (current) { + if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); + }); + } + else if (info.ai.canLink(player, target, card)) { + game.players.forEach(function (current) { + if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); + }); + } + } + return final; + } + static effect(target, card, player, player2, isLink) { + var event = _status.event; + var eventskill = null; + if (player == undefined) player = _status.event.player; + if (card && typeof card == 'object' && 'name' in card) card = get.autoViewAs(card); + if (typeof card != 'string' && (typeof card != 'object' || !card.name)) { + var skillinfo = get.info(event.skill); + if (event.skill && skillinfo.viewAs == undefined) card = _status.event.skill; + else { + card = get.card(); + if (skillinfo && skillinfo.viewAs && card.name === skillinfo.viewAs.name) { + eventskill = event.skill; + } + } + } + var result = get.result(card, eventskill); + var result1 = result.player, result2 = result.target; + if (typeof result1 == 'function') result1 = result1(player, target, card, isLink); + if (typeof result2 == 'function') result2 = result2(player, target, card, isLink); + + if (typeof result1 != 'number') result1 = 0; + if (typeof result2 != 'number') result2 = 0; + var temp1, temp2, temp3, temp01 = 0, temp02 = 0, threaten = 1; + var skills1 = player.getSkills().concat(lib.skill.global); + game.expandSkills(skills1); + var zerotarget = false, zeroplayer = false; + for (var i = 0; i < skills1.length; i++) { + temp1 = get.info(skills1[i]).ai; + if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player == 'function') { + temp1 = temp1.effect.player(card, player, target, result1, isLink); + } + else temp1 = undefined; + if (typeof temp1 == 'object') { + if (temp1.length == 2 || temp1.length == 4) { + result1 *= temp1[0]; + temp01 += temp1[1]; + } + if (temp1.length == 4) { + result2 *= temp1[2]; + temp02 += temp1[3]; + } + } + else if (typeof temp1 == 'number') { + result1 *= temp1; + } + else if (temp1 == 'zeroplayer') { + zeroplayer = true; + } + else if (temp1 == 'zerotarget') { + zerotarget = true; + } + else if (temp1 == 'zeroplayertarget') { + zeroplayer = true; + zerotarget = true; + } + } + if (target) { + var skills2 = target.getSkills().concat(lib.skill.global); + game.expandSkills(skills2); + for (var i = 0; i < skills2.length; i++) { + temp2 = get.info(skills2[i]).ai; + if (temp2 && temp2.threaten) temp3 = temp2.threaten; + else temp3 = undefined; + if (temp2 && typeof temp2.effect == 'function') { + if (!player.hasSkillTag('ignoreSkill', true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + })) temp2 = temp2.effect(card, player, target, result2, isLink); + else temp2 = undefined; + } + else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target == 'function') { + if (!player.hasSkillTag('ignoreSkill', true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + })) temp2 = temp2.effect.target(card, player, target, result2, isLink); + else temp2 = undefined; + } + else temp2 = undefined; + if (typeof temp2 == 'object') { + if (temp2.length == 2 || temp2.length == 4) { + result2 *= temp2[0]; + temp02 += temp2[1]; + } + if (temp2.length == 4) { + result1 *= temp2[2]; + temp01 += temp2[3]; + } + } + else if (typeof temp2 == 'number') { + result2 *= temp2; + } + else if (temp2 == 'zeroplayer') { + zeroplayer = true; + } + else if (temp2 == 'zerotarget') { + zerotarget = true; + } + else if (temp2 == 'zeroplayertarget') { + zeroplayer = true; + zerotarget = true; + } + if (typeof temp3 == 'function' && temp3(player, target) != undefined) { + threaten *= temp3(player, target); + } + else if (typeof temp3 == 'object') { + if (typeof temp3.target == 'number') { + threaten *= temp3; + } + else if (typeof temp3.target == 'function' && temp3(player, target) != undefined) { + threaten *= temp3(player, target); + } + } + else if (typeof temp3 == 'number') { + threaten *= temp3; + } + } + result2 += temp02; + result1 += temp01; + if (typeof card == 'object' && !result.ignoreStatus) { + if (get.attitude(player, target) < 0) { + result2 *= Math.sqrt(threaten); + } + else { + result2 *= Math.sqrt(Math.sqrt(threaten)); + } + // *** continue here *** + if (target.hp == 1) result2 *= 2.5; + if (target.hp == 2) result2 *= 1.8; + if (target.countCards('h') == 0) { + if (get.tag(card, 'respondSha') || get.tag(card, 'respondShan')) { + result2 *= 1.7; + } + else { + result2 *= 1.5; + } + } + if (target.countCards('h') == 1) result2 *= 1.3; + if (target.countCards('h') == 2) result2 *= 1.1; + if (target.countCards('h') > 3) result2 *= 0.5; + if (target.hp == 4) result2 *= 0.9; + if (target.hp == 5) result2 *= 0.8; + if (target.hp > 5) result2 *= 0.6; + } + } + else { + result2 += temp02; + result1 += temp01; + } + if (zeroplayer) result1 = 0; + if (zerotarget) result2 = 0; + var final = 0; + if (player2) { + final = (result1 * get.attitude(player2, player) + (target ? result2 * get.attitude(player2, target) : 0)); + } + else final = (result1 * get.attitude(player, player) + (target ? result2 * get.attitude(player, target) : 0)); + if (!isLink && get.tag(card, 'natureDamage') && !zerotarget) { + var info = get.info(card); + if (!info || !info.ai || !info.ai.canLink) { + if (target.isLinked()) game.players.forEach(function (current) { + if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); + }); + } + else if (info.ai.canLink(player, target, card)) { + game.players.forEach(function (current) { + if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); + }); + } + } + return final; + } + static damageEffect(target, player, viewer, nature) { + if (get.itemtype(nature) == 'natures') { + var natures = get.natureList(nature); + return natures.map(n => get.damageEffect(target, player, viewer, n)).reduce((p, c) => p + c, 0) / (natures.length || 1); + } + if (!player) { + player = target; + } + if (!viewer) { + viewer = target; + } + var name = 'damage'; + if (nature == 'fire') { + name = 'firedamage'; + } + else if (nature == 'thunder') { + name = 'thunderdamage'; + } + else if (nature == 'ice') { + name = 'icedamage'; + } + var eff = get.effect(target, { name: name }, player, viewer); + if (eff > 0 && target.hujia > 0) return eff / 1.3; + return eff; + } + static recoverEffect(target, player, viewer) { + if (target.hp == target.maxHp) return 0; + if (!player) { + player = target; + } + if (!viewer) { + viewer = target; + } + return get.effect(target, { name: 'recover' }, player, viewer); + } + static buttonValue(button) { + var card = button.link; + var player = get.owner(card); + if (!player) player = _status.event.player; + if (player.getCards('j').includes(card)) { + var efff = get.effect(player, { + name: card.viewAs || card.name, + cards: [card], + }, player, player); + if (efff > 0) return 0.5; + if (efff == 0) return 0; + return -1.5; + } + if (player.getCards('e').includes(card)) { + var evalue = get.value(card, player); + if (player.hasSkillTag('noe')) { + if (evalue >= 7) { + return evalue / 6; + } + return evalue / 10; + } + return evalue / 3; + } + if (player.hasSkillTag('noh')) return 0.1; + var nh = player.countCards('h'); + switch (nh) { + case 1: return 2; + case 2: return 1.6; + case 3: return 1; + case 4: return 0.8; + case 5: return 0.6; + default: return 0.4; + } + } + static attitude2(to) { return get.attitude(_status.event.player, to); } +} + +export const get = Get; + +export { + Is +}; diff --git a/noname/init/import.js b/noname/init/import.js index 1c7177c08..c08354319 100644 --- a/noname/init/import.js +++ b/noname/init/import.js @@ -1,41 +1,41 @@ -import { Game as game } from '../game/index.js'; - -/** - * @param {string} name - 卡牌包名 - * @returns {Promise} - */ -export const importCardPack = generateImportFunction('card', (name) => `../../card/${name}.js`) - -/** - * @param {string} name - 武将包名 - * @returns {Promise} - */ -export const importCharacterPack = generateImportFunction('character', (name) => `../../character/${name}.js`) - -/** - * @param {string} name - 扩展名 - * @returns {Promise} - */ -export const importExtension = generateImportFunction('extension', (name) => `../../extension/${name}/extension.js`) - -/** - * @param {string} name - 模式名 - * @returns {Promise} - */ -export const importMode = generateImportFunction('mode', (name) => `../../mode/${name}.js`) - -/** - * 生成导入 - * - * @param {string} type - * @param {(name: string) => string} pathParser - * @returns {(name: string) => Promise} - */ -function generateImportFunction(type, pathParser) { - return async (name) => { - const modeContent = await import(pathParser(name)); - if (!modeContent.type) return; - if (modeContent.type !== type) throw new Error(`Loaded Content doesn't conform to "${type}" but "${modeContent.type}".`); - await game.import(type, modeContent.default); - } -} +import { Game as game } from '../game/index.js'; + +/** + * @param {string} name - 卡牌包名 + * @returns {Promise} + */ +export const importCardPack = generateImportFunction('card', (name) => `../../card/${name}.js`) + +/** + * @param {string} name - 武将包名 + * @returns {Promise} + */ +export const importCharacterPack = generateImportFunction('character', (name) => `../../character/${name}.js`) + +/** + * @param {string} name - 扩展名 + * @returns {Promise} + */ +export const importExtension = generateImportFunction('extension', (name) => `../../extension/${name}/extension.js`) + +/** + * @param {string} name - 模式名 + * @returns {Promise} + */ +export const importMode = generateImportFunction('mode', (name) => `../../mode/${name}.js`) + +/** + * 生成导入 + * + * @param {string} type + * @param {(name: string) => string} pathParser + * @returns {(name: string) => Promise} + */ +function generateImportFunction(type, pathParser) { + return async (name) => { + const modeContent = await import(pathParser(name)); + if (!modeContent.type) return; + if (modeContent.type !== type) throw new Error(`Loaded Content doesn't conform to "${type}" but "${modeContent.type}".`); + await game.import(type, modeContent.default); + } +} diff --git a/noname/init/index.js b/noname/init/index.js index 7a5e3ad12..1cc23525d 100644 --- a/noname/init/index.js +++ b/noname/init/index.js @@ -1,981 +1,970 @@ - -import { AI as ai } from '../ai/index.js'; -import { Get as get } from '../get/index.js'; -import { Library as lib } from '../library/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; - -import { userAgent } from '../util/index.js'; -import * as config from '../util/config.js'; -import { gnc } from '../gnc/index.js'; - -import { importCardPack, importCharacterPack, importExtension, importMode } from './import.js'; -import { onload } from './onload.js'; - -// 无名杀,启动! -export async function boot() { - // 不想看,反正别动 - if (typeof __dirname === 'string' && __dirname.length) { - const dirsplit = __dirname.split('/'); - for (let i = 0; i < dirsplit.length; i++) { - if (dirsplit[i]) { - var c = dirsplit[i][0]; - lib.configprefix += /[A-Z]|[a-z]/.test(c) ? c : '_'; - } - } - lib.configprefix += '_'; - } - - // 加载polyfill内容 - await import('./polyfill.js'); - - // 设定游戏加载时间,超过时间未加载就提醒 - const configLoadTime = localStorage.getItem(lib.configprefix + 'loadtime'); - // 现在不暴露到全局变量里了,直接传给onload - const resetGameTimeout = setTimeout(lib.init.reset, configLoadTime ? parseInt(configLoadTime) : 10000) - - if (Reflect.has(window, 'cordovaLoadTimeout')) { - clearTimeout(Reflect.get(window, 'cordovaLoadTimeout')); - Reflect.deleteProperty(window, 'cordovaLoadTimeout'); - } - - for (const link of document.head.querySelectorAll('link')) { - if (link.href.includes('app/color.css')) { - link.remove(); - break; - } - } - - setServerIndex(); - setBackground(); - - Reflect.set(lib, 'get', get); - Reflect.set(lib, 'ui', ui); - Reflect.set(lib, 'ai', ai); - Reflect.set(lib, 'game', game); - _status.event = lib.element.GameEvent.initialGameEvent(); - - setWindowListener(); - - // 无名杀更新日志 - if (window.noname_update) { - Reflect.set(lib, 'version', window.noname_update.version); - lib.changeLog = window.noname_update.changeLog; - if (window.noname_update.players) { - lib.changeLog.push('players://' + JSON.stringify(window.noname_update.players)); - } - if (window.noname_update.cards) { - lib.changeLog.push('cards://' + JSON.stringify(window.noname_update.cards)); - } - delete window.noname_update; - } - // 确认手机端平台 - const noname_inited = localStorage.getItem('noname_inited'); - if (noname_inited && noname_inited !== 'nodejs') { - const ua = userAgent; - if (ua.includes('android')) { - Reflect.set(lib, 'device', 'android'); - } - else if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('macintosh')) { - Reflect.set(lib, 'device', 'ios'); - } - } - - // 在dom加载完后执行相应的操作 - const waitDomLoad = new Promise((resolve) => { - if (document.readyState !== 'complete') { - window.onload = resolve; - } else resolve(void 0) - }).then(onWindowReady.bind(window)); - - - // 闭源客户端检测并提醒 - if (lib.assetURL.includes('com.widget.noname.qingyao') || lib.assetURL.includes('online.nonamekill.android')) { - alert('您正在一个不受信任的闭源客户端上运行《无名杀》。建议您更换为其他开源的无名杀客户端,避免给您带来不必要的损失。'); - } - - // Electron平台 - if (typeof window.require === 'function') { - const { nodeReady } = await import('./node.js'); - nodeReady(); - } - // 手机平台已在别处判断 - else if (!Reflect.has(lib, 'device')) { - Reflect.set(lib, 'path', (await import('../library/path.js')).default); - //为其他自定义平台提供文件读写函数赋值的一种方式。 - //但这种方式只能修改game的文件读写函数。 - if (typeof window.initReadWriteFunction == 'function') { - const g = {}; - const ReadWriteFunctionName = ['download', 'readFile', 'readFileAsText', 'writeFile', 'removeFile', 'getFileList', 'ensureDirectory', 'createDir']; - ReadWriteFunctionName.forEach(prop => { - Object.defineProperty(g, prop, { - configurable: true, - get() { return undefined; }, - set(newValue) { - if (typeof newValue == 'function') { - delete g[prop]; - g[prop] = game[prop] = newValue; - } - } - }); - }); - // @ts-ignore - window.initReadWriteFunction(g); - } - window.onbeforeunload = function () { - if (config.get('confirm_exit') && !_status.reloading) { - return '是否离开游戏?'; - } - else { - return null; - } - }; - } - - const loadCssPromise = loadCss(); - const loadConfigPromise = loadConfig(); - await loadCssPromise; - const config2 = await loadConfigPromise; - - // 读取模式 - if (config2.mode) config.set('mode', config2.mode); - if (config.get('mode_config')[config.get('mode')] === undefined) - config.get('mode_config')[config.get('mode')] = {}; - - // 复制共有模式设置 - for (const name in config.get('mode_config').global) { - if (config.get('mode_config')[config.get('mode')][name] === undefined) { - config.get('mode_config')[config.get('mode')][name] = config.get('mode_config').global[name]; - } - } - - if (config.get('characters')) - config.set('defaultcharacters', config.get('characters').slice(0)); - if (config.get('cards')) - config.set('defaultcards', config.get('cards').slice(0)); - - for (const name in config2) { - if (name.includes('_mode_config')) { - var thismode = name.substr(name.indexOf('_mode_config') + 13); - if (!config.get('mode_config')[thismode]) - config.get('mode_config')[thismode] = {}; - config.get('mode_config')[thismode][name.substr(0, name.indexOf('_mode_config'))] = config2[name]; - } - else { - config.set(name, config2[name]); - } - } - - for (const name in get.config('translate')) { - lib.translate[name] = get.config('translate')[name]; - } - - config.get('all').characters = []; - config.get('all').cards = []; - config.get('all').plays = []; - config.get('all').mode = []; - - if (config.get('debug')) { - await lib.init.promises.js(`${lib.assetURL}game`, 'asset'); - if (window.noname_skin_list) { - lib.skin = window.noname_skin_list; - delete window.noname_skin_list; - delete window.noname_asset_list; - } - } - - if (Reflect.get(window, 'isNonameServer')) - config.set('mode', 'connect'); - - var pack = Reflect.get(window, 'noname_package'); - Reflect.deleteProperty(window, 'noname_package'); - for (const name in pack.character) { - if (config.get('all').sgscharacters.includes(name) || config.get('hiddenCharacterPack').indexOf(name) == -1) { - config.get('all').characters.push(name); - lib.translate[name + '_character_config'] = pack.character[name]; - } - } - for (const name in pack.card) { - if (config.get('all').sgscards.includes(name) || config.get('hiddenCardPack').indexOf(name) == -1) { - config.get('all').cards.push(name); - lib.translate[name + '_card_config'] = pack.card[name]; - } - } - for (const name in pack.play) { - config.get('all').plays.push(name); - lib.translate[name + '_play_config'] = pack.play[name]; - } - for (const name in pack.submode) { - for (var j in pack.submode[name]) { - lib.translate[name + '|' + j] = pack.submode[name][j]; - } - } - - if (!config.get('gameRecord')) - config.set('gameRecord', {}); - for (const name in pack.mode) { - if (config.get('hiddenModePack').indexOf(name) == -1) { - config.get('all').mode.push(name); - lib.translate[name] = pack.mode[name]; - if (!config.get('gameRecord')[name]) - config.get('gameRecord')[name] = { data: {} }; - } - } - if (config.get('all').mode.length == 0) { - config.get('all').mode.push('identity'); - lib.translate.identity = '身份'; - if (!config.get('gameRecord').identity) - config.get('gameRecord').identity = { data: {} }; - } - if (pack.background) { - for (const name in pack.background) { - if (config.get('hiddenBackgroundPack').includes(name)) continue; - lib.configMenu.appearence.config.image_background.item[name] = pack.background[name]; - } - for (let i = 0; i < config.get('customBackgroundPack').length; i++) { - var link = config.get('customBackgroundPack')[i]; - lib.configMenu.appearence.config.image_background.item[link] = link.slice(link.indexOf('_') + 1); - } - lib.configMenu.appearence.config.image_background.item.default = '默认'; - } - if (pack.music) { - if (Reflect.has(lib, 'device') || typeof window.require === 'function') { - lib.configMenu.audio.config.background_music.item.music_custom = '自定义音乐'; - } - config.get('all').background_music = ['music_default']; - for (const name in pack.music) { - config.get('all').background_music.push(name); - lib.configMenu.audio.config.background_music.item[name] = pack.music[name]; - } - if (config.get('customBackgroundMusic')) { - for (const name in config.get('customBackgroundMusic')) { - config.get('all').background_music.push(name); - lib.configMenu.audio.config.background_music.item[name] = config.get('customBackgroundMusic')[name]; - } - } - lib.configMenu.audio.config.background_music.item.music_random = '随机播放'; - lib.configMenu.audio.config.background_music.item.music_off = '关闭'; - } - if (pack.theme) { - for (const name in pack.theme) { - lib.configMenu.appearence.config.theme.item[name] = pack.theme[name]; - } - } - if (config.get('extension_sources')) { - for (const name in config.get('extension_sources')) { - lib.configMenu.general.config.extension_source.item[name] = name; - } - } - - if (pack.font) { - Reflect.get(ui, 'css').fontsheet = lib.init.sheet(); - const appearenceConfig = lib.configMenu.appearence.config, fontSheet = Reflect.get(ui, 'css').fontsheet.sheet, suitsFont = config.get('suits_font'); - Object.keys(pack.font).forEach((value) => { - const font = pack.font[value]; - appearenceConfig.name_font.item[value] = font; - appearenceConfig.identity_font.item[value] = font; - appearenceConfig.cardtext_font.item[value] = font; - appearenceConfig.global_font.item[value] = font; - fontSheet.insertRule(`@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/${value}.woff2');}`, 0); - if (suitsFont) fontSheet.insertRule(`@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/suits.woff2');}`, 0); - }); - if (suitsFont) fontSheet.insertRule(`@font-face {font-family: 'Suits'; src: url('${lib.assetURL}font/suits.woff2');}`, 0); - fontSheet.insertRule(`@font-face {font-family: 'NonameSuits'; src: url('${lib.assetURL}font/suits.woff2');}`, 0); - fontSheet.insertRule(`@font-face {font-family: 'MotoyaLMaru'; src: url('${lib.assetURL}font/motoyamaru.woff2');}`, 0); - appearenceConfig.cardtext_font.item.default = '默认'; - appearenceConfig.global_font.item.default = '默认'; - } - - const ua = userAgent; - if ('ontouchstart' in document) { - if (!config.get('totouched')) { - game.saveConfig('totouched', true); - if (Reflect.has(lib, 'device')) { - game.saveConfig('low_performance', true); - game.saveConfig('confirm_exit', true); - game.saveConfig('touchscreen', true); - game.saveConfig('fold_mode', false); - if (ua.indexOf('ipad') == -1) { - game.saveConfig('phonelayout', true); - } - else if (Reflect.get(lib, 'device') === 'ios') { - game.saveConfig('show_statusbar_ios', 'overlay'); - } - } - else if (confirm('是否切换到触屏模式?(触屏模式可提高触屏设备的响应速度,但无法使用鼠标)')) { - game.saveConfig('touchscreen', true); - if (ua.includes('iphone') || ua.includes('android')) { - game.saveConfig('phonelayout', true); - } - game.reload(); - } - } - } - else if (config.get('touchscreen')) { - game.saveConfig('touchscreen', false); - } - if (!config.get('toscrolled') && ua.includes('macintosh')) { - game.saveConfig('toscrolled', true); - game.saveConfig('mousewheel', false); - } - - let show_splash = config.get('show_splash'); - if (show_splash == 'off') { - show_splash = false; - } - else if (show_splash == 'init') { - if (localStorage.getItem('show_splash_off')) { - show_splash = false; - } - } - localStorage.removeItem('show_splash_off'); - const extensionlist = []; - if (!localStorage.getItem(lib.configprefix + 'disable_extension')) { - if (config.has('extensions') && config.get('extensions').length) { - Reflect.set(window, 'resetExtension', () => { - for (var i = 0; i < config.get('extensions').length; i++) { - game.saveConfig('extension_' + config.get('extensions')[i] + '_enable', false); - } - // @ts-ignore - localStorage.setItem(lib.configprefix + 'disable_extension', true); - }); - } - for (var name = 0; name < config.get('plays').length; name++) { - if (config.get('all').plays.includes(config.get('plays')[name])) { - extensionlist.push(config.get('plays')[name]); - } - } - var alerted = false; - for (var name = 0; name < config.get('extensions').length; name++) { - if (Reflect.get(window, 'bannedExtensions').includes(config.get('extensions')[name])) { - //if(!alerted) alert('读取某些扩展时出现问题。'); - alerted = true; - continue; - } - var extcontent = localStorage.getItem(lib.configprefix + 'extension_' + config.get('extensions')[name]); - if (extcontent) { - //var backup_onload=lib.init.onload; - _status.evaluatingExtension = true; - try { - eval(extcontent); - } - catch (e) { - console.log(e); - } - //lib.init.onload=backup_onload; - _status.evaluatingExtension = false; - } - else if (config.get('mode') != 'connect' || (!localStorage.getItem(lib.configprefix + 'directstart') && show_splash)) { - extensionlist.push(config.get('extensions')[name]); - } - } - } - else { - if (config.get('mode') != 'connect' || (!localStorage.getItem(lib.configprefix + 'directstart') && show_splash)) { - var alerted = false; - for (var name = 0; name < config.get('extensions').length; name++) { - if (Reflect.get(window, 'bannedExtensions').includes(config.get('extensions')[name])) { - //if(!alerted) alert('读取某些扩展时出现问题。'); - alerted = true; - continue; - } - // @ts-ignore - game.import('extension', { name: config.get('extensions')[name] }); - } - } - } - - let layout = config.get('layout'); - if (layout == 'default' || lib.layoutfixed.indexOf(config.get('mode')) !== -1) { - layout = 'mobile'; - } - if (layout == 'phone') { - layout = 'mobile'; - game.saveConfig('layout', 'mobile'); - game.saveConfig('phonelayout', true); - } - Reflect.set(game, 'layout', layout); - - if (config.get('image_background_random')) { - if (_status.htmlbg) { - game.saveConfig('image_background', _status.htmlbg); - } - else { - const list = []; - for (const name in lib.configMenu.appearence.config.image_background.item) { - if (name == 'default') continue; - list.push(name); - } - // @ts-ignore - game.saveConfig('image_background', list.randomGet(lib.config.image_background)); - } - lib.init.background(); - } - delete _status.htmlbg; - - // 虽然但是,我就暴露个import,应该没啥问题 - Reflect.set(window, 'game', { - import: game.import.bind(null) - }); - - if (config.get('layout') == 'default') { - config.set('layout', 'mobile'); - } - - const stylesName = ['layout', 'theme', 'card_style', 'cardback_style', 'hp_style']; - const stylesLoading = [ - lib.init.promises.css(lib.assetURL + 'layout/' + layout, 'layout', void 0, true), - lib.init.promises.css(lib.assetURL + 'theme/' + config.get('theme'), 'style', void 0, true), - lib.init.promises.css(lib.assetURL + 'theme/style/card', config.get('card_style'), void 0, true), - lib.init.promises.css(lib.assetURL + 'theme/style/cardback', config.get('cardback_style'), void 0, true), - lib.init.promises.css(lib.assetURL + 'theme/style/hp', config.get('hp_style'), void 0, true) - ]; - - if (get.is.phoneLayout()) { - stylesName.push('phone'); - stylesLoading.push(lib.init.promises.css(lib.assetURL + 'layout/default', 'phone')); - } - else { - Reflect.get(ui, 'css').phone = lib.init.css(); - } - - initSheet(Reflect.get(lib, 'config')); - - config.set('duration', 500); - - if (!config.get('touchscreen')) { - document.addEventListener('mousewheel', ui.click.windowmousewheel, { passive: true }); - document.addEventListener('mousemove', ui.click.windowmousemove); - document.addEventListener('mousedown', ui.click.windowmousedown); - document.addEventListener('mouseup', ui.click.windowmouseup); - document.addEventListener('contextmenu', ui.click.right); - } - else { - document.addEventListener('touchstart', ui.click.touchconfirm); - document.addEventListener('touchstart', ui.click.windowtouchstart); - document.addEventListener('touchend', ui.click.windowtouchend); - document.addEventListener('touchmove', ui.click.windowtouchmove); - } - - const stylesLoaded = await Promise.all(stylesLoading); - const stylesLength = Math.min(stylesName.length, stylesLoaded.length); - for (let i = 0; i < stylesLength; ++i) { - Reflect.get(ui, 'css')[stylesName[i]] = stylesLoaded[i]; - } - - if (extensionlist.length && (config.get('mode') != 'connect' || show_splash)) { - _status.extensionLoading = []; - - const bannedExtensions = Reflect.get(window, 'bannedExtensions'); - - const extensionsLoading = []; - for (const name of extensionlist) { - if (bannedExtensions.includes(name)) continue; - extensionsLoading.push(importExtension(name)); - } - - await Promise.allSettled(extensionsLoading); - await Promise.allSettled(_status.extensionLoading); - _status.extensionLoaded.filter(Boolean).forEach((name) => { - lib.announce.publish("Noname.Init.Extension.onLoad", name); - lib.announce.publish(`Noname.Init.Extension.${name}.onLoad`, void 0); - }); - delete _status.extensionLoading; - } - - const isArray = Array.isArray; - if (isArray(lib.onprepare) && lib.onprepare.length) { - _status.onprepare = Object.freeze(lib.onprepare.map((fn) => { - if (typeof fn !== "function") return; - return (gnc.is.generatorFunc(fn) ? gnc.of(fn) : fn)(); - })); - } - - const toLoad = []; - - if (localStorage.getItem(`${lib.configprefix}playback`)) - toLoad.push(importMode(config.get('mode'))); - else if ((localStorage.getItem(`${lib.configprefix}directstart`) || !show_splash) && config.get('all').mode.includes(config.get('mode'))) - toLoad.push(importMode(config.get('mode'))); - - for (const cardPack of config.get('all').cards) { - toLoad.push(importCardPack(cardPack)); - } - for (const characterPack of config.get('all').characters) { - toLoad.push(importCharacterPack(characterPack)); - } - toLoad.push(lib.init.promises.js(`${lib.assetURL}character`, 'rank')); - - if (_status.javaScriptExtensions) { - const loadJavaScriptExtension = async (javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray, index) => { - if (!pathArray && !fileArray && !onLoadArray && !onErrorArray) { - try { - await lib.init.promises.js(javaScriptExtension.path, javaScriptExtension.file); - if (typeof javaScriptExtension.onload == 'function') javaScriptExtension.onload(); - } catch { - if (typeof javaScriptExtension.onerror == 'function') javaScriptExtension.onerror(); - } - return; - } - if (typeof index != 'number') index = 0; - if (pathArray && index >= javaScriptExtension.path.length) return; - if (fileArray && index >= javaScriptExtension.file.length) return; - if (onLoadArray && index >= javaScriptExtension.onload.length) return; - if (onErrorArray && index >= javaScriptExtension.onerror.length) return; - const path = pathArray ? javaScriptExtension.path[index] : javaScriptExtension.path; - const file = fileArray ? javaScriptExtension.file[index] : javaScriptExtension.file; - const onLoad = onLoadArray ? javaScriptExtension.onload[index] : javaScriptExtension.onload; - const onError = onErrorArray ? javaScriptExtension.onerror[index] : javaScriptExtension.onerror; - try { - await lib.init.promises.js(path, file); - if (typeof onLoad == 'function') onLoad(); - } catch { - if (typeof onError == 'function') onError(); - } - await loadJavaScriptExtension(javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray, index + 1); - }; - _status.javaScriptExtensions.forEach((javaScriptExtension) => { - const pathArray = isArray(javaScriptExtension.path); - const fileArray = isArray(javaScriptExtension.file); - const onLoadArray = isArray(javaScriptExtension.onLoad); - const onErrorArray = isArray(javaScriptExtension.onError); - toLoad.push(loadJavaScriptExtension(javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray)); - }); - } - - await Promise.allSettled(toLoad); - - if (_status.importing) { - /** - * @type {Promise[]} - */ - let promises = lib.creation.array; - for (const type in _status.importing) { - // @ts-ignore - promises.addArray(_status.importing[type]); - } - await Promise.allSettled(promises); - delete _status.importing; - } - - await waitDomLoad; - await onload(resetGameTimeout); -} - -function initSheet(libConfig) { - if (libConfig.player_style && libConfig.player_style != 'default' && libConfig.player_style != 'custom') { - var str = ''; - switch (libConfig.player_style) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646)'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; break; - } - Reflect.get(ui, 'css').player_stylesheet = lib.init.sheet('#window .player{background-image:' + str + '}'); - } - if (libConfig.border_style && libConfig.border_style != 'default' && libConfig.border_style != 'custom' && libConfig.border_style != 'auto') { - Reflect.get(ui, 'css').border_stylesheet = lib.init.sheet(); - var bstyle = libConfig.border_style; - if (bstyle.startsWith('dragon_')) { - bstyle = bstyle.slice(7); - } - Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('#window .player>.framebg,#window #arena.long.mobile:not(.fewplayer) .player[data-position="0"]>.framebg{display:block;background-image:url("' + lib.assetURL + 'theme/style/player/' + bstyle + '1.png")}', 0); - Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('#window #arena.long:not(.fewplayer) .player>.framebg, #arena.oldlayout .player>.framebg{background-image:url("' + lib.assetURL + 'theme/style/player/' + bstyle + '3.png")}', 0); - Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}', 0); - } - if (libConfig.control_style && libConfig.control_style != 'default' && libConfig.control_style != 'custom') { - var str = ''; - switch (libConfig.control_style) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px'; break; - } - if (libConfig.control_style == 'wood') { - Reflect.get(ui, 'css').control_stylesheet = lib.init.sheet('#window .control,#window .menubutton,#window #system>div>div,#window #system>div>.pressdown2{background-image:' + str + '}'); - } - else { - Reflect.get(ui, 'css').control_stylesheet = lib.init.sheet('#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:' + str + '}'); - } - } - if (libConfig.menu_style && libConfig.menu_style != 'default' && libConfig.menu_style != 'custom') { - var str = ''; - switch (libConfig.menu_style) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood2.png")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px'; break; - } - Reflect.get(ui, 'css').menu_stylesheet = lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:' + str + '}'); - } -} - -async function loadConfig() { - Reflect.set(lib, 'config', Reflect.get(window, 'config')); - Reflect.set(lib, 'configOL', {}); - Reflect.deleteProperty(window, 'config'); - let result; - if (localStorage.getItem(`${lib.configprefix}nodb`)) - Reflect.set(window, 'nodb', true); - if (window.indexedDB && !Reflect.get(window, 'nodb')) { - const event = await new Promise((resolve, reject) => { - const idbOpenDBRequest = window.indexedDB.open(`${lib.configprefix}data`, 4); - idbOpenDBRequest.onerror = reject; - idbOpenDBRequest.onsuccess = resolve; - idbOpenDBRequest.onupgradeneeded = idbVersionChangeEvent => { - // @ts-expect-error MaybeHave - const idbDatabase = idbVersionChangeEvent.target.result; - if (!idbDatabase.objectStoreNames.contains('video')) idbDatabase.createObjectStore('video', { - keyPath: 'time' - }); - if (!idbDatabase.objectStoreNames.contains('image')) idbDatabase.createObjectStore('image'); - if (!idbDatabase.objectStoreNames.contains('audio')) idbDatabase.createObjectStore('audio'); - if (!idbDatabase.objectStoreNames.contains('config')) idbDatabase.createObjectStore('config'); - if (!idbDatabase.objectStoreNames.contains('data')) idbDatabase.createObjectStore('data'); - }; - }); - Reflect.set(lib, 'db', event.target.result); - - const object = await game.getDB('config'); - - if (!object.storageImported) { - try { - const item = localStorage.getItem(`${lib.configprefix}config`); - if (!item) throw 'err'; - result = JSON.parse(item); - if (!result || typeof result != 'object') throw 'err'; - } - catch (err) { - result = {}; - } - Object.keys(result).forEach(key => game.saveConfig(key, result[key])); - Object.keys(lib.mode).forEach(key => { - try { - const item = localStorage.getItem(`${lib.configprefix}${key}`); - if (!item) throw 'err'; - result = JSON.parse(item); - if (!result || typeof result != 'object' || get.is.empty(result)) throw 'err'; - } - catch (err) { - result = false; - } - localStorage.removeItem(`${lib.configprefix}${key}`); - if (result) game.putDB('data', key, result); - }); - game.saveConfig('storageImported', true); - lib.init.background(); - localStorage.removeItem(`${lib.configprefix}config`); - } - else result = object; - } else { - try { - const item = localStorage.getItem(lib.configprefix + 'config'); - if (!item) throw 'err'; - result = JSON.parse(item); - if (!result || typeof result != 'object') throw 'err'; - } - catch (err) { - result = {}; - localStorage.setItem(lib.configprefix + 'config', JSON.stringify({})); - } - } - - return result; -} - -async function loadCss() { - Reflect.set(ui, 'css', { - menu: await lib.init.promises.css(lib.assetURL + 'layout/default', 'menu'), - default: await lib.init.promises.css(lib.assetURL + 'layout/default', 'layout') - }); -} - -async function onWindowReady() { - if (Reflect.has(lib, 'device')) { - var script = document.createElement('script'); - script.src = 'cordova.js'; - document.body.appendChild(script); - await new Promise((resolve) => { - document.addEventListener('deviceready', async () => { - const { cordovaReady } = await import('./cordova.js'); - await cordovaReady(); - resolve(void 0) - }); - }) - } - /* - if (_status.packLoaded) { - delete _status.packLoaded; - lib.init.onload(); - } - else { - _status.windowLoaded = true; - } - */ -} - -function setBackground() { - let htmlbg = localStorage.getItem(lib.configprefix + 'background'); - if (htmlbg) { - if (htmlbg[0] == '[') { - try { - htmlbg = JSON.parse(htmlbg); - if (!htmlbg) throw new Error(); - htmlbg = htmlbg[get.rand(htmlbg.length)]; - if (htmlbg.startsWith('custom_')) { - throw ('err'); - } - _status.htmlbg = htmlbg; - } - catch (e) { - htmlbg = null; - } - } - if (htmlbg) { - document.documentElement.style.backgroundImage = 'url("' + lib.assetURL + 'image/background/' + htmlbg + '.jpg")'; - document.documentElement.style.backgroundSize = 'cover'; - document.documentElement.style.backgroundPosition = '50% 50%'; - } - } -} - -function setServerIndex() { - const index = window.location.href.indexOf('index.html?server='); - if (index !== -1) { - Reflect.set(window, 'isNonameServer', window.location.href.slice(index + 18)); - Reflect.set(window, 'nodb', true); - } else { - const savedIndex = localStorage.getItem(lib.configprefix + 'asserver'); - if (savedIndex) { - Reflect.set(window, 'isNonameServer', savedIndex); - Reflect.set(window, 'isNonameServerIp', lib.hallURL); - } - } -} - -function setWindowListener() { - /** - * @type { [Error, NodeJS.CallSite[]][] } - */ - const errorList = []; - // 这他娘的能捕获浏览器控制台里的输入值,尽量别用 - // 在火狐里无效 - Error.prepareStackTrace = function (e, stackTraces) { - errorList.push([e, stackTraces]); - }; - // 已经有用了 - window.addEventListener("unhandledrejection", promiseRejectionEvent => { - promiseRejectionEvent.promise.catch(e => { - const result = errorList.find(v => v[0] === e); - if (result) { - // @ts-ignore - window.onerror( - result[0].message, - result[1][0].getScriptNameOrSourceURL() || void 0, - result[1][0].getLineNumber() || void 0, - result[1][0].getColumnNumber() || void 0, - result[0] - ); - } - }); - }); - - window.onkeydown = function (e) { - if (!Reflect.has(ui, 'menuContainer') || !Reflect.get(ui, 'menuContainer').classList.contains('hidden')) { - if (e.keyCode == 116 || ((e.ctrlKey || e.metaKey) && e.keyCode == 82)) { - if (e.shiftKey) { - if (confirm('是否重置游戏?')) { - var noname_inited = localStorage.getItem('noname_inited'); - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); - localStorage.clear(); - if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); - } - if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); - } - if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + 'data'); - game.reload(); - return; - } - } - else { - game.reload(); - } - } - else if (e.keyCode == 83 && (e.ctrlKey || e.metaKey)) { - if (Reflect.has(window, 'saveNonameInput')) { - Reflect.get(window, 'saveNonameInput')(); - } - e.preventDefault(); - e.stopPropagation(); - return false; - } - else if (e.keyCode == 74 && (e.ctrlKey || e.metaKey) && Reflect.has(lib, 'node')) { - Reflect.get(lib, 'node').debug(); - } - } - else { - game.closePopped(); - var dialogs = document.querySelectorAll('#window>.dialog.popped:not(.static)'); - for (var i = 0; i < dialogs.length; i++) { - // @ts-ignore - dialogs[i].delete(); - } - if (e.keyCode == 32) { - var node = Reflect.get(ui, 'window').querySelector('pausedbg'); - if (node) { - node.click(); - } - else { - ui.click.pause(); - } - } - else if (e.keyCode == 65) { - if (Reflect.has(ui, 'auto')) - Reflect.get(ui, 'auto').click(); - } - else if (e.keyCode == 87) { - if (Reflect.has(ui, 'wuxie') && Reflect.get(ui, 'wuxie').style.display != 'none') { - Reflect.get(ui, 'wuxie').classList.toggle('glow'); - } - else if (Reflect.has(ui, 'tempnowuxie')) { - Reflect.get(ui, 'tempnowuxie').classList.toggle('glow'); - } - } - else if (e.keyCode == 116 || ((e.ctrlKey || e.metaKey) && e.keyCode == 82)) { - if (e.shiftKey) { - if (confirm('是否重置游戏?')) { - var noname_inited = localStorage.getItem('noname_inited'); - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); - localStorage.clear(); - if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); - } - if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); - } - if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + 'data'); - game.reload(); - return; - } - } - else { - game.reload(); - } - } - else if (e.keyCode == 83 && (e.ctrlKey || e.metaKey)) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - else if (e.keyCode == 74 && (e.ctrlKey || e.metaKey) && Reflect.has(lib, 'node')) { - Reflect.get(lib, 'node').debug(); - } - // else if(e.keyCode==27){ - // if(!ui.arena.classList.contains('paused')) ui.click.config(); - // } - } - }; - - window.onerror = function (msg, src, line, column, err) { - errorList.length = 0; - const winPath = window.__dirname ? ('file:///' + (__dirname.replace(new RegExp('\\\\', 'g'), '/') + '/')) : ''; - let str = `错误文件: ${typeof src == 'string' ? decodeURI(src).replace(lib.assetURL, '').replace(winPath, '') : '未知文件'}`; - str += `\n错误信息: ${msg}`; - const tip = lib.getErrorTip(msg); - if (tip) str += `\n错误提示: ${tip}`; - str += `\n行号: ${line}`; - str += `\n列号: ${column}`; - const version = Reflect.has(lib, 'version') ? Reflect.get(lib, 'version') : ''; - const reg = /[^\d.]/; - const match = version.match(reg) != null; - str += '\n' + `${match ? '游戏' : '无名杀'}版本: ${version || '未知版本'}`; - if (match) str += '\n⚠️您使用的游戏代码不是源于libccy/noname无名杀官方仓库,请自行寻找您所使用的游戏版本开发者反馈!'; - if (_status && _status.event) { - let evt = _status.event; - str += `\nevent.name: ${evt.name}\nevent.step: ${evt.step}`; - // @ts-ignore - if (evt.parent) str += `\nevent.parent.name: ${evt.parent.name}\nevent.parent.step: ${evt.parent.step}`; - // @ts-ignore - if (evt.parent && evt.parent.parent) str += `\nevent.parent.parent.name: ${evt.parent.parent.name}\nevent.parent.parent.step: ${evt.parent.parent.step}`; - if (evt.player || evt.target || evt.source || evt.skill || evt.card) { - str += '\n-------------'; - } - if (evt.player) { - if (lib.translate[evt.player.name]) str += `\nplayer: ${lib.translate[evt.player.name]}[${evt.player.name}]`; - else str += '\nplayer: ' + evt.player.name; - let distance = get.distance(_status.roundStart, evt.player, 'absolute'); - if (distance != Infinity) { - str += `\n座位号: ${distance + 1}`; - } - } - if (evt.target) { - if (lib.translate[evt.target.name]) str += `\ntarget: ${lib.translate[evt.target.name]}[${evt.target.name}]`; - else str += '\ntarget: ' + evt.target.name; - } - if (evt.source) { - if (lib.translate[evt.source.name]) str += `\nsource: ${lib.translate[evt.source.name]}[${evt.source.name}]`; - else str += '\nsource: ' + evt.source.name; - } - if (evt.skill) { - if (lib.translate[evt.skill]) str += `\nskill: ${lib.translate[evt.skill]}[${evt.skill}]`; - else str += '\nskill: ' + evt.skill; - } - if (evt.card) { - if (lib.translate[evt.card.name]) str += `\ncard: ${lib.translate[evt.card.name]}[${evt.card.name}]`; - else str += '\ncard: ' + evt.card.name; - } - } - str += '\n-------------'; - if (typeof line == 'number' && (typeof Reflect.get(game, 'readFile') == 'function' || location.origin != 'file://')) { - const createShowCode = function (lines) { - let showCode = ''; - if (lines.length >= 10) { - if (line > 4) { - for (let i = line - 5; i < line + 6 && i < lines.length; i++) { - showCode += `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${lines[i]}\n`; - } - } else { - for (let i = 0; i < line + 6 && i < lines.length; i++) { - showCode += `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${lines[i]}\n`; - } - } - } else { - showCode = lines.map((_line, i) => `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${_line}\n`).toString(); - } - return showCode; - }; - //协议名须和html一致(网页端防跨域),且文件是js - if (typeof src == 'string' && src.startsWith(location.protocol) && src.endsWith('.js')) { - //获取代码 - const codes = lib.init.reqSync('local:' + decodeURI(src).replace(lib.assetURL, '').replace(winPath, '')); - if (codes) { - const lines = codes.split("\n"); - str += '\n' + createShowCode(lines); - str += '\n-------------'; - } - } - //解析parsex里的content fun内容(通常是技能content) - else if (err && err.stack && err.stack.split('\n')[1].trim().startsWith('at Object.eval [as content]')) { - const codes = _status.event.content; - if (typeof codes == 'function') { - const lines = codes.toString().split("\n"); - str += '\n' + createShowCode(lines); - str += '\n-------------'; - } - } - } - if (err && err.stack) str += '\n' + decodeURI(err.stack).replace(new RegExp(lib.assetURL, 'g'), '').replace(new RegExp(winPath, 'g'), ''); - alert(str); - Reflect.set(window, 'ea', Array.from(arguments)); - Reflect.set(window, 'em', msg); - Reflect.set(window, 'el', line); - Reflect.set(window, 'ec', column); - Reflect.set(window, 'eo', err); - game.print(str); - // @ts-ignore - if (!lib.config.errstop) { - _status.withError = true; - game.loop(); - } - }; -} + +import { AI as ai } from '../ai/index.js'; +import { Get as get } from '../get/index.js'; +import { Library as lib } from '../library/index.js'; +import { Game as game } from '../game/index.js'; +import { status as _status } from '../status/index.js'; +import { UI as ui } from '../ui/index.js'; + +import { userAgent } from '../util/index.js'; +import * as config from '../util/config.js'; +import { promiseErrorHandlerMap } from '../util/browser.js'; +import { gnc } from '../gnc/index.js'; + +import { importCardPack, importCharacterPack, importExtension, importMode } from './import.js'; +import { onload } from './onload.js'; + +// 无名杀,启动! +export async function boot() { + // 不想看,反正别动 + if (typeof __dirname === 'string' && __dirname.length) { + const dirsplit = __dirname.split('/'); + for (let i = 0; i < dirsplit.length; i++) { + if (dirsplit[i]) { + var c = dirsplit[i][0]; + lib.configprefix += /[A-Z]|[a-z]/.test(c) ? c : '_'; + } + } + lib.configprefix += '_'; + } + + // 加载polyfill内容 + await import('./polyfill.js'); + + // 设定游戏加载时间,超过时间未加载就提醒 + const configLoadTime = localStorage.getItem(lib.configprefix + 'loadtime'); + // 现在不暴露到全局变量里了,直接传给onload + const resetGameTimeout = setTimeout(lib.init.reset, configLoadTime ? parseInt(configLoadTime) : 10000); + + if (Reflect.has(window, 'cordovaLoadTimeout')) { + clearTimeout(Reflect.get(window, 'cordovaLoadTimeout')); + Reflect.deleteProperty(window, 'cordovaLoadTimeout'); + } + + for (const link of document.head.querySelectorAll('link')) { + if (link.href.includes('app/color.css')) { + link.remove(); + break; + } + } + + setServerIndex(); + setBackground(); + + Reflect.set(lib, 'get', get); + Reflect.set(lib, 'ui', ui); + Reflect.set(lib, 'ai', ai); + Reflect.set(lib, 'game', game); + _status.event = lib.element.GameEvent.initialGameEvent(); + + setWindowListener(); + await setOnError(); + + // 无名杀更新日志 + if (window.noname_update) { + Reflect.set(lib, 'version', window.noname_update.version); + lib.changeLog = window.noname_update.changeLog; + if (window.noname_update.players) { + lib.changeLog.push('players://' + JSON.stringify(window.noname_update.players)); + } + if (window.noname_update.cards) { + lib.changeLog.push('cards://' + JSON.stringify(window.noname_update.cards)); + } + delete window.noname_update; + } + // 确认手机端平台 + const noname_inited = localStorage.getItem('noname_inited'); + if (noname_inited && noname_inited !== 'nodejs') { + const ua = userAgent; + if (ua.includes('android')) { + Reflect.set(lib, 'device', 'android'); + } + else if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('macintosh')) { + Reflect.set(lib, 'device', 'ios'); + } + } + + // 在dom加载完后执行相应的操作 + const waitDomLoad = new Promise((resolve) => { + if (document.readyState !== 'complete') { + window.onload = resolve; + } else resolve(void 0); + }).then(onWindowReady.bind(window)); + + + // 闭源客户端检测并提醒 + if (lib.assetURL.includes('com.widget.noname.qingyao') || lib.assetURL.includes('online.nonamekill.android')) { + alert('您正在一个不受信任的闭源客户端上运行《无名杀》。建议您更换为其他开源的无名杀客户端,避免给您带来不必要的损失。'); + } + + // Electron平台 + if (typeof window.require === 'function') { + const { nodeReady } = await import('./node.js'); + nodeReady(); + } + // 手机平台已在别处判断 + else if (!Reflect.has(lib, 'device')) { + Reflect.set(lib, 'path', (await import('../library/path.js')).default); + //为其他自定义平台提供文件读写函数赋值的一种方式。 + //但这种方式只能修改game的文件读写函数。 + if (typeof window.initReadWriteFunction == 'function') { + const g = {}; + const ReadWriteFunctionName = ['download', 'readFile', 'readFileAsText', 'writeFile', 'removeFile', 'getFileList', 'ensureDirectory', 'createDir']; + ReadWriteFunctionName.forEach(prop => { + Object.defineProperty(g, prop, { + configurable: true, + get() { return undefined; }, + set(newValue) { + if (typeof newValue == 'function') { + delete g[prop]; + g[prop] = game[prop] = newValue; + } + } + }); + }); + // @ts-ignore + window.initReadWriteFunction(g); + } + window.onbeforeunload = function () { + if (config.get('confirm_exit') && !_status.reloading) { + return '是否离开游戏?'; + } + else { + return null; + } + }; + } + + const loadCssPromise = loadCss(); + const loadConfigPromise = loadConfig(); + await loadCssPromise; + const config2 = await loadConfigPromise; + + // 读取模式 + if (config2.mode) config.set('mode', config2.mode); + if (config.get('mode_config')[config.get('mode')] === undefined) + config.get('mode_config')[config.get('mode')] = {}; + + // 复制共有模式设置 + for (const name in config.get('mode_config').global) { + if (config.get('mode_config')[config.get('mode')][name] === undefined) { + config.get('mode_config')[config.get('mode')][name] = config.get('mode_config').global[name]; + } + } + + if (config.get('characters')) + config.set('defaultcharacters', config.get('characters').slice(0)); + if (config.get('cards')) + config.set('defaultcards', config.get('cards').slice(0)); + + for (const name in config2) { + if (name.includes('_mode_config')) { + var thismode = name.substr(name.indexOf('_mode_config') + 13); + if (!config.get('mode_config')[thismode]) + config.get('mode_config')[thismode] = {}; + config.get('mode_config')[thismode][name.substr(0, name.indexOf('_mode_config'))] = config2[name]; + } + else { + config.set(name, config2[name]); + } + } + + for (const name in get.config('translate')) { + lib.translate[name] = get.config('translate')[name]; + } + + config.get('all').characters = []; + config.get('all').cards = []; + config.get('all').plays = []; + config.get('all').mode = []; + + if (config.get('debug')) { + await lib.init.promises.js(`${lib.assetURL}game`, 'asset'); + if (window.noname_skin_list) { + lib.skin = window.noname_skin_list; + delete window.noname_skin_list; + delete window.noname_asset_list; + } + } + + if (Reflect.get(window, 'isNonameServer')) + config.set('mode', 'connect'); + + var pack = Reflect.get(window, 'noname_package'); + Reflect.deleteProperty(window, 'noname_package'); + for (const name in pack.character) { + if (config.get('all').sgscharacters.includes(name) || config.get('hiddenCharacterPack').indexOf(name) == -1) { + config.get('all').characters.push(name); + lib.translate[name + '_character_config'] = pack.character[name]; + } + } + for (const name in pack.card) { + if (config.get('all').sgscards.includes(name) || config.get('hiddenCardPack').indexOf(name) == -1) { + config.get('all').cards.push(name); + lib.translate[name + '_card_config'] = pack.card[name]; + } + } + for (const name in pack.play) { + config.get('all').plays.push(name); + lib.translate[name + '_play_config'] = pack.play[name]; + } + for (const name in pack.submode) { + for (var j in pack.submode[name]) { + lib.translate[name + '|' + j] = pack.submode[name][j]; + } + } + + if (!config.get('gameRecord')) + config.set('gameRecord', {}); + for (const name in pack.mode) { + if (config.get('hiddenModePack').indexOf(name) == -1) { + config.get('all').mode.push(name); + lib.translate[name] = pack.mode[name]; + if (!config.get('gameRecord')[name]) + config.get('gameRecord')[name] = { data: {} }; + } + } + if (config.get('all').mode.length == 0) { + config.get('all').mode.push('identity'); + lib.translate.identity = '身份'; + if (!config.get('gameRecord').identity) + config.get('gameRecord').identity = { data: {} }; + } + if (pack.background) { + for (const name in pack.background) { + if (config.get('hiddenBackgroundPack').includes(name)) continue; + lib.configMenu.appearence.config.image_background.item[name] = pack.background[name]; + } + for (let i = 0; i < config.get('customBackgroundPack').length; i++) { + var link = config.get('customBackgroundPack')[i]; + lib.configMenu.appearence.config.image_background.item[link] = link.slice(link.indexOf('_') + 1); + } + lib.configMenu.appearence.config.image_background.item.default = '默认'; + } + if (pack.music) { + if (Reflect.has(lib, 'device') || typeof window.require === 'function') { + lib.configMenu.audio.config.background_music.item.music_custom = '自定义音乐'; + } + config.get('all').background_music = ['music_default']; + for (const name in pack.music) { + config.get('all').background_music.push(name); + lib.configMenu.audio.config.background_music.item[name] = pack.music[name]; + } + if (config.get('customBackgroundMusic')) { + for (const name in config.get('customBackgroundMusic')) { + config.get('all').background_music.push(name); + lib.configMenu.audio.config.background_music.item[name] = config.get('customBackgroundMusic')[name]; + } + } + lib.configMenu.audio.config.background_music.item.music_random = '随机播放'; + lib.configMenu.audio.config.background_music.item.music_off = '关闭'; + } + if (pack.theme) { + for (const name in pack.theme) { + lib.configMenu.appearence.config.theme.item[name] = pack.theme[name]; + } + } + if (config.get('extension_sources')) { + for (const name in config.get('extension_sources')) { + lib.configMenu.general.config.extension_source.item[name] = name; + } + } + + if (pack.font) { + Reflect.get(ui, 'css').fontsheet = lib.init.sheet(); + const appearenceConfig = lib.configMenu.appearence.config, fontSheet = Reflect.get(ui, 'css').fontsheet.sheet, suitsFont = config.get('suits_font'); + Object.keys(pack.font).forEach((value) => { + const font = pack.font[value]; + appearenceConfig.name_font.item[value] = font; + appearenceConfig.identity_font.item[value] = font; + appearenceConfig.cardtext_font.item[value] = font; + appearenceConfig.global_font.item[value] = font; + fontSheet.insertRule(`@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/${value}.woff2');}`, 0); + if (suitsFont) fontSheet.insertRule(`@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/suits.woff2');}`, 0); + }); + if (suitsFont) fontSheet.insertRule(`@font-face {font-family: 'Suits'; src: url('${lib.assetURL}font/suits.woff2');}`, 0); + fontSheet.insertRule(`@font-face {font-family: 'NonameSuits'; src: url('${lib.assetURL}font/suits.woff2');}`, 0); + fontSheet.insertRule(`@font-face {font-family: 'MotoyaLMaru'; src: url('${lib.assetURL}font/motoyamaru.woff2');}`, 0); + appearenceConfig.cardtext_font.item.default = '默认'; + appearenceConfig.global_font.item.default = '默认'; + } + + const ua = userAgent; + if ('ontouchstart' in document) { + if (!config.get('totouched')) { + game.saveConfig('totouched', true); + if (Reflect.has(lib, 'device')) { + game.saveConfig('low_performance', true); + game.saveConfig('confirm_exit', true); + game.saveConfig('touchscreen', true); + game.saveConfig('fold_mode', false); + if (ua.indexOf('ipad') == -1) { + game.saveConfig('phonelayout', true); + } + else if (Reflect.get(lib, 'device') === 'ios') { + game.saveConfig('show_statusbar_ios', 'overlay'); + } + } + else if (confirm('是否切换到触屏模式?(触屏模式可提高触屏设备的响应速度,但无法使用鼠标)')) { + game.saveConfig('touchscreen', true); + if (ua.includes('iphone') || ua.includes('android')) { + game.saveConfig('phonelayout', true); + } + game.reload(); + } + } + } + else if (config.get('touchscreen')) { + game.saveConfig('touchscreen', false); + } + if (!config.get('toscrolled') && ua.includes('macintosh')) { + game.saveConfig('toscrolled', true); + game.saveConfig('mousewheel', false); + } + + let show_splash = config.get('show_splash'); + if (show_splash == 'off') { + show_splash = false; + } + else if (show_splash == 'init') { + if (localStorage.getItem('show_splash_off')) { + show_splash = false; + } + } + localStorage.removeItem('show_splash_off'); + const extensionlist = []; + if (!localStorage.getItem(lib.configprefix + 'disable_extension')) { + if (config.has('extensions') && config.get('extensions').length) { + Reflect.set(window, 'resetExtension', () => { + for (var i = 0; i < config.get('extensions').length; i++) { + game.saveConfig('extension_' + config.get('extensions')[i] + '_enable', false); + } + // @ts-ignore + localStorage.setItem(lib.configprefix + 'disable_extension', true); + }); + } + for (var name = 0; name < config.get('plays').length; name++) { + if (config.get('all').plays.includes(config.get('plays')[name])) { + extensionlist.push(config.get('plays')[name]); + } + } + var alerted = false; + for (var name = 0; name < config.get('extensions').length; name++) { + if (Reflect.get(window, 'bannedExtensions').includes(config.get('extensions')[name])) { + //if(!alerted) alert('读取某些扩展时出现问题。'); + alerted = true; + continue; + } + var extcontent = localStorage.getItem(lib.configprefix + 'extension_' + config.get('extensions')[name]); + if (extcontent) { + //var backup_onload=lib.init.onload; + _status.evaluatingExtension = true; + try { + eval(extcontent); + } + catch (e) { + console.log(e); + } + //lib.init.onload=backup_onload; + _status.evaluatingExtension = false; + } + else if (config.get('mode') != 'connect' || (!localStorage.getItem(lib.configprefix + 'directstart') && show_splash)) { + extensionlist.push(config.get('extensions')[name]); + } + } + } + else { + if (config.get('mode') != 'connect' || (!localStorage.getItem(lib.configprefix + 'directstart') && show_splash)) { + var alerted = false; + for (var name = 0; name < config.get('extensions').length; name++) { + if (Reflect.get(window, 'bannedExtensions').includes(config.get('extensions')[name])) { + //if(!alerted) alert('读取某些扩展时出现问题。'); + alerted = true; + continue; + } + // @ts-ignore + game.import('extension', { name: config.get('extensions')[name] }); + } + } + } + + let layout = config.get('layout'); + if (layout == 'default' || lib.layoutfixed.indexOf(config.get('mode')) !== -1) { + layout = 'mobile'; + } + if (layout == 'phone') { + layout = 'mobile'; + game.saveConfig('layout', 'mobile'); + game.saveConfig('phonelayout', true); + } + Reflect.set(game, 'layout', layout); + + if (config.get('image_background_random')) { + if (_status.htmlbg) { + game.saveConfig('image_background', _status.htmlbg); + } + else { + const list = []; + for (const name in lib.configMenu.appearence.config.image_background.item) { + if (name == 'default') continue; + list.push(name); + } + // @ts-ignore + game.saveConfig('image_background', list.randomGet(lib.config.image_background)); + } + lib.init.background(); + } + delete _status.htmlbg; + + // 虽然但是,我就暴露个import,应该没啥问题 + Reflect.set(window, 'game', { + import: game.import.bind(null) + }); + + if (config.get('layout') == 'default') { + config.set('layout', 'mobile'); + } + + const stylesName = ['layout', 'theme', 'card_style', 'cardback_style', 'hp_style']; + const stylesLoading = [ + lib.init.promises.css(lib.assetURL + 'layout/' + layout, 'layout', void 0, true), + lib.init.promises.css(lib.assetURL + 'theme/' + config.get('theme'), 'style', void 0, true), + lib.init.promises.css(lib.assetURL + 'theme/style/card', config.get('card_style'), void 0, true), + lib.init.promises.css(lib.assetURL + 'theme/style/cardback', config.get('cardback_style'), void 0, true), + lib.init.promises.css(lib.assetURL + 'theme/style/hp', config.get('hp_style'), void 0, true) + ]; + + if (get.is.phoneLayout()) { + stylesName.push('phone'); + stylesLoading.push(lib.init.promises.css(lib.assetURL + 'layout/default', 'phone')); + } + else { + Reflect.get(ui, 'css').phone = lib.init.css(); + } + + initSheet(Reflect.get(lib, 'config')); + + config.set('duration', 500); + + if (!config.get('touchscreen')) { + document.addEventListener('mousewheel', ui.click.windowmousewheel, { passive: true }); + document.addEventListener('mousemove', ui.click.windowmousemove); + document.addEventListener('mousedown', ui.click.windowmousedown); + document.addEventListener('mouseup', ui.click.windowmouseup); + document.addEventListener('contextmenu', ui.click.right); + } + else { + document.addEventListener('touchstart', ui.click.touchconfirm); + document.addEventListener('touchstart', ui.click.windowtouchstart); + document.addEventListener('touchend', ui.click.windowtouchend); + document.addEventListener('touchmove', ui.click.windowtouchmove); + } + + const stylesLoaded = await Promise.all(stylesLoading); + const stylesLength = Math.min(stylesName.length, stylesLoaded.length); + for (let i = 0; i < stylesLength; ++i) { + Reflect.get(ui, 'css')[stylesName[i]] = stylesLoaded[i]; + } + + if (extensionlist.length && (config.get('mode') != 'connect' || show_splash)) { + _status.extensionLoading = []; + + const bannedExtensions = Reflect.get(window, 'bannedExtensions'); + + const extensionsLoading = []; + for (const name of extensionlist) { + if (bannedExtensions.includes(name)) continue; + extensionsLoading.push(importExtension(name)); + } + + await Promise.allSettled(extensionsLoading); + await Promise.allSettled(_status.extensionLoading); + _status.extensionLoaded.filter(Boolean).forEach((name) => { + lib.announce.publish("Noname.Init.Extension.onLoad", name); + lib.announce.publish(`Noname.Init.Extension.${name}.onLoad`, void 0); + }); + delete _status.extensionLoading; + } + + const isArray = Array.isArray; + if (isArray(lib.onprepare) && lib.onprepare.length) { + _status.onprepare = Object.freeze(lib.onprepare.map((fn) => { + if (typeof fn !== "function") return; + return (gnc.is.generatorFunc(fn) ? gnc.of(fn) : fn)(); + })); + } + + const toLoad = []; + + if (localStorage.getItem(`${lib.configprefix}playback`)) + toLoad.push(importMode(config.get('mode'))); + else if ((localStorage.getItem(`${lib.configprefix}directstart`) || !show_splash) && config.get('all').mode.includes(config.get('mode'))) + toLoad.push(importMode(config.get('mode'))); + + for (const cardPack of config.get('all').cards) { + toLoad.push(importCardPack(cardPack)); + } + for (const characterPack of config.get('all').characters) { + toLoad.push(importCharacterPack(characterPack)); + } + toLoad.push(lib.init.promises.js(`${lib.assetURL}character`, 'rank')); + + if (_status.javaScriptExtensions) { + const loadJavaScriptExtension = async (javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray, index) => { + if (!pathArray && !fileArray && !onLoadArray && !onErrorArray) { + try { + await lib.init.promises.js(javaScriptExtension.path, javaScriptExtension.file); + if (typeof javaScriptExtension.onload == 'function') javaScriptExtension.onload(); + } catch { + if (typeof javaScriptExtension.onerror == 'function') javaScriptExtension.onerror(); + } + return; + } + if (typeof index != 'number') index = 0; + if (pathArray && index >= javaScriptExtension.path.length) return; + if (fileArray && index >= javaScriptExtension.file.length) return; + if (onLoadArray && index >= javaScriptExtension.onload.length) return; + if (onErrorArray && index >= javaScriptExtension.onerror.length) return; + const path = pathArray ? javaScriptExtension.path[index] : javaScriptExtension.path; + const file = fileArray ? javaScriptExtension.file[index] : javaScriptExtension.file; + const onLoad = onLoadArray ? javaScriptExtension.onload[index] : javaScriptExtension.onload; + const onError = onErrorArray ? javaScriptExtension.onerror[index] : javaScriptExtension.onerror; + try { + await lib.init.promises.js(path, file); + if (typeof onLoad == 'function') onLoad(); + } catch { + if (typeof onError == 'function') onError(); + } + await loadJavaScriptExtension(javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray, index + 1); + }; + _status.javaScriptExtensions.forEach((javaScriptExtension) => { + const pathArray = isArray(javaScriptExtension.path); + const fileArray = isArray(javaScriptExtension.file); + const onLoadArray = isArray(javaScriptExtension.onLoad); + const onErrorArray = isArray(javaScriptExtension.onError); + toLoad.push(loadJavaScriptExtension(javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray)); + }); + } + + await Promise.allSettled(toLoad); + + if (_status.importing) { + /** + * @type {Promise[]} + */ + let promises = lib.creation.array; + for (const type in _status.importing) { + // @ts-ignore + promises.addArray(_status.importing[type]); + } + await Promise.allSettled(promises); + delete _status.importing; + } + + await waitDomLoad; + await onload(resetGameTimeout); +} + +function initSheet(libConfig) { + if (libConfig.player_style && libConfig.player_style != 'default' && libConfig.player_style != 'custom') { + var str = ''; + switch (libConfig.player_style) { + case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; break; + case 'music': str = 'linear-gradient(#4b4b4b, #464646)'; break; + case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; break; + } + Reflect.get(ui, 'css').player_stylesheet = lib.init.sheet('#window .player{background-image:' + str + '}'); + } + if (libConfig.border_style && libConfig.border_style != 'default' && libConfig.border_style != 'custom' && libConfig.border_style != 'auto') { + Reflect.get(ui, 'css').border_stylesheet = lib.init.sheet(); + var bstyle = libConfig.border_style; + if (bstyle.startsWith('dragon_')) { + bstyle = bstyle.slice(7); + } + Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('#window .player>.framebg,#window #arena.long.mobile:not(.fewplayer) .player[data-position="0"]>.framebg{display:block;background-image:url("' + lib.assetURL + 'theme/style/player/' + bstyle + '1.png")}', 0); + Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('#window #arena.long:not(.fewplayer) .player>.framebg, #arena.oldlayout .player>.framebg{background-image:url("' + lib.assetURL + 'theme/style/player/' + bstyle + '3.png")}', 0); + Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}', 0); + } + if (libConfig.control_style && libConfig.control_style != 'default' && libConfig.control_style != 'custom') { + var str = ''; + switch (libConfig.control_style) { + case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; break; + case 'music': str = 'linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px'; break; + case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px'; break; + } + if (libConfig.control_style == 'wood') { + Reflect.get(ui, 'css').control_stylesheet = lib.init.sheet('#window .control,#window .menubutton,#window #system>div>div,#window #system>div>.pressdown2{background-image:' + str + '}'); + } + else { + Reflect.get(ui, 'css').control_stylesheet = lib.init.sheet('#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:' + str + '}'); + } + } + if (libConfig.menu_style && libConfig.menu_style != 'default' && libConfig.menu_style != 'custom') { + var str = ''; + switch (libConfig.menu_style) { + case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood2.png")'; break; + case 'music': str = 'linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px'; break; + case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px'; break; + } + Reflect.get(ui, 'css').menu_stylesheet = lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:' + str + '}'); + } +} + +async function loadConfig() { + Reflect.set(lib, 'config', Reflect.get(window, 'config')); + Reflect.set(lib, 'configOL', {}); + Reflect.deleteProperty(window, 'config'); + let result; + if (localStorage.getItem(`${lib.configprefix}nodb`)) + Reflect.set(window, 'nodb', true); + if (window.indexedDB && !Reflect.get(window, 'nodb')) { + const event = await new Promise((resolve, reject) => { + const idbOpenDBRequest = window.indexedDB.open(`${lib.configprefix}data`, 4); + idbOpenDBRequest.onerror = reject; + idbOpenDBRequest.onsuccess = resolve; + idbOpenDBRequest.onupgradeneeded = idbVersionChangeEvent => { + // @ts-expect-error MaybeHave + const idbDatabase = idbVersionChangeEvent.target.result; + if (!idbDatabase.objectStoreNames.contains('video')) idbDatabase.createObjectStore('video', { + keyPath: 'time' + }); + if (!idbDatabase.objectStoreNames.contains('image')) idbDatabase.createObjectStore('image'); + if (!idbDatabase.objectStoreNames.contains('audio')) idbDatabase.createObjectStore('audio'); + if (!idbDatabase.objectStoreNames.contains('config')) idbDatabase.createObjectStore('config'); + if (!idbDatabase.objectStoreNames.contains('data')) idbDatabase.createObjectStore('data'); + }; + }); + Reflect.set(lib, 'db', event.target.result); + + const object = await game.getDB('config'); + + if (!object.storageImported) { + try { + const item = localStorage.getItem(`${lib.configprefix}config`); + if (!item) throw 'err'; + result = JSON.parse(item); + if (!result || typeof result != 'object') throw 'err'; + } + catch (err) { + result = {}; + } + Object.keys(result).forEach(key => game.saveConfig(key, result[key])); + Object.keys(lib.mode).forEach(key => { + try { + const item = localStorage.getItem(`${lib.configprefix}${key}`); + if (!item) throw 'err'; + result = JSON.parse(item); + if (!result || typeof result != 'object' || get.is.empty(result)) throw 'err'; + } + catch (err) { + result = false; + } + localStorage.removeItem(`${lib.configprefix}${key}`); + if (result) game.putDB('data', key, result); + }); + game.saveConfig('storageImported', true); + lib.init.background(); + localStorage.removeItem(`${lib.configprefix}config`); + } + else result = object; + } else { + try { + const item = localStorage.getItem(lib.configprefix + 'config'); + if (!item) throw 'err'; + result = JSON.parse(item); + if (!result || typeof result != 'object') throw 'err'; + } + catch (err) { + result = {}; + localStorage.setItem(lib.configprefix + 'config', JSON.stringify({})); + } + } + + return result; +} + +async function loadCss() { + Reflect.set(ui, 'css', { + menu: await lib.init.promises.css(lib.assetURL + 'layout/default', 'menu'), + default: await lib.init.promises.css(lib.assetURL + 'layout/default', 'layout') + }); +} + +async function onWindowReady() { + if (Reflect.has(lib, 'device')) { + var script = document.createElement('script'); + script.src = 'cordova.js'; + document.body.appendChild(script); + await new Promise((resolve) => { + document.addEventListener('deviceready', async () => { + const { cordovaReady } = await import('./cordova.js'); + await cordovaReady(); + resolve(void 0); + }); + }); + } + /* + if (_status.packLoaded) { + delete _status.packLoaded; + lib.init.onload(); + } + else { + _status.windowLoaded = true; + } + */ +} + +function setBackground() { + let htmlbg = localStorage.getItem(lib.configprefix + 'background'); + if (htmlbg) { + if (htmlbg[0] == '[') { + try { + htmlbg = JSON.parse(htmlbg); + if (!htmlbg) throw new Error(); + htmlbg = htmlbg[get.rand(htmlbg.length)]; + if (htmlbg.startsWith('custom_')) { + throw ('err'); + } + _status.htmlbg = htmlbg; + } + catch (e) { + htmlbg = null; + } + } + if (htmlbg) { + document.documentElement.style.backgroundImage = 'url("' + lib.assetURL + 'image/background/' + htmlbg + '.jpg")'; + document.documentElement.style.backgroundSize = 'cover'; + document.documentElement.style.backgroundPosition = '50% 50%'; + } + } +} + +function setServerIndex() { + const index = window.location.href.indexOf('index.html?server='); + if (index !== -1) { + Reflect.set(window, 'isNonameServer', window.location.href.slice(index + 18)); + Reflect.set(window, 'nodb', true); + } else { + const savedIndex = localStorage.getItem(lib.configprefix + 'asserver'); + if (savedIndex) { + Reflect.set(window, 'isNonameServer', savedIndex); + Reflect.set(window, 'isNonameServerIp', lib.hallURL); + } + } +} + +async function setOnError() { + const [core] = get.coreInfo(); + + const promiseErrorHandler = new ((core in promiseErrorHandlerMap) ? promiseErrorHandlerMap[core] : promiseErrorHandlerMap.other); + + if (promiseErrorHandler.onLoad) await promiseErrorHandler.onLoad(); + + window.addEventListener("unhandledrejection", async (event) => { + if (promiseErrorHandler.onHandle) await promiseErrorHandler.onHandle(event); + }); + + window.onerror = function (msg, src, line, column, err) { + if (promiseErrorHandler.onErrorPrepare) promiseErrorHandler.onErrorPrepare(); + const winPath = window.__dirname ? ('file:///' + (__dirname.replace(new RegExp('\\\\', 'g'), '/') + '/')) : ''; + let str = `错误文件: ${typeof src == 'string' ? decodeURI(src).replace(lib.assetURL, '').replace(winPath, '') : '未知文件'}`; + str += `\n错误信息: ${msg}`; + const tip = lib.getErrorTip(msg); + if (tip) str += `\n错误提示: ${tip}`; + str += `\n行号: ${line}`; + str += `\n列号: ${column}`; + const version = Reflect.has(lib, 'version') ? Reflect.get(lib, 'version') : ''; + const reg = /[^\d.]/; + const match = version.match(reg) != null; + str += '\n' + `${match ? '游戏' : '无名杀'}版本: ${version || '未知版本'}`; + if (match) str += '\n⚠️您使用的游戏代码不是源于libccy/noname无名杀官方仓库,请自行寻找您所使用的游戏版本开发者反馈!'; + if (_status && _status.event) { + let evt = _status.event; + str += `\nevent.name: ${evt.name}\nevent.step: ${evt.step}`; + // @ts-ignore + if (evt.parent) str += `\nevent.parent.name: ${evt.parent.name}\nevent.parent.step: ${evt.parent.step}`; + // @ts-ignore + if (evt.parent && evt.parent.parent) str += `\nevent.parent.parent.name: ${evt.parent.parent.name}\nevent.parent.parent.step: ${evt.parent.parent.step}`; + if (evt.player || evt.target || evt.source || evt.skill || evt.card) { + str += '\n-------------'; + } + if (evt.player) { + if (lib.translate[evt.player.name]) str += `\nplayer: ${lib.translate[evt.player.name]}[${evt.player.name}]`; + else str += '\nplayer: ' + evt.player.name; + let distance = get.distance(_status.roundStart, evt.player, 'absolute'); + if (distance != Infinity) { + str += `\n座位号: ${distance + 1}`; + } + } + if (evt.target) { + if (lib.translate[evt.target.name]) str += `\ntarget: ${lib.translate[evt.target.name]}[${evt.target.name}]`; + else str += '\ntarget: ' + evt.target.name; + } + if (evt.source) { + if (lib.translate[evt.source.name]) str += `\nsource: ${lib.translate[evt.source.name]}[${evt.source.name}]`; + else str += '\nsource: ' + evt.source.name; + } + if (evt.skill) { + if (lib.translate[evt.skill]) str += `\nskill: ${lib.translate[evt.skill]}[${evt.skill}]`; + else str += '\nskill: ' + evt.skill; + } + if (evt.card) { + if (lib.translate[evt.card.name]) str += `\ncard: ${lib.translate[evt.card.name]}[${evt.card.name}]`; + else str += '\ncard: ' + evt.card.name; + } + } + str += '\n-------------'; + if (typeof line == 'number' && (typeof Reflect.get(game, 'readFile') == 'function' || location.origin != 'file://')) { + const createShowCode = function (lines) { + let showCode = ''; + if (lines.length >= 10) { + if (line > 4) { + for (let i = line - 5; i < line + 6 && i < lines.length; i++) { + showCode += `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${lines[i]}\n`; + } + } else { + for (let i = 0; i < line + 6 && i < lines.length; i++) { + showCode += `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${lines[i]}\n`; + } + } + } else { + showCode = lines.map((_line, i) => `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${_line}\n`).toString(); + } + return showCode; + }; + //协议名须和html一致(网页端防跨域),且文件是js + if (typeof src == 'string' && src.startsWith(location.protocol) && src.endsWith('.js')) { + //获取代码 + const codes = lib.init.reqSync('local:' + decodeURI(src).replace(lib.assetURL, '').replace(winPath, '')); + if (codes) { + const lines = codes.split("\n"); + str += '\n' + createShowCode(lines); + str += '\n-------------'; + } + } + //解析parsex里的content fun内容(通常是技能content) + else if (err && err.stack && err.stack.split('\n')[1].trim().startsWith('at Object.eval [as content]')) { + const codes = _status.event.content; + if (typeof codes == 'function') { + const lines = codes.toString().split("\n"); + str += '\n' + createShowCode(lines); + str += '\n-------------'; + } + } + } + if (err && err.stack) str += '\n' + decodeURI(err.stack).replace(new RegExp(lib.assetURL, 'g'), '').replace(new RegExp(winPath, 'g'), ''); + alert(str); + Reflect.set(window, 'ea', Array.from(arguments)); + Reflect.set(window, 'em', msg); + Reflect.set(window, 'el', line); + Reflect.set(window, 'ec', column); + Reflect.set(window, 'eo', err); + game.print(str); + if (promiseErrorHandler.onErrorFinish) promiseErrorHandler.onErrorFinish(); + // @ts-ignore + if (!lib.config.errstop) { + _status.withError = true; + game.loop(); + } + }; +} + +function setWindowListener() { + window.onkeydown = function (e) { + if (!Reflect.has(ui, 'menuContainer') || !Reflect.get(ui, 'menuContainer').classList.contains('hidden')) { + if (e.keyCode == 116 || ((e.ctrlKey || e.metaKey) && e.keyCode == 82)) { + if (e.shiftKey) { + if (confirm('是否重置游戏?')) { + var noname_inited = localStorage.getItem('noname_inited'); + var onlineKey = localStorage.getItem(lib.configprefix + 'key'); + localStorage.clear(); + if (noname_inited) { + localStorage.setItem('noname_inited', noname_inited); + } + if (onlineKey) { + localStorage.setItem(lib.configprefix + 'key', onlineKey); + } + if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + 'data'); + game.reload(); + return; + } + } + else { + game.reload(); + } + } + else if (e.keyCode == 83 && (e.ctrlKey || e.metaKey)) { + if (Reflect.has(window, 'saveNonameInput')) { + Reflect.get(window, 'saveNonameInput')(); + } + e.preventDefault(); + e.stopPropagation(); + return false; + } + else if (e.keyCode == 74 && (e.ctrlKey || e.metaKey) && Reflect.has(lib, 'node')) { + Reflect.get(lib, 'node').debug(); + } + } + else { + game.closePopped(); + var dialogs = document.querySelectorAll('#window>.dialog.popped:not(.static)'); + for (var i = 0; i < dialogs.length; i++) { + // @ts-ignore + dialogs[i].delete(); + } + if (e.keyCode == 32) { + var node = Reflect.get(ui, 'window').querySelector('pausedbg'); + if (node) { + node.click(); + } + else { + ui.click.pause(); + } + } + else if (e.keyCode == 65) { + if (Reflect.has(ui, 'auto')) + Reflect.get(ui, 'auto').click(); + } + else if (e.keyCode == 87) { + if (Reflect.has(ui, 'wuxie') && Reflect.get(ui, 'wuxie').style.display != 'none') { + Reflect.get(ui, 'wuxie').classList.toggle('glow'); + } + else if (Reflect.has(ui, 'tempnowuxie')) { + Reflect.get(ui, 'tempnowuxie').classList.toggle('glow'); + } + } + else if (e.keyCode == 116 || ((e.ctrlKey || e.metaKey) && e.keyCode == 82)) { + if (e.shiftKey) { + if (confirm('是否重置游戏?')) { + var noname_inited = localStorage.getItem('noname_inited'); + var onlineKey = localStorage.getItem(lib.configprefix + 'key'); + localStorage.clear(); + if (noname_inited) { + localStorage.setItem('noname_inited', noname_inited); + } + if (onlineKey) { + localStorage.setItem(lib.configprefix + 'key', onlineKey); + } + if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + 'data'); + game.reload(); + return; + } + } + else { + game.reload(); + } + } + else if (e.keyCode == 83 && (e.ctrlKey || e.metaKey)) { + e.preventDefault(); + e.stopPropagation(); + return false; + } + else if (e.keyCode == 74 && (e.ctrlKey || e.metaKey) && Reflect.has(lib, 'node')) { + Reflect.get(lib, 'node').debug(); + } + // else if(e.keyCode==27){ + // if(!ui.arena.classList.contains('paused')) ui.click.config(); + // } + } + }; +} diff --git a/noname/library/element/content.js b/noname/library/element/content.js index a02ecd75d..ffc85cfe0 100644 --- a/noname/library/element/content.js +++ b/noname/library/element/content.js @@ -1,8302 +1,8300 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; -import { GNC as gnc } from '../../gnc/index.js'; - -// 未来再改 -export const Content = { - emptyEvent: async (event) => { - event.trigger(event.name); - }, - //增加明置手牌 - addShownCards: async (event, _trigger, player) => { - const hs = player.getCards('h'), showingCards = event._cards.filter(showingCard => hs.includes(showingCard)), shown = player.getShownCards(); - event.gaintag.forEach(tag => player.addGaintag(showingCards, tag)); - if (!(event.cards = showingCards.filter(showingCard => !shown.includes(showingCard))).length) return; - game.log(player, '明置了', event.cards); - if (event.animate != false) player.$give(event.cards, player, false); - event.trigger('addShownCardsAfter'); - }, - //隐藏明置手牌 - hideShownCards: () => { - var shown = player.getShownCards(), hidingCards = event._cards.filter(hidingCard => shown.includes(hidingCard)); - if (!hidingCards.length) return; - if (event.gaintag.length) event.gaintag.forEach(tag => player.removeGaintag(tag, hidingCards)); - else { - var map = hidingCards.reduce((constructingMap, hidingCard) => { - hidingCard.gaintag.forEach(tag => { - if (!tag.startsWith('visible_')) return; - if (!constructingMap[tag]) constructingMap[tag] = []; - constructingMap[tag].push(hidingCard); - }); - return constructingMap; - }, {}); - Object.keys(map).forEach(key => player.removeGaintag(key, map[key])); - } - hidingCards.removeArray(player.getShownCards()); - if (!hidingCards.length) return; - game.log(player, '取消明置了', event.cards = hidingCards); - if (event.animate != false) player.$give(hidingCards, player, false); - event.trigger('hideShownCardsAfter'); - }, - //Execute the delay card effect - //执行延时锦囊牌效果 - executeDelayCardEffect: () => { - 'step 0'; - target.$phaseJudge(card); - event.cancelled = false; - event.trigger('executeDelayCardEffect'); - event.cardName = card.viewAs || card.name; - target.popup(event.cardName, 'thunder'); - if (!lib.card[event.cardName].effect) { - game.delay(); - event.finish(); - } - else if (!lib.card[event.cardName].judge) { - game.delay(); - event.nojudge = true; - } - 'step 1'; - if (event.cancelled || event.nojudge) return; - var next = player.judge(card), judge = event.judge; - if (typeof judge == 'function') next.judge = judge; - var judge2 = event.judge2; - if (typeof judge2 == 'function') next.judge2 = judge2; - 'step 2'; - if (event.excluded) delete event.excluded; - else { - var cardName = event.cardName; - if (event.cancelled && !event.direct) { - var cardCancel = lib.card[cardName].cancel; - if (cardCancel) { - var next = game.createEvent(`${cardName}Cancel`); - next.setContent(cardCancel); - next.cards = [card]; - if (!card.viewAs) { - var autoViewAs = next.card = get.autoViewAs(card); - autoViewAs.expired = card.expired; - } - else { - var autoViewAs = next.card = get.autoViewAs({ - name: cardName - }, next.cards); - autoViewAs.expired = card.expired; - } - next.player = player; - } - } - else { - var next = game.createEvent(cardName); - next.setContent(lib.card[cardName].effect); - next._result = result; - next.cards = [card]; - if (!card.viewAs) { - var autoViewAs = next.card = get.autoViewAs(card); - autoViewAs.expired = card.expired; - } - else { - var autoViewAs = next.card = get.autoViewAs({ - name: cardName - }, next.cards); - autoViewAs.expired = card.expired; - } - next.player = player; - } - } - ui.clear(); - card.delete(); - }, - //Gift - //赠予 - gift: () => { - 'step 0'; - event.num = 0; - 'step 1'; - if (num < cards.length) { - event.card = cards[num]; - event.trigger('gift'); - } - else { - game.delayx(); - event.finish(); - } - 'step 2'; - if (event.deniedGifts.includes(card)) { - game.log(target, '拒绝了', player, '赠予的', card); - event.trigger('giftDeny'); - player.loseToDiscardpile(card).log = false; - event.trigger('giftDenied'); - return; - } - game.log(player, '将', card, '赠予了', target); - player.$give(card, target, false); - game.delay(0.5); - event.trigger('giftAccept'); - if (get.type(card, false) == 'equip') target.equip(card).log = false; - else target.gain(card, player).visible = true; - event.trigger('giftAccepted'); - 'step 3'; - event.num++; - event.goto(1); - }, - //Recast - //重铸 - recast: () => { - 'step 0'; - game.log(player, '重铸了', cards); - if (typeof event.recastingLose != 'function') return; - event.trigger('recastingLose'); - event.recastingLose(player, cards); - event.trigger('recastingLost'); - event.recastingLosingEvents.push(...event.next.filter(value => value.name != 'arrangeTrigger')); - 'step 1'; - event.trigger('recast'); - 'step 2'; - if (typeof event.recastingGain != 'function') return; - event.trigger('recastingGain'); - event.recastingGain(player, cards); - event.trigger('recastingGained'); - event.recastingGainingEvents.push(...event.next.filter(value => value.name != 'arrangeTrigger')); - }, - //装备栏相关 - disableEquip: function () { - 'step 0'; - event.cards = []; - event.num = 0; - event.slotsx = []; - if (get.is.mountCombined()) { - event.slots.forEach(type => { - if (type == 'equip3' || type == 'equip4') event.slotsx.add('equip3_4'); - else event.slotsx.add(type); - }); - } - else { - event.slotsx.addArray(event.slots); - } - event.slotsx.sort(); - if (!event.slots.length) event.finish(); - 'step 1'; - var slot = event.slotsx[event.num]; - var slot_key = slot; - var left = player.countEnabledSlot(slot), lose; - if (slot == 'equip3_4') { - lose = Math.min(left, Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4'))); - slot_key = 'equip3'; - } - else lose = Math.min(left, get.numOf(event.slots, slot)); - if (lose <= 0) event.goto(3); - else { - game.log(player, '废除了' + get.cnNumber(lose) + '个', '#g' + get.translation(slot) + '栏'); - if (!player.disabledSlots) player.disabledSlots = {}; - if (!player.disabledSlots[slot_key]) player.disabledSlots[slot_key] = 0; - player.disabledSlots[slot_key] += lose; - var cards = player.getEquips(slot).filter(card => !event.cards.includes(card)); - if (cards.length > 0) { - if (lose >= left) { - event._result = { bool: true, links: cards }; - } - else if (cards.length > (left - lose)) { - var source = event.source, num = (cards.length - (left - lose)); - if (!source || !source.isIn()) source = player; - source.chooseButton([ - '选择' + (player == source ? '你' : get.translation(player)) + '的' + get.cnNumber(num) + '张' + get.translation(slot) + '牌置入弃牌堆', - cards, - ], true, [1, num]).set('filterOk', function () { - var evt = _status.event; - return ui.selected.buttons.reduce(function (num, button) { - if (evt.slot == 'equip3_4') return num + Math.max(get.numOf(get.subtypes(button.link, false), 'equip3'), get.numOf(get.subtypes(button.link, false), 'equip4')); - return num + get.numOf(get.subtypes(button.link, false), evt.slot); - }, 0) == evt.required; - }).set('required', num).set('slot', slot); - } - else event.goto(3); - } - else event.goto(3); - } - 'step 2'; - if (result.bool) event.cards.addArray(result.links); - 'step 3'; - event.num++; - if (event.num < event.slotsx.length) event.goto(1); - else { - player.$syncDisable(); - if (cards.length > 0) player.loseToDiscardpile(cards); - } - }, - enableEquip: function () { - if (!event.slots.length) return; - var slotsx = [...new Set(event.slots)].sort(); - for (var slot of slotsx) { - var lost = player.countDisabledSlot(slot), gain = Math.min(lost, get.numOf(event.slots, slot)); - if (lost <= 0) continue; - else { - game.log(player, '恢复了' + get.cnNumber(gain) + '个', '#g' + get.translation(slot) + '栏'); - if (!player.disabledSlots) player.disabledSlots = {}; - if (!player.disabledSlots[slot]) player.disabledSlots[slot] = 0; - player.disabledSlots[slot] -= gain; - } - } - player.$syncDisable(); - }, - expandEquip: function () { - if (!event.slots.length) return; - var slotsx = []; - if (get.is.mountCombined()) { - event.slots.forEach(type => { - if (type == 'equip3' || type == 'equip4') slotsx.add('equip3_4'); - else slotsx.add(type); - }); - } - else { - slotsx.addArray(event.slots); - } - slotsx.sort(); - for (var slot of slotsx) { - var expand = get.numOf(event.slots, slot), slot_key = slot; - if (slot == 'equip3_4') { - expand = Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4')); - slot_key = 'equip3'; - } - game.log(player, '获得了' + get.cnNumber(expand) + '个额外的', '#g' + get.translation(slot) + '栏'); - if (!player.expandedSlots) player.expandedSlots = {}; - if (!player.expandedSlots[slot_key]) player.expandedSlots[slot_key] = 0; - player.expandedSlots[slot_key] += expand; - } - player.$syncExpand(); - }, - //选择顶装备要顶的牌 - replaceEquip: function () { - 'step 0'; - event.cards = []; - var types = get.subtypes(card, false); - if (types.length) { - var info = get.info(card, false); - if (info.customSwap) { - event.cards.addArray(player.getCards('e', function (card) { - return info.customSwap(card); - })); - event.goto(4); - } - else { - event.num = 0; - event.slots = types; - event.slotsx = []; - if (get.is.mountCombined()) { - event.slots.forEach(type => { - if (type == 'equip3' || type == 'equip4') event.slotsx.add('equip3_4'); - else event.slotsx.add(type); - }); - } - else { - event.slotsx.addArray(event.slots); - } - event.slotsx.sort(); - } - } - else event.goto(4); - 'step 1'; - var slot = event.slotsx[event.num]; - var left = player.countEquipableSlot(slot), lose; - if (slot == 'equip3_4') lose = Math.min(left, Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4'))); - else lose = Math.min(left, get.numOf(event.slots, slot)); - if (lose <= 0) event.goto(3); - else { - var cards = player.getEquips(slot).filter(card => { - return !event.cards.includes(card) && lib.filter.canBeReplaced(card, player); - }); - if (cards.length > 0) { - if (lose >= left) { - event._result = { bool: true, links: cards }; - } - else if (cards.length > (left - lose)) { - var source = event.source, num = (cards.length - (left - lose)); - if (!source || !source.isIn()) source = player; - source.chooseButton([ - '选择替换掉' + get.cnNumber(num) + '张' + get.translation(slot) + '牌', - cards, - ], true, [1, num]).set('filterOk', function () { - var evt = _status.event; - return ui.selected.buttons.reduce(function (num, button) { - if (evt.slot == 'equip3_4') return num + Math.max(get.numOf(get.subtypes(button.link, false), 'equip3'), get.numOf(get.subtypes(button.link, false), 'equip4')); - return num + get.numOf(get.subtypes(button.link, false), evt.slot); - }, 0) == evt.required; - }).set('required', num).set('slot', slot); - } - else event.goto(3); - } - else event.goto(3); - } - 'step 2'; - if (result.bool) event.cards.addArray(result.links); - 'step 3'; - event.num++; - if (event.num < event.slotsx.length) event.goto(1); - 'step 4'; - event.result = cards; - }, - //装备牌 - equip: function () { - "step 0"; - var owner = get.owner(card); - if (owner) { - event.owner = owner; - owner.lose(card, ui.special, 'visible').set('type', 'equip').set('getlx', false); - } - else if (get.position(card) == 'c') event.updatePile = true; - "step 1"; - if (event.cancelled) { - event.finish(); - return; - } - if (card.willBeDestroyed('equip', player, event)) { - card.selfDestroy(event); - event.finish(); - return; - } - else if (event.owner) { - if (event.owner.getCards('hejsx').includes(card)) { - event.finish(); - return; - } - } - if (event.draw) { - game.delay(0, 300); - player.$draw(card); - } - "step 2"; - if (card.clone) { - game.broadcast(function (card, player) { - if (card.clone) { - card.clone.moveDelete(player); - } - }, card, player); - card.clone.moveDelete(player); - game.addVideo('gain2', player, get.cardsInfo([card.clone])); - } - player.equiping = true; - "step 3"; - var info = get.info(card, false); - var next = game.createEvent('replaceEquip'); - next.player = player; - next.card = card; - next.setContent(info.replaceEquip || 'replaceEquip'); - "step 4"; - var info = get.info(card, false); - if (get.itemtype(result) == 'cards') { - player.lose(result, 'visible').set('type', 'equip').set('getlx', false).swapEquip = true; - if (info.loseThrow) { - player.$throw(result, 1000); - } - event.swapped = true; - } - "step 5"; - //if(player.isMin() || player.countCards('e',{subtype:get.subtype(card)})){ - if (player.isMin() || !player.canEquip(card)) { - event.finish(); - game.cardsDiscard(card); - delete player.equiping; - return; - } - var subtype = get.subtype(card); - if (subtype == 'equip6') subtype = 'equip3'; - game.broadcastAll(function (type) { - if (lib.config.background_audio) { - game.playAudio('effect', type); - } - }, subtype); - player.$equip(card); - game.addVideo('equip', player, get.cardInfo(card)); - if (event.log != false) game.log(player, '装备了', card); - if (event.updatePile) game.updateRoundNumber(); - "step 6"; - var info = get.info(card, false); - if (info.onEquip && (!info.filterEquip || info.filterEquip(card, player))) { - if (Array.isArray(info.onEquip)) { - for (var i = 0; i < info.onEquip.length; i++) { - var next = game.createEvent('equip_' + card.name); - next.setContent(info.onEquip[i]); - next.player = player; - next.card = card; - } - } - else { - var next = game.createEvent('equip_' + card.name); - next.setContent(info.onEquip); - next.player = player; - next.card = card; - } - if (info.equipDelay != false) game.delayx(); - } - delete player.equiping; - if (event.delay) { - game.delayx(); - } - }, - //装备栏 END - changeGroup: function () { - 'step 0'; - event.originGroup = player.group; - if (!event.group) event.group = player.group; - var group = event.group; - player.getHistory('custom').push(event); - if (event.broadcast !== false) { - game.broadcast(function (player, group) { - player.group = group; - player.node.name.dataset.nature = get.groupnature(group); - }, player, group); - } - player.group = group; - player.node.name.dataset.nature = get.groupnature(group); - if (event.log !== false) game.log(player, '将势力变为了', '#y' + get.translation(group + 2)); - }, - chooseToDebate: function () { - 'step 0'; - event.targets = event.list.filter(function (i) { - return i.countCards('h') > 0; - }); - if (!event.targets.length) event.result = { bool: false }; - else { - var next = player.chooseCardOL(event.targets, get.translation(player) + '发起了议事,请选择展示的手牌', true).set('type', 'debate').set('source', player).set('ai', event.ai || function (card) { - return Math.random(); - }).set('aiCard', event.aiCard || function (target) { - var hs = target.getCards('h'); - return { bool: true, cards: [hs.randomGet()] }; - }); - next._args.remove('glow_result'); - } - 'step 1'; - var red = [], black = []; - event.videoId = lib.status.videoId++; - for (var i = 0; i < event.targets.length; i++) { - var card = result[i].cards[0], target = event.targets[i]; - if (get.color(card, target) == 'red') red.push([target, card]); - else black.push([target, card]); - } - event.red = red; event.black = black; - if (red.length) { - game.log(red.map(function (i) { - return i[0]; - }), '意见为红色,展示了', red.map(function (i) { - return i[1]; - })); - } - else game.log('#b无人', '意见为红色'); - if (black.length) { - game.log(black.map(function (i) { - return i[0]; - }), '意见为', '#g黑色', ',展示了', black.map(function (i) { - return i[1]; - })); - } - else game.log('#b无人', '意见为', '#g黑色'); - game.broadcastAll(function (name, id, redArgs, blackArgs) { - var dialog = ui.create.dialog(name + '发起了议事', 'hidden', 'forcebutton'); - dialog.videoId = id; - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - dialog.buttonss = []; - - var list = ['意见为红色的角色', '意见为黑色的角色']; - for (var i = 0; i < list.length; i++) { - dialog.add('
' + list[i] + '
'); - var buttons = ui.create.div('.buttons', dialog.content); - dialog.buttonss.push(buttons); - buttons.classList.add('popup'); - buttons.classList.add('guanxing'); - } - var func = function (target) { - if (target._tempTranslate) return target._tempTranslate; - var name = target.name; - if (lib.translate[name + '_ab']) return lib.translate[name + '_ab']; - return get.translation(name); - }; - for (var i = 0; i < redArgs.length; i++) { - var list = redArgs[i]; - var button = ui.create.button(list[1], 'card', dialog.buttonss[0]); - button.querySelector('.info').innerHTML = func(list[0]); - } - for (var i = 0; i < blackArgs.length; i++) { - var list = blackArgs[i]; - var button = ui.create.button(list[1], 'card', dialog.buttonss[1]); - button.querySelector('.info').innerHTML = func(list[0]); - } - dialog.open(); - }, get.translation(player), event.videoId, red, black); - game.delay(4); - 'step 2'; - game.broadcastAll('closeDialog', event.videoId); - var opinion = null; - if (event.red.length > event.black.length) opinion = 'red'; - else if (event.red.length < event.black.length) opinion = 'black'; - if (opinion) game.log(player, '本次发起的议事结果为', opinion == 'red' ? '红色' : '#g黑色'); - else game.log(player, '本次发起的议事无结果'); - event.result = { - bool: true, - opinion: opinion, - red: event.red, - black: event.black, - targets: event.targets - }; - 'step 3'; - if (event.callback) { - var next = game.createEvent('debateCallback', false); - next.player = player; - next.debateResult = get.copy(event.result); - next.setContent(event.callback); - } - }, - delay: function () { - game[event.name].apply(game, event._args); - }, - chooseCooperationFor: function () { - 'step 0'; - var next = player.chooseButton([ - '选择和' + get.translation(target) + '的协力方式', - [event.cardlist, 'vcard'], - ], true); - next.set('ai', event.ai || function () { - return Math.random(); - }); - 'step 1'; - if (result.bool) { - player.cooperationWith(target, result.links[0][2].slice(12), event.reason); - } - }, - chooseToPlayBeatmap: function () { - 'step 0'; - if (game.online) return; - if (_status.connectMode) event.time = lib.configOL.choose_timeout; - event.videoId = lib.status.videoId++; - //给其他角色看的演奏框 - game.broadcastAll(function (player, id, beatmap) { - if (_status.connectMode) lib.configOL.choose_timeout = (Math.ceil((beatmap.timeleap[beatmap.timeleap.length - 1] + beatmap.speed * 100 + (beatmap.current || 0)) / 1000) + 5).toString(); - if (player == game.me) return; - var str = get.translation(player) + '正在演奏《' + beatmap.name + '》...'; - if (!_status.connectMode) str += '
(点击屏幕可以跳过等待AI操作)'; - ui.create.dialog(str).videoId = id; - if (ui.backgroundMusic) ui.backgroundMusic.pause(); - if (lib.config.background_audio) { - if (beatmap.filename.startsWith('ext:')) game.playAudio(beatmap.filename); - else game.playAudio('effect', beatmap.filename); - } - }, player, event.videoId, event.beatmap); - 'step 1'; - var beatmap = event.beatmap; - if (event.isMine()) { - var timeleap = beatmap.timeleap.slice(0); - var current = beatmap.current; - //获取两个音符的时间间隔 - var getTimeout = function () { - var time = timeleap.shift(); - var out = time - current; - current = time; - return out; - }; - //初始化一堆变量 - var score = 0; - var added = timeleap.length; - var number_of_tracks = beatmap.number_of_tracks || 6; - var custom_mapping = Array.isArray(beatmap.mapping); - var mapping = custom_mapping ? beatmap.mapping.slice() : beatmap.mapping; - var hitsound = beatmap.hitsound || 'hitsound.wav'; - if (hitsound.startsWith('ext:')) hitsound = lib.assetURL + 'extension/' + hitsound.slice(4); - else hitsound = lib.assetURL + 'audio/effect/' + hitsound; - var hitsound_audio = new Audio(hitsound); - hitsound_audio.volume = 0.25; - var abs = 1; - var node_pos = 0; - if (custom_mapping) { - node_pos = mapping.shift(); - } - else if (mapping == 'random') { - abs = get.rand(number_of_tracks); - node_pos = abs; - } - var combo = 0; - var max_combo = 0; - var nodes = []; - var roundmenu = false; - //隐藏菜单按钮 - if (ui.roundmenu && ui.roundmenu.display != 'none') { - roundmenu = true; - ui.roundmenu.style.display = 'none'; - } - if (ui.backgroundMusic) ui.backgroundMusic.pause(); - var event = _status.event; - event.settleed = false; - //建个框框 - var dialog = ui.create.dialog('forcebutton', 'hidden'); - event.dialog = dialog; - event.dialog.textPrompt = event.dialog.add('
' + (beatmap.prompt || '在音符滑条和底部判定区重合时点击屏幕!') + '
'); - event.switchToAuto = function () { }; - event.dialog.classList.add('fixed'); - event.dialog.classList.add('scroll1'); - event.dialog.classList.add('scroll2'); - event.dialog.classList.add('fullwidth'); - event.dialog.classList.add('fullheight'); - event.dialog.classList.add('noupdate'); - event.dialog.style.overflow = 'hidden'; - //结束后操作 - event.settle = function () { - if (event.settleed) return; - event.settleed = true; - //评分 - var acc = Math.floor(score / (added * 5) * 100); - if (!Array.isArray(lib.config.choose_to_play_beatmap_accuracies)) lib.config.choose_to_play_beatmap_accuracies = []; - lib.config.choose_to_play_beatmap_accuracies.push(acc); - if (lib.config.choose_to_play_beatmap_accuracies.length > 5) lib.config.choose_to_play_beatmap_accuracies.shift(); - game.saveConfigValue("choose_to_play_beatmap_accuracies"); - var rank; - if (acc == 100) rank = ['SS', 'metal']; - else if (acc >= 94) rank = ['S', 'orange']; - else if (acc >= 87) rank = ['A', 'wood']; - else if (acc >= 80) rank = ['B', 'water']; - else if (acc >= 65) rank = ['C', 'thunder']; - else rank = ['D', 'fire']; - event.dialog.textPrompt.innerHTML = '
演奏结束!
最大连击数:' + max_combo + ' 精准度:' + acc + '%
'; - game.me.$fullscreenpop('演奏评级:' + rank[0] + '', null, null, false); - //返回结果并继续游戏 - setTimeout(function () { - event._result = { - bool: true, - accuracy: acc, - rank: rank, - }; - event.dialog.close(); - game.resume(); - _status.imchoosing = false; - if (roundmenu) ui.roundmenu.style.display = ''; - if (ui.backgroundMusic) ui.backgroundMusic.play(); - hitsound_audio.remove(); - }, 1000); - }; - event.dialog.open(); - //操作容差 - var height = event.dialog.offsetHeight; - var width = event.dialog.offsetWidth; - var range1 = (beatmap.range1 || [90, 110]); - var range2 = (beatmap.range2 || [93, 107]); - var range3 = (beatmap.range3 || [96, 104]); - var speed = (beatmap.speed || 25); - //初始化底部的条子 - var judger = ui.create.div(''); - judger.style["background-image"] = (beatmap.judgebar_color || 'linear-gradient(rgba(240, 235, 3, 1), rgba(230, 225, 5, 1))'); - judger.style["border-radius"] = '3px'; - judger.style.position = 'absolute'; - judger.style.opacity = '0.3'; - var heightj = Math.ceil(height * (beatmap.judgebar_height || 0.1)); - judger.style.height = heightj + 'px'; - judger.style.width = width + 'px'; - judger.style.left = '0px'; - judger.style.top = (height - heightj) + 'px'; - event.dialog.appendChild(judger); - //生成每个音符 - var addNode = function () { - var node = ui.create.div(''); - nodes.push(node); - node.style["background-image"] = (beatmap.node_color || 'linear-gradient(rgba(120, 120, 240, 1), rgba(100, 100, 230, 1))'); - node.style["border-radius"] = '3px'; - node.style.position = 'absolute'; - node.style.height = Math.ceil(height / 10) + 'px'; - node.style.width = Math.ceil(width / number_of_tracks) - 10 + 'px'; - node._position = get.utc(); - event.dialog.appendChild(node); - - node.style.left = Math.ceil(width * node_pos / number_of_tracks + 5) + 'px'; - node.style.top = '-' + (Math.ceil(height / 10)) + 'px'; - ui.refresh(node); - node.style.transition = 'all ' + speed * 110 + 'ms linear'; - node.style.transform = 'translateY(' + Math.ceil(height * 1.1) + 'px)'; - node.timeout = setTimeout(function () { - if (nodes.includes(node)) { - nodes.remove(node); - player.popup('Miss', 'fire', false); - if (player.damagepopups.length) player.$damagepop(); - combo = 0; - } - }, speed * 110); - - if (custom_mapping) { - node_pos = mapping.shift(); - } - else if (mapping == 'random') { - while (node_pos == abs) { - node_pos = get.rand(number_of_tracks); - } - abs = node_pos; - } - else { - node_pos += abs; - if (node_pos > number_of_tracks - 1) { - abs = -1; - node_pos = number_of_tracks - 2; - } - else if (node_pos < 0) { - abs = 1; - node_pos = 1; - } - } - if (timeleap.length) { - setTimeout(function () { - addNode(); - }, getTimeout()); - } - else { - setTimeout(function () { - event.settle(); - }, speed * 110 + 100); - } - }; - //点击时的判断操作 - var click = function () { - if (!nodes.length) return; - for (var node of nodes) { - //用生成到点击的时间差来判断距离 - var time = get.utc(); - var top = (time - node._position) / speed; - if (top > range1[1]) continue; - else if (top < range1[0]) return; - nodes.remove(node); - clearTimeout(node.timeout); - node.style.transform = ''; - node.style.transition = 'all 0s'; - node.style.top = (height * ((top - 10) / 100)) + 'px'; - ui.refresh(node); - node.style.transition = 'all 0.5s'; - node.style.transform = 'scale(1.2)'; - node.delete(); - if (top >= range3[0] && top < range3[1]) { - score += 5; - player.popup('Perfect', 'orange', false); - } - else if (top >= range2[0] && top < range2[1]) { - score += 3; - player.popup('Great', 'wood', false); - } - else { - score += 1; - player.popup('Good', 'soil', false); - } - if (player.damagepopups.length) player.$damagepop(); - combo++; - max_combo = Math.max(combo, max_combo); - hitsound_audio.currentTime = 0; - if (hitsound_audio.paused) Promise.resolve(hitsound_audio.play()).catch(() => void 0); - break; - } - }; - document.addEventListener(lib.config.touchscreen ? 'touchstart' : 'mousedown', click); - - game.pause(); - game.countChoose(); - setTimeout(() => { - if (!lib.config.background_audio) return; - if (beatmap.filename.startsWith('ext:')) game.playAudio(beatmap.filename); - else game.playAudio('effect', beatmap.filename); - }, Math.floor(speed * 100 * (0.9 + beatmap.judgebar_height)) + beatmap.current); - setTimeout(function () { - addNode(); - }, getTimeout()); - } - else if (event.isOnline()) { - event.send(); - } - else { - game.pause(); - game.countChoose(); - var settle = function () { - _status.imchoosing = false; - //Algorithm: Generate the random number range using the mean and the half standard deviation of accuracies of the player's last 5 plays - //算法:用玩家的上5次游玩的准确率的平均数和半标准差生成随机数范围 - var choose_to_play_beatmap_accuracies = (lib.config.choose_to_play_beatmap_accuracies || []).concat(Array.from({ - length: 6 - (lib.config.choose_to_play_beatmap_accuracies || []).length - }, () => get.rand(70, 100))); - var mean = Math.round(choose_to_play_beatmap_accuracies.reduce((previousValue, currentValue) => previousValue + currentValue) / choose_to_play_beatmap_accuracies.length); - var half_standard_deviation = Math.round(Math.sqrt(choose_to_play_beatmap_accuracies.reduce((previousValue, currentValue) => previousValue + Math.pow(currentValue - mean, 2), 0)) / 2); - var acc = Math.min(Math.max(get.rand.apply(get, beatmap.aiAcc || [mean - half_standard_deviation - get.rand(0, half_standard_deviation), mean + half_standard_deviation + get.rand(0, half_standard_deviation)]), 0), 100); - var rank; - if (acc == 100) rank = ['SS', 'metal']; - else if (acc >= 94) rank = ['S', 'orange']; - else if (acc >= 87) rank = ['A', 'green']; - else if (acc >= 80) rank = ['B', 'water']; - else if (acc >= 65) rank = ['C', 'thunder']; - else rank = ['D', 'fire']; - event._result = { - bool: true, - accuracy: acc, - rank: rank, - }; - if (event.dialog) event.dialog.close(); - if (event.control) event.control.close(); - game.resume(); - }; - var song_duration = beatmap.timeleap[beatmap.timeleap.length - 1] + beatmap.speed * 100 + 1000 + (beatmap.current || 0); - var settle_timeout = setTimeout(settle, song_duration); - if (!_status.connectMode) { - var skip_timeout; - var skip = () => { - settle(); - Array.from(ui.window.getElementsByTagName('audio')).forEach(audio => { - if (audio.currentSrc.includes(beatmap.filename.startsWith('ext:') ? beatmap.name : beatmap.filename)) audio.remove(); - }); - document.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip); - clearTimeout(settle_timeout); - clearTimeout(skip_timeout); - }; - document.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip); - skip_timeout = setTimeout(() => document.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip), song_duration); - } - } - 'step 2'; - game.broadcastAll(function (id, time) { - if (_status.connectMode) lib.configOL.choose_timeout = time; - var dialog = get.idDialog(id); - if (dialog) { - dialog.close(); - } - if (ui.backgroundMusic) ui.backgroundMusic.play(); - }, event.videoId, event.time); - var result = event.result || result; - event.result = result; - }, - chooseToMove: function () { - 'step 0'; - if (event.chooseTime && _status.connectMode && !game.online) { - event.time = lib.configOL.choose_timeout; - game.broadcastAll(function (time) { - lib.configOL.choose_timeout = time; - }, event.chooseTime); - } - if (event.isMine()) { - delete ui.selected.guanxing_button; - var list = event.list, filterMove = event.filterMove, filterOk = event.filterOk; - _status.imchoosing = true; - var event = _status.event; - event.settleed = false; - event.dialog = ui.create.dialog(event.prompt || '请选择要操作的牌', 'hidden', 'forcebutton'); - event.switchToAuto = function () { - if (!filterOk(event.moved)) { - if (!event.forced) event._result = { bool: false }; - else event._result = 'ai'; - } - else { - event._result = { - bool: true, - moved: event.moved, - }; - } - event.dialog.close(); - if (ui.confirm) ui.confirm.close(); - game.resume(); - _status.imchoosing = false; - setTimeout(function () { - ui.arena.classList.remove('choose-to-move'); - }, 500); - }; - event.dialog.classList.add('scroll1'); - event.dialog.classList.add('scroll2'); - event.dialog.classList.add('fullwidth'); - if (list.length > 1) { - ui.arena.classList.add('choose-to-move'); - event.dialog.classList.add('fullheight'); - } - - event.moved = []; - var buttonss = []; - event.buttonss = buttonss; - var updateButtons = function () { - for (var i of buttonss) { - event.moved[i._link] = get.links(Array.from(i.childNodes)); - if (i.textPrompt) i.previousSibling.innerHTML = ('
' + i.textPrompt(event.moved[i._link]) + '
'); - } - if (filterOk(event.moved)) { - ui.create.confirm('o'); - } - else { - if (!event.forced) ui.create.confirm('c'); - else if (ui.confirm) ui.confirm.close(); - } - }; - var clickButtons = function () { - if (!ui.selected.guanxing_button) return; - if (ui.selected.guanxing_button.parentNode == this) return; - if (!filterMove(ui.selected.guanxing_button, this._link, event.moved)) return; - ui.selected.guanxing_button.classList.remove('glow2'); - this.appendChild(ui.selected.guanxing_button); - delete ui.selected.guanxing_button; - updateButtons(); - }; - - for (var i = 0; i < list.length; i++) { - var tex = event.dialog.add('
' + list[i][0] + '
'); - tex.classList.add('choosetomove'); - var buttons = ui.create.div('.buttons', event.dialog.content, clickButtons); - buttonss.push(buttons); - buttons.classList.add('popup'); - buttons.classList.add('guanxing'); - buttons._link = i; - if (list[i][1]) { - if (get.itemtype(list[i][1]) == 'cards') { - var cardsb = ui.create.buttons(list[i][1], 'card', buttons); - if (list[i][2] && typeof list[i][2] == 'string') { - for (var ij of cardsb) ij.node.gaintag.innerHTML = get.translation(list[i][2]); - } - } - else if (list[i][1].length == 2) { - ui.create.buttons(list[i][1][0], list[i][1][1], buttons); - } - } - if (list[i][2] && typeof list[i][2] == 'function') buttons.textPrompt = list[i][2]; - } - var tex = event.dialog.add('
点击两张牌以交换位置;点击一张牌并点击其他区域以移动卡牌
'); - tex.classList.add('choosetomove'); - - event.dialog.open(); - updateButtons(); - - event.custom.replace.button = function (button) { - var node = button.parentNode; - if (!buttonss.includes(node)) return; - if (!ui.selected.guanxing_button) { - ui.selected.guanxing_button = button; - button.classList.add('glow2'); - return; - } - if (ui.selected.guanxing_button == button) { - button.classList.remove('glow2'); - delete ui.selected.guanxing_button; - return; - } - if (!filterMove(button, ui.selected.guanxing_button, event.moved)) return; - var par1 = ui.selected.guanxing_button.parentNode, ind1 = ui.selected.guanxing_button.nextSibling, par2 = button.parentNode, ind2 = button.nextSibling; - ui.selected.guanxing_button.classList.remove('glow2'); - par1.insertBefore(button, ind1); - par2.insertBefore(ui.selected.guanxing_button, ind2); - delete ui.selected.guanxing_button; - updateButtons(); - }; - event.custom.replace.confirm = function (bool) { - if (bool) event._result = { - bool: true, - moved: event.moved, - }; - else event._result = { bool: false }; - event.dialog.close(); - if (ui.confirm) ui.confirm.close(); - game.resume(); - _status.imchoosing = false; - setTimeout(function () { - ui.arena.classList.remove('choose-to-move'); - }, 500); - }; - - game.pause(); - game.countChoose(); - event.choosing = true; - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.time) game.broadcastAll(function (time) { - lib.configOL.choose_timeout = time; - }, event.time); - var result = event.result || result; - if ((!result || result == 'ai' || (event.forced && !result.bool)) && event.processAI) { - var moved = event.processAI(event.list); - if (moved) result = { - bool: true, - moved: moved, - }; - else result = { bool: false }; - } - event.result = result; - }, - showCharacter: function () { - 'step 0'; - event.trigger('showCharacterEnd'); - 'step 1'; - event.trigger('showCharacterAfter'); - if (get.mode() == 'identity' && player.isZhu) event.trigger('zhuUpdate'); - }, - removeCharacter: function () { - player.$removeCharacter(event.num); - }, - chooseUseTarget: function () { - 'step 0'; - if (get.is.object(card) && !event.viewAs) card.isCard = true; - if (cards && get.itemtype(card) != 'card') { - card = get.copy(card); - card.cards = cards.slice(0); - event.card = card; - } - if (!lib.filter.cardEnabled(card, player) || (event.addCount !== false && !lib.filter.cardUsable(card, player))) { - event.result = { bool: false }; - event.finish(); - return; - } - var info = get.info(card); - var range; - if (!info.notarget) { - var select = get.copy(info.selectTarget); - range = get.select(select); - if (event.selectTarget) range = get.select(event.selectTarget); - game.checkMod(card, player, range, 'selectTarget', player); - } - if (info.notarget || range[1] <= -1) { - if (!info.notarget && range[1] <= -1) { - for (var i = 0; i < targets.length; i++) { - if (event.filterTarget) { - if (!event.filterTarget(card, player, targets[i])) { - targets.splice(i--, 1); - } - } - else if (!player.canUse(card, targets[i], event.nodistance ? false : null, event.addCount === false ? null : true)) { - targets.splice(i--, 1); - } - } - if (targets.length) { - event.targets2 = targets; - } - else { - event.finish(); - return; - } - } - else event.targets2 = []; - if (event.forced) { - event._result = { bool: true }; - return; - } - else { - var next = player.chooseBool(); - next.set('prompt', event.prompt || ('是否' + (event.targets2.length ? '对' : '') + get.translation(event.targets2) + '使用' + get.translation(card) + '?')); - if (event.hsskill) next.setHiddenSkill(event.hsskill); - if (event.prompt2) next.set('prompt2', event.prompt2); - next.ai = function () { - var eff = 0; - for (var i = 0; i < event.targets2.length; i++) { - eff += get.effect(event.targets2[i], card, player, player); - } - return eff > 0; - }; - } - } - else { - if (event.filterTarget) { - var targets = game.filterPlayer(function (current) { - return event.filterTarget(card, player, current); - }); - if (targets.length < range[0]) { - event._result = { bool: false }; - return; - } - else if (!info.complexTarget && targets.length == range[0] && range[0] == range[1]) { - event.targets2 = targets; - event._result = { bool: true }; - return; - } - } - var next = player.chooseTarget(); - next.set('_get_card', card); - next.set('filterTarget', event.filterTarget || function (card, player, target) { - if (!_status.event.targets.includes(target)) return false; - if (!_status.event.nodistance && !lib.filter.targetInRange(card, player, target)) return false; - return lib.filter.targetEnabledx(card, player, target); - }); - next.set('ai', event.ai || get.effect_use); - next.set('selectTarget', event.selectTarget || lib.filter.selectTarget); - if (event.nodistance) next.set('nodistance', true); - if (event.forced) next.set('forced', true); - if (event.addCount !== false) next.set('addCount_extra', true); - next.set('targets', targets); - next.set('prompt', event.prompt || ('选择' + get.translation(card) + '的目标')); - if (event.prompt2) next.set('prompt2', event.prompt2); - if (event.hsskill) next.setHiddenSkill(event.hsskill); - } - 'step 1'; - if (result.bool) { - event.result = { - bool: true, - targets: event.targets2 || result.targets, - }; - var args = [card, event.targets2 || result.targets]; - if (cards) args.push(cards.slice()); - var next = player.useCard(...args); - next.oncard = event.oncard; - if (cards) next.cards = cards.slice(0); - if (event.nopopup) next.nopopup = true; - if (event.animate === false) next.animate = false; - if (event.throw === false) next.throw = false; - if (event.addCount === false) next.addCount = false; - if (event.noTargetDelay) next.targetDelay = false; - if (event.nodelayx) next.delayx = false; - if (event.logSkill) { - if (typeof event.logSkill == 'string') { - next.skill = event.logSkill; - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - } - else event.result = { bool: false }; - }, - chooseToDuiben: function () { - 'step 0'; - if (!event.namelist) event.namelist = ['全军出击', '分兵围城', '奇袭粮道', '开城诱敌']; - game.broadcastAll(function (list) { - var list2 = ['db_atk1', 'db_atk2', 'db_def1', 'db_def2']; - for (var i = 0; i < 4; i++) { - lib.card[list2[i]].image = 'card/' + list2[i] + (list[0] == '全军出击' ? '' : '_' + list[i]); - lib.translate[list2[i]] = list[i]; - } - }, event.namelist); - if (!event.title) event.title = '对策'; - game.log(player, '向', target, '发起了', '#y' + event.title); - if (!event.ai) event.ai = function () { return 1 + Math.random(); }; - if (_status.connectMode) { - player.chooseButtonOL([ - [player, [event.title + ':请选择一种策略', [[['', '', 'db_def2'], ['', '', 'db_def1']], 'vcard']], true], - [target, [event.title + ':请选择一种策略', [[['', '', 'db_atk1'], ['', '', 'db_atk2']], 'vcard']], true] - ], function () { }, event.ai).set('switchToAuto', function () { - _status.event.result = 'ai'; - }).set('processAI', function () { - var buttons = _status.event.dialog.buttons; - return { - bool: true, - links: [buttons.randomGet().link], - }; - }); - } - 'step 1'; - if (_status.connectMode) { - event.mes = result[player.playerid].links[0][2]; - event.tes = result[target.playerid].links[0][2]; - event.goto(4); - } - else { - player.chooseButton([event.title + ':请选择一种策略', [[['', '', 'db_def2'], ['', '', 'db_def1']], 'vcard']], true).ai = event.ai; - } - 'step 2'; - event.mes = result.links[0][2]; - target.chooseButton([event.title + ':请选择一种策略', [[['', '', 'db_atk1'], ['', '', 'db_atk2']], 'vcard']], true).ai = event.ai; - 'step 3'; - event.tes = result.links[0][2]; - 'step 4'; - game.broadcast(function () { - ui.arena.classList.add('thrownhighlight'); - }); - ui.arena.classList.add('thrownhighlight'); - game.addVideo('thrownhighlight1'); - target.$compare(game.createCard(event.tes, '', ''), player, game.createCard(event.mes, '', '')); - game.log(target, '选择的策略为', '#g' + get.translation(event.tes)); - game.log(player, '选择的策略为', '#g' + get.translation(event.mes)); - game.delay(0, 1500); - 'step 5'; - var mes = event.mes.slice(6); - var tes = event.tes.slice(6); - var str; - if (mes == tes) { - str = get.translation(player) + event.title + '成功'; - player.popup('胜', 'wood'); - target.popup('负', 'fire'); - game.log(player, '#g胜'); - event.result = { bool: true }; - } - else { - str = get.translation(player) + event.title + '失败'; - target.popup('胜', 'wood'); - player.popup('负', 'fire'); - game.log(target, '#g胜'); - event.result = { bool: false }; - } - event.result.player = event.mes; - event.result.target = event.tes; - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - game.trySkillAudio(event.getParent().name + '_' + (event.result.bool ? 'true' + mes : 'false'), player); - game.delay(2); - 'step 6'; - game.broadcastAll(function () { - ui.arena.classList.remove('thrownhighlight'); - }); - game.addVideo('thrownhighlight2'); - if (event.clear !== false) { - game.broadcastAll(ui.clear); - } - }, - chooseToPSS: function () { - 'step 0'; - game.log(player, '对', target, '发起了猜拳'); - if (_status.connectMode) { - player.chooseButtonOL([ - [player, ['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true], - [target, ['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true] - ], function () { }, function () { return 1 + Math.random(); }).set('switchToAuto', function () { - _status.event.result = 'ai'; - }).set('processAI', function () { - var buttons = _status.event.dialog.buttons; - return { - bool: true, - links: [buttons.randomGet().link], - }; - }); - } - 'step 1'; - if (_status.connectMode) { - event.mes = result[player.playerid].links[0][2]; - event.tes = result[target.playerid].links[0][2]; - event.goto(4); - } - else { - player.chooseButton(['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true).ai = function () { return 1 + Math.random(); }; - } - 'step 2'; - event.mes = result.links[0][2]; - target.chooseButton(['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true).ai = function () { return 1 + Math.random(); }; - 'step 3'; - event.tes = result.links[0][2]; - 'step 4'; - game.broadcast(function () { - ui.arena.classList.add('thrownhighlight'); - }); - ui.arena.classList.add('thrownhighlight'); - game.addVideo('thrownhighlight1'); - player.$compare(game.createCard(event.mes, '', ''), target, game.createCard(event.tes, '', '')); - game.log(player, '选择的手势为', '#g' + get.translation(event.mes)); - game.log(target, '选择的手势为', '#g' + get.translation(event.tes)); - game.delay(0, 1500); - 'step 5'; - var mes = event.mes.slice(4); - var tes = event.tes.slice(4); - var str; - if (mes == tes) { - str = '二人平局'; - player.popup('平', 'metal'); - target.popup('平', 'metal'); - game.log('猜拳的结果为', '#g平局'); - event.result = { tie: true }; - } - else { - if ({ paper: 'stone', scissor: 'paper', stone: 'scissor' }[mes] == tes) { - str = get.translation(player) + '胜利'; - player.popup('胜', 'wood'); - target.popup('负', 'fire'); - game.log(player, '#g胜'); - event.result = { bool: true }; - } - else { - str = get.translation(target) + '胜利'; - target.popup('胜', 'wood'); - player.popup('负', 'fire'); - game.log(target, '#g胜'); - event.result = { bool: false }; - } - } - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - game.delay(2); - 'step 6'; - game.broadcastAll(function () { - ui.arena.classList.remove('thrownhighlight'); - }); - game.addVideo('thrownhighlight2'); - if (event.clear !== false) { - game.broadcastAll(ui.clear); - } - }, - cardsDiscard: function () { - game.getGlobalHistory().cardMove.push(event); - var withPile = false; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('discardPile', null, event)) { - cards[i].selfDestroy(event); - continue; - } - if (get.position(cards[i], true) == 'c') withPile = true; - cards[i].discard(); - } - if (withPile) game.updateRoundNumber(); - }, - orderingDiscard: function () { - var cards = event.relatedEvent.orderingCards.slice(0); - for (var i = 0; i < cards.length; i++) { - if (get.position(cards[i], true) != 'o') cards.splice(i--, 1); - } - if (cards.length) game.cardsDiscard(cards); - }, - cardsGotoOrdering: function () { - game.getGlobalHistory().cardMove.push(event); - var withPile = false; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('ordering', null, event)) { - cards[i].selfDestroy(event); - continue; - } - if (get.position(cards[i], true) == 'c') withPile = true; - cards[i].fix(); - ui.ordering.appendChild(cards[i]); - } - if (withPile) game.updateRoundNumber(); - var evt = event.relatedEvent || event.getParent(); - if (!evt.orderingCards) evt.orderingCards = []; - if (!evt.noOrdering && !evt.cardsOrdered) { - evt.cardsOrdered = true; - var next = game.createEvent('orderingDiscard', false, evt.getParent()); - next.relatedEvent = evt; - next.setContent('orderingDiscard'); - } - if (!evt.noOrdering) evt.orderingCards.addArray(cards); - }, - cardsGotoSpecial: function () { - game.getGlobalHistory().cardMove.push(event); - var withPile = false; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('special', null, event)) { - cards[i].selfDestroy(event); - continue; - } - if (get.position(cards[i], true) == 'c') withPile = true; - cards[i].fix(); - ui.special.appendChild(cards[i]); - } - if (withPile) game.updateRoundNumber(); - if (event.toRenku) { - _status.renku.addArray(cards); - if (_status.renku.length > 6) { - var cards = _status.renku.splice(0, _status.renku.length - 6); - game.log(cards, '从仁库进入了弃牌堆'); - game.cardsDiscard(cards).set('outRange', true).fromRenku = true; - } - game.updateRenku(); - } - }, - cardsGotoPile: function () { - if (event.washCard) { - event.trigger('washCard'); - for (var i = 0; i < lib.onwash.length; i++) { - if (lib.onwash[i]() == 'remove') { - lib.onwash.splice(i--, 1); - } - } - } - game.getGlobalHistory().cardMove.push(event); - if (!event._triggeronly) game.$cardsGotoPile(event); - }, - chooseToEnable: function () { - 'step 0'; - var list = []; - for (var i = 1; i <= 5; i++) { - if (player.hasDisabledSlot(i)) list.push('equip' + i); - } - if (!list.length) event.finish(); - else if (list.length == 1) { - event.list = list; - event._result = { control: list[0] }; - } - else { - var next = player.chooseControl(list); - next.set('prompt', '请选择恢复一个装备栏'); - if (!event.ai) event.ai = function (event, player, list) { - return list.randomGet(); - }; - event.ai = event.ai(event.getParent(), player, list); - next.ai = function () { - return event.ai; - }; - } - 'step 1'; - event.result = { control: result.control }; - player.enableEquip(result.control); - }, - chooseToDisable: function () { - 'step 0'; - var list = []; - for (var i = 1; i <= 5; i++) { - if (player.hasEnabledSlot(i)) list.push('equip' + i); - } - if (event.horse) { - if (list.includes('equip3') && (get.is.mountCombined() || list.includes('equip4'))) list.push('equip3_4'); - list.remove('equip3'); - list.remove('equip4'); - } - if (!list.length) event.finish(); - else if (list.length == 1) { - event.list = list; - event._result = { control: list[0] }; - } - else { - list.sort(); - event.list = list; - var next = player.chooseControl(list); - next.set('prompt', '请选择废除一个装备栏'); - if (!event.ai) event.ai = function (event, player, list) { - return list.randomGet(); - }; - event.ai = event.ai(event.getParent(), player, list); - next.ai = function () { - return event.ai; - }; - } - 'step 1'; - event.result = { control: result.control }; - if (result.control == 'equip3_4') { - player.disableEquip(3, 4); - } - else player.disableEquip(result.control); - }, - swapEquip: function () { - "step 0"; - game.log(player, '和', target, '交换了装备区中的牌'); - event.cards = [player.getCards('e'), target.getCards('e')]; - game.loseAsync({ - player: player, - target: target, - cards1: event.cards[0], - cards2: event.cards[1], - }).setContent('swapHandcardsx'); - "step 1"; - for (var i = 0; i < event.cards[1].length; i++) { - if (get.position(event.cards[1][i], true) == 'o') player.equip(event.cards[1][i]); - } - for (var i = 0; i < event.cards[0].length; i++) { - if (get.position(event.cards[0][i], true) == 'o') target.equip(event.cards[0][i]); - } - }, - disableJudge: function () { - 'step 0'; - game.log(player, '废除了判定区'); - var js = player.getCards('j'); - if (js.length) player.discard(js); - player.storage._disableJudge = true; - //player.markSkill('_disableJudge'); - 'step 1'; - game.broadcastAll(function (player, card) { - player.$disableJudge(); - }, player); - }, - enableJudge: function () { - if (!player.storage._disableJudge) return; - game.log(player, '恢复了判定区'); - game.broadcastAll(function (player) { - player.$enableJudge(); - }, player); - }, - /*----分界线----*/ - phasing: function () { - 'step 0'; - while (ui.dialogs.length) { - ui.dialogs[0].close(); - } - game.phaseNumber++; - player.phaseNumber++; - game.broadcastAll(function (player, player2, num, popup) { - if (lib.config.glow_phase) { - if (player2) player2.classList.remove('glow_phase'); - player.classList.add('glow_phase'); - } - player.phaseNumber = num; - if (popup && lib.config.show_phase_prompt) player.popup('回合开始', null, false); - }, player, _status.currentPhase, player.phaseNumber, !player.noPhaseDelay); - _status.currentPhase = player; - _status.discarded = []; - game.syncState(); - game.addVideo('phaseChange', player); - if (game.phaseNumber == 1) { - delete player._start_cards; - if (lib.configOL.observe) { - lib.configOL.observeReady = true; - game.send('server', 'config', lib.configOL); - } - } - game.log(); - game.log(player, '的回合开始'); - player._noVibrate = true; - if (get.config('identity_mode') != 'zhong' && get.config('identity_mode') != 'purple' && !_status.connectMode) { - var num; - switch (get.config('auto_identity')) { - case 'one': num = 1; break; - case 'two': num = 2; break; - case 'three': num = 3; break; - case 'always': num = -1; break; - default: num = 0; break; - } - if (num && !_status.identityShown && game.phaseNumber > game.players.length * num && game.showIdentity) { - if (!_status.video) player.popup('显示身份'); - _status.identityShown = true; - game.showIdentity(false); - } - } - player.ai.tempIgnore = []; - if (ui.land && ui.land.player == player) { - game.addVideo('destroyLand'); - ui.land.destroy(); - } - 'step 1'; - event.trigger('phaseBeginStart'); - }, - toggleSubPlayer: function () { - 'step 0'; - var list = event.list || player.storage.subplayer.skills.slice(0); - list.remove(player.storage.subplayer.name2); - event.list = list; - if (!event.directresult) { - if (list.length > 1) { - var dialog = ui.create.dialog('更换一个随从', 'hidden'); - dialog.add([list, 'character']); - player.chooseButton(dialog, true); - } - else if (list.length == 1) { - event.directresult = list[0]; - } - else { - event.finish(); - } - } - else { - if (!list.includes(event.directresult)) { - event.finish(); - } - } - 'step 1'; - if (!event.directresult) { - if (result && result.bool && result.links[0]) { - event.directresult = result.links[0]; - } - else { - event.finish(); - return; - } - } - if (player.storage.subplayer) { - var current = player.storage.subplayer.name2; - if (event.directresult == current) { - event.finish(); - return; - } - player.storage[current].hp = player.hp; - player.storage[current].maxHp = player.maxHp; - player.storage[current].hs = player.getCards('h'); - player.storage[current].es = player.getCards('e'); - player.lose(player.getCards('he'), ui.special)._triggered = null; - - var cfg = player.storage[event.directresult]; - player.storage.subplayer.name2 = event.directresult; - player.reinit(current, event.directresult, [ - cfg.hp, - cfg.maxHp - ]); - if (cfg.hs.length) player.directgain(cfg.hs); - if (cfg.es.length) player.directequip(cfg.es); - } - }, - exitSubPlayer: function () { - 'step 0'; - if (player.storage.subplayer) { - var current = player.storage.subplayer.name2; - if (event.remove) { - player.lose(player.getCards('he'), ui.discardPile)._triggered = null; - } - else { - player.storage[current].hp = player.hp; - player.storage[current].maxHp = player.maxHp; - player.storage[current].hs = player.getCards('h'); - player.storage[current].es = player.getCards('e'); - player.lose(player.getCards('he'), ui.special)._triggered = null; - } - player.reinit(current, player.storage.subplayer.name, [ - player.storage.subplayer.hp, - player.storage.subplayer.maxHp - ]); - player.update(); - if (event.remove) { - if (player.storage[current].onremove) { - player.storage[current].onremove(player); - } - delete player.storage[current]; - player.storage.subplayer.skills.remove(current); - game.log(player, '牺牲了随从', '#g' + current); - } - else { - game.log(player, '收回了随从', '#g' + current); - } - player.addSkill(player.storage.subplayer.skills); - } - 'step 1'; - if (player.storage.subplayer) { - player.directgain(player.storage.subplayer.hs); - player.directequip(player.storage.subplayer.es); - } - player.removeSkill('subplayer'); - 'step 2'; - if (event.remove) { - event.trigger('subPlayerDie'); - } - }, - callSubPlayer: function () { - 'step 0'; - var list = player.getSubPlayers(event.tag); - event.list = list; - if (!event.directresult) { - if (list.length > 1) { - var dialog = ui.create.dialog('调遣一个随从', 'hidden'); - dialog.add([list, 'character']); - player.chooseButton(dialog, true); - } - else if (list.length == 1) { - event.directresult = list[0]; - } - else { - event.finish(); - } - } - else { - if (!list.includes(event.directresult)) { - event.finish(); - } - } - 'step 1'; - if (!event.directresult) { - if (result && result.bool && result.links[0]) { - event.directresult = result.links[0]; - } - else { - event.finish(); - return; - } - } - if (event.directresult) { - var cfg = player.storage[event.directresult]; - var source = cfg.source || player.name; - var name = event.directresult; - game.log(player, '调遣了随从', '#g' + name); - player.storage.subplayer = { - name: source, - name2: event.directresult, - hp: player.hp, - maxHp: player.maxHp, - skills: event.list.slice(0), - hs: player.getCards('h'), - es: player.getCards('e'), - intro2: cfg.intro2 - }; - player.removeSkill(event.list); - player.reinit(source, name, [cfg.hp, cfg.maxHp]); - player.addSkill('subplayer'); - player.lose(player.getCards('he'), ui.special)._triggered = null; - if (cfg.hs.length) player.directgain(cfg.hs); - if (cfg.es.length) player.directequip(cfg.es); - } - 'step 2'; - game.delay(); - }, - addExtraTarget: function () { - "step 0"; - event.num = 0; - "step 1"; - var target = targets[num], info = get.info(card); - if (target == event.target && event.addedTarget) { - event.addedTargets[num] = event.addedTarget; - event._result = { bool: false }; - } - else if (game.hasPlayer(function (current) { - return info.filterAddedTarget(card, player, current, target); - })) { - var next = player.chooseTarget(get.translation(event.card) + ':选择' + get.translation(targets[num]) + '对应的指向目标', function (card, player, target) { - var card = get.card(), info = get.info(card); - return info.filterAddedTarget(card, player, target, _status.event.preTarget); - }, true); - next.set('_get_card', card); - next.set('preTarget', targets[num]); - next.set('ai', target => get.effect(target, get.card(), player, _status.event.player)); - } - else { - event.addedTargets[num] = false; - event._result = { bool: false }; - } - "step 2"; - if (result.bool) { - event.addedTargets[num] = result.targets[0]; - player.line2([targets[num], result.targets[0]]); - } - event.num++; - if (event.num < targets.length) event.goto(1); - }, - reverseOrder: function () { - "step 0"; - game.delay(); - "step 1"; - var choice; - if (get.tag(card, 'multineg')) { - choice = (player.previous.side == player.side) ? '逆时针' : '顺时针'; - } - else { - choice = (player.next.side == player.side) ? '逆时针' : '顺时针'; - } - player.chooseControl('顺时针', '逆时针', function (event, player) { - return _status.event.choice || '逆时针'; - }).set('prompt', '选择' + get.translation(card) + '的结算方向').set('choice', choice).set('forceDie', true); - "step 2"; - if (result && result.control == '顺时针') { - var evt = event.getParent(), sorter = (_status.currentPhase || player); - evt.fixedSeat = true; - evt.targets.sortBySeat(sorter); - evt.targets.reverse(); - if (evt.targets[evt.targets.length - 1] == sorter) { - evt.targets.unshift(evt.targets.pop()); - } - } - }, - addJudgeCard: function () { - if (lib.filter.judge(card, player, target) && cards.length && get.position(cards[0], true) == 'o') target.addJudge(card, cards); - }, - equipCard: function () { - if (cards.length && get.position(cards[0], true) == 'o') target.equip(cards[0]); - }, - gameDraw: function () { - "step 0"; - if (_status.brawl && _status.brawl.noGameDraw) { - event.finish(); - return; - } - var end = player; - var numx = num; - do { - if (typeof num == 'function') { - numx = num(player); - } - if (player.getTopCards) player.directgain(player.getTopCards(numx)); - else player.directgain(get.cards(numx)); - if (player.singleHp === true && get.mode() != 'guozhan' && (lib.config.mode != 'doudizhu' || _status.mode != 'online')) { - player.doubleDraw(); - } - player._start_cards = player.getCards('h'); - player = player.next; - } - while (player != end); - event.changeCard = get.config('change_card'); - if (_status.connectMode || (lib.config.mode == 'doudizhu' && _status.mode == 'online') || lib.config.mode != 'identity' && lib.config.mode != 'guozhan' && lib.config.mode != 'doudizhu') { - event.changeCard = 'disabled'; - } - "step 1"; - if (event.changeCard != 'disabled' && !_status.auto) { - event.dialog = ui.create.dialog('是否使用手气卡?'); - ui.create.confirm('oc'); - event.custom.replace.confirm = function (bool) { - _status.event.bool = bool; - game.resume(); - }; - } - else { - event.finish(); - } - "step 2"; - if (event.changeCard == 'once') { - event.changeCard = 'disabled'; - } - else if (event.changeCard == 'twice') { - event.changeCard = 'once'; - } - else if (event.changeCard == 'disabled') { - event.bool = false; - return; - } - _status.imchoosing = true; - event.switchToAuto = function () { - _status.event.bool = false; - game.resume(); - }; - game.pause(); - "step 3"; - _status.imchoosing = false; - if (event.bool) { - if (game.changeCoin) { - game.changeCoin(-3); - } - var hs = game.me.getCards('h'); - game.addVideo('lose', game.me, [get.cardsInfo(hs), [], [], []]); - for (var i = 0; i < hs.length; i++) { - hs[i].discard(false); - } - game.me.directgain(get.cards(hs.length)); - event.goto(2); - } - else { - if (event.dialog) event.dialog.close(); - if (ui.confirm) ui.confirm.close(); - game.me._start_cards = game.me.getCards('h'); - event.finish(); - } - }, - phaseLoop: function () { - "step 0"; - var num = 1, current = player; - while (current.getSeatNum() == 0) { - current.setSeatNum(num); - current = current.next; - num++; - } - "step 1"; - for (var i = 0; i < lib.onphase.length; i++) { - lib.onphase[i](); - } - player.phase(); - "step 2"; - if (!game.players.includes(event.player.next)) { - event.player = game.findNext(event.player.next); - } - else { - event.player = event.player.next; - } - event.goto(1); - }, - loadPackage: function () { - 'step 0'; - if (event.packages.length) { - window.game = game; - var pack = event.packages.shift().split('/'); - lib.init.js(lib.assetURL + pack[0], pack[1], game.resume); - game.pause(); - } - else { - event.finish(); - } - 'step 1'; - if (!lib.config.dev) delete window.game; - var character = lib.imported.character; - var card = lib.imported.card; - var i, j, k; - for (i in character) { - if (character[i].character) { - var characterPack = lib.characterPack[i]; - if (characterPack) Object.assign(characterPack, character[i].character); - else lib.characterPack[i] = character[i].character; - } - if (character[i].forbid && character[i].forbid.includes(lib.config.mode)) continue; - if (character[i].mode && character[i].mode.includes(lib.config.mode) == false) continue; - - if (Array.isArray(lib[j]) && Array.isArray(character[i][j])) { - lib[j].addArray(character[i][j]); - continue; - } - for (j in character[i]) { - if (j == 'mode' || j == 'forbid' || j == 'characterSort') continue; - for (k in character[i][j]) { - if (j == 'character') { - if (!character[i][j][k][4]) { - character[i][j][k][4] = []; - } - if (character[i][j][k][4].includes('boss') || - character[i][j][k][4].includes('hiddenboss')) { - lib.config.forbidai.add(k); - } - if (lib.config.forbidai_user && lib.config.forbidai_user.includes(k)) { - lib.config.forbidai.add(k); - } - for (var l = 0; l < character[i][j][k][3].length; l++) { - lib.skilllist.add(character[i][j][k][3][l]); - } - } - if (j == 'translate' && k == i) { - lib[j][k + '_character_config'] = character[i][j][k]; - } - else { - if (lib[j][k] == undefined) { - Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(character[i][j], k)); - } - else if (Array.isArray(lib[j][k]) && Array.isArray(character[i][j][k])) { - lib[j][k].addArray(character[i][j][k]); - } - else { - console.log( - `dublicate ${j} in character ${i}:\n${k}:\nlib.${j}.${k}`, - lib[j][k], - `\ncharacter.${i}.${j}.${k}`, - character[i][j][k] - ); - } - } - } - } - } - for (i in card) { - var cardPack = lib.cardPack[i] ? lib.cardPack[i] : lib.cardPack[i] = []; - if (card[i].card) { - for (var j in card[i].card) { - if (!card[i].card[j].hidden && card[i].translate[j + '_info']) { - cardPack.push(j); - } - } - } - for (j in card[i]) { - if (j == 'mode' || j == 'forbid') continue; - if (j == 'list') continue; - for (k in card[i][j]) { - if (j == 'skill' && k[0] == '_' && !lib.config.cards.includes(i)) { - continue; - } - if (j == 'translate' && k == i) { - lib[j][k + '_card_config'] = card[i][j][k]; - } - else { - if (lib[j][k] == undefined) Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(card[i][j], k)); - else { - console.log( - `dublicate ${j} in card ${i}:\n${k}\nlib.${j}.${k}`, - lib[j][k], - `\ncard.${i}.${j}.${k}`, - card[i][j][k] - ); - } - } - } - } - } - event.goto(0); - }, - loadMode: function () { - 'step 0'; - window.game = game; - lib.init.js(lib.assetURL + 'mode', event.mode, game.resume); - game.pause(); - 'step 1'; - if (!lib.config.dev) delete window.game; - event.result = lib.imported.mode[event.mode]; - delete lib.imported.mode[event.mode]; - }, - forceOver: function () { - 'step 0'; - while (ui.controls.length) { - ui.controls[0].close(); - } - while (ui.dialogs.length) { - ui.dialogs[0].close(); - } - 'step 1'; - if (event.bool != 'noover') { - game.over(event.bool); - } - if (event.callback) { - event.callback(); - } - }, - arrangeTrigger: function () { - 'step 0'; - event.doing = event.doingList[0]; - if (event.doing && event.doing.todoList.length) return; - if (event.doingList.length) { - event.doingList.shift(); - return event.redo(); - } - event.finish(); - 'step 1'; - if (trigger.filterStop && trigger.filterStop()) return event.finish(); - event.current = event.doing.todoList.find(info => lib.filter.filterTrigger(trigger, info.player, event.triggername, info.skill)); - if (!event.current) { - event.doing.todoList = []; - return event.goto(0); - } - event.doing.todoList = event.doing.todoList.filter(i => i.priority <= event.current.priority); - - const directUse = info => lib.skill[info.skill].silent || !lib.translate[info.skill];//是否不触发同顺序选择 - if (directUse(event.current)) return event.goto(4); - event.choice = event.doing.todoList.filter(info => { - if (!lib.filter.filterTrigger(trigger, info.player, event.triggername, info.skill)) return false; - if (directUse(info)) return false; - if (event.current.player !== info.player) return false; - return lib.skill.global.includes(info.skill) || event.current.player.hasSkill(info.skill, true); - }); - if (event.choice.length < 2) return event.goto(4); - 'step 2'; - const next = event.choice[0].player.chooseControl(event.choice.map(i => i.skill)); - next.set('prompt', '选择下一个触发的技能'); - next.set('forceDie', true); - next.set('arrangeSkill', true); - next.set('includeOut', true); - 'step 3'; - if (result.control) event.current = event.doing.todoList.find(info => info.skill == result.control && info.player == event.choice[0].player); - 'step 4'; - if (!event.current || !event.doing.todoList.includes(event.current)) return; - event.doing.doneList.push(event.current); - event.doing.todoList.remove(event.current); - game.createTrigger(event.triggername, event.current.skill, event.current.player, trigger); - event.goto(0); - }, - createTrigger: function () { - "step 0"; - // console.log('triggering: ' + player.name+ ' \'s skill: ' + event.skill+' in ' + event.triggername) - if (game.expandSkills(player.getSkills().concat(lib.skill.global)).includes(event.skill)) return; - var info = get.info(event.skill); - let hidden = player.hiddenSkills.slice(0); - let invisible = player.invisibleSkills.slice(0); - game.expandSkills(hidden); - game.expandSkills(invisible); - if (hidden.includes(event.skill)) { - if (!info.silent && player.hasSkillTag('nomingzhi', false, null, true)) event.finish(); - else if (!info.direct) event.trigger('triggerHidden'); - else event.skillHidden = true; - } - else if (invisible.includes(event.skill)) event.trigger('triggerInvisible'); - else if (Object.keys(player.additionalSkills).every(i => { - if (i.startsWith('hidden:')) return true; - return !game.expandSkills(player.additionalSkills[i]).includes(event.skill); - })) event.finish(); - "step 1"; - if (event.cancelled) return event.finish(); - var info = get.info(event.skill); - if (event.revealed || info.forced) return; - const checkFrequent = function (info) { - if (player.hasSkillTag('nofrequent', false, event.skill)) return false; - if (typeof info.frequent == 'boolean') return info.frequent; - if (typeof info.frequent == 'function') return info.frequent(trigger, player); - if (info.frequent == 'check' && typeof info.check == 'function') return info.check(trigger, player); - return false; - }; - if (info.direct) { - if (player.isUnderControl()) game.swapPlayerAuto(player); - if (player.isOnline()) void 0; - event._result = { bool: true }; - event._direct = true; - } - else { - if (checkFrequent(info)) event.frequentSkill = true; - var str; - var check = info.check; - if (info.prompt) str = info.prompt; - else if (typeof info.logTarget == 'string') str = get.prompt(event.skill, trigger[info.logTarget], player); - else if (typeof info.logTarget == 'function') { - const logTarget = info.logTarget(trigger, player); - if (get.itemtype(logTarget).startsWith('player')) str = get.prompt(event.skill, logTarget, player); - } - else str = get.prompt(event.skill, null, player); - if (typeof str == 'function') str = str(trigger, player); - - var next = player.chooseBool(str); - if (event.frequentSkill) next.set('frequentSkill', event.skill); - next.set('forceDie', true); - next.set('includeOut', true); - next.ai = () => !check || check(trigger, player); - - if (typeof info.prompt2 == 'function') next.set('prompt2', info.prompt2(trigger, player)); - else if (typeof info.prompt2 == 'string') next.set('prompt2', info.prompt2); - else if (info.prompt2 != false) { - if (lib.dynamicTranslate[event.skill]) next.set('prompt2', lib.dynamicTranslate[event.skill](player, event.skill)); - else if (lib.translate[event.skill + '_info']) next.set('prompt2', lib.translate[event.skill + '_info']); - } - - if (trigger.skillwarn) { - if (next.prompt2) next.set('prompt2', '' + trigger.skillwarn + '。' + next.prompt2); - else next.set('prompt2', trigger.skillwarn); - } - } - "step 2"; - var info = get.info(event.skill); - if (!result || !result.bool) return; - var autodelay = info.autodelay; - if (typeof autodelay == 'function') autodelay = autodelay(trigger, player); - if (autodelay && (info.forced || !event.isMine())) { - if (typeof autodelay == 'number') game.delayx(autodelay); - else game.delayx(); - } - "step 3"; - var info = get.info(event.skill); - if (result && result.bool == false) { - if (info.oncancel) info.oncancel(trigger, player); - return event.finish(); - } - if (info.popup != false && !info.direct) { - if (info.popup) { - player.popup(info.popup); - game.log(player, '发动了', '【' + get.skillTranslation(event.skill, player) + '】'); - } - else if (!info.logTarget || info.logLine === false) player.logSkill(event.skill, false, info.line); - else if (typeof info.logTarget == 'string') player.logSkill(event.skill, trigger[info.logTarget], info.line); - else if (typeof info.logTarget == 'function') player.logSkill(event.skill, info.logTarget(trigger, player), info.line); - } - var next = game.createEvent(event.skill); - if (typeof info.usable == 'number') { - player.addSkill('counttrigger'); - if (!player.storage.counttrigger) player.storage.counttrigger = {}; - if (!player.storage.counttrigger[event.skill]) player.storage.counttrigger[event.skill] = 1; - else player.storage.counttrigger[event.skill]++; - } - next.player = player; - next._trigger = trigger; - next.triggername = event.triggername; - - if ("contents" in info && Array.isArray(info.contents)) { - next.setContents(info.contents); - } else { - next.setContent(info.content); - } - - next.skillHidden = event.skillHidden; - if (info.forceDie) next.forceDie = true; - if (info.forceOut) next.includeOut = true; - "step 4"; - if (!player._hookTrigger) return; - if (player._hookTrigger.some(i => { - const info = lib.skill[i].hookTrigger; - return info && info.after && info.after(event, player, event.triggername); - })) event.trigger('triggerAfter'); - }, - playVideoContent: function () { - 'step 0'; - game.delay(0, 500); - 'step 1'; - if (!game.chess) { - ui.control.innerHTML = ''; - var nodes = []; - for (var i = 0; i < ui.arena.childNodes.length; i++) { - nodes.push(ui.arena.childNodes[i]); - } - for (var i = 0; i < nodes.length; i++) { - if (nodes[i] == ui.canvas) continue; - if (nodes[i] == ui.control) continue; - if (nodes[i] == ui.mebg) continue; - if (nodes[i] == ui.me) continue; - if (nodes[i] == ui.roundmenu) continue; - nodes[i].remove(); - } - ui.sidebar.innerHTML = ''; - ui.cardPile.innerHTML = ''; - ui.discardPile.innerHTML = ''; - ui.special.innerHTML = ''; - ui.ordering.innerHTML = ''; - } - ui.system.firstChild.innerHTML = ''; - ui.system.lastChild.innerHTML = ''; - ui.system.firstChild.appendChild(ui.config2); - if (ui.updateVideoMenu) { - ui.updateVideoMenu(); - } - _status.videoDuration = 1; - ui.create.system('返回', function () { - var mode = localStorage.getItem(lib.configprefix + 'playbackmode'); - if (mode) { - game.saveConfig('mode', mode); - } - game.reload(); - }); - ui.create.system('重播', function () { - _status.replayvideo = true; - game.playVideo(_status.playback, lib.config.mode); - }); - ui.create.system('暂停', ui.click.pause, true).id = 'pausebutton'; - var slow = ui.create.system('减速', function () { - _status.videoDuration *= 1.5; - updateDuration(); - }, true); - var fast = ui.create.system('加速', function () { - _status.videoDuration /= 1.5; - updateDuration(); - }, true); - var updateDuration = function () { - if (_status.videoDuration > 1) { - slow.classList.add('glow'); - } - else { - slow.classList.remove('glow'); - } - if (_status.videoDuration < 1) { - fast.classList.add('glow'); - } - else { - fast.classList.remove('glow'); - } - }; - ui.system.style.display = ''; - ui.refresh(ui.system); - ui.system.show(); - ui.window.show(); - if (lib.config.mode != 'versus' && lib.config.mode != 'boss') { - ui.arena.style.display = ''; - ui.refresh(ui.arena); - ui.arena.show(); - } - if (!game.chess) { - game.playerMap = {}; - } - game.finishCards(); - 'step 2'; - if (event.video.length) { - var content = event.video.shift(); - // console.log(content); - if (content.type == 'delay') { - game.delay(content.content); - } - else if (content.type == 'play') { - window.play = {}; - if (!event.playtoload) { - event.playtoload = 1; - } - else { - event.playtoload++; - } - var script = lib.init.js(lib.assetURL + 'play', content.name); - script.addEventListener('load', function () { - var play = window.play[content.name]; - if (play && play.video) { - play.video(content.init); - } - event.playtoload--; - if (event.playtoload == 0) { - delete window.play; - } - }); - } - else if (typeof content.player == 'string' && game.playerMap[content.player] && - game.playerMap[content.player].classList && - !game.playerMap[content.player].classList.contains('obstacle')) { - game.videoContent[content.type](game.playerMap[content.player], content.content); - } - else { - game.videoContent[content.type](content.content); - } - if (event.video.length) { - game.delay(0, _status.videoDuration * Math.min(2000, event.video[0].delay)); - } - event.redo(); - } - else { - _status.over = true; - ui.system.lastChild.hide(); - setTimeout(function () { - ui.system.lastChild.innerHTML = ''; - }, 500); - } - }, - waitForPlayer: function () { - 'step 0'; - ui.auto.hide(); - ui.pause.hide(); - - game.createServer(); - if (!lib.translate.zhu) { - lib.translate.zhu = '主'; - } - if (event.func) { - event.func(); - } - if (!lib.configOL.number) { - lib.configOL.number = parseInt(lib.configOL.player_number); - } - if (game.onlineroom) { - game.send('server', 'config', lib.configOL); - } - - ui.create.connectPlayers(game.ip); - if (!window.isNonameServer) { - var me = game.connectPlayers[0]; - me.setIdentity('zhu'); - me.initOL(get.connectNickname(), lib.config.connect_avatar); - me.playerid = '1'; - game.onlinezhu = '1'; - } - _status.waitingForPlayer = true; - if (window.isNonameServer) { - document.querySelector('#server_status').innerHTML = '等待中'; - } - game.pause(); - 'step 1'; - _status.waitingForPlayer = false; - lib.configOL.gameStarted = true; - if (window.isNonameServer) { - document.querySelector('#server_status').innerHTML = '游戏中'; - } - if (game.onlineroom) { - game.send('server', 'config', lib.configOL); - } - for (var i = 0; i < game.connectPlayers.length; i++) { - game.connectPlayers[i].delete(); - } - delete game.connectPlayers; - if (ui.roomInfo) { - ui.roomInfo.remove(); - delete ui.roomInfo; - } - if (ui.exitroom) { - ui.exitroom.remove(); - delete ui.exitroom; - } - game.broadcast('gameStart'); - game.delay(2); - ui.auto.show(); - ui.pause.show(); - if (lib.config.show_cardpile) { - ui.cardPileButton.style.display = ''; - } - }, - replaceHandcards: function () { - 'step 0'; - if (event.players.includes(game.me)) { - game.me.chooseBool('是否置换手牌?'); - } - else { - event.finish(); - } - 'step 1'; - if (result && result.bool) { - var hs = game.me.getCards('h'); - for (var i = 0; i < hs.length; i++) { - hs[i].discard(false); - } - var cards = get.cards(hs.length); - game.me._start_cards = cards; - game.me.directgain(cards); - } - }, - replaceHandcardsOL: function () { - 'step 0'; - var send = function () { - game.me.chooseBool('是否置换手牌?'); - game.resume(); - }; - var sendback = function (result, player) { - if (result && result.bool) { - var hs = player.getCards('h'); - game.broadcastAll(function (player, hs) { - game.addVideo('lose', player, [get.cardsInfo(hs), [], [], []]); - for (var i = 0; i < hs.length; i++) { - hs[i].discard(false); - } - }, player, hs); - var cards = get.cards(hs.length); - player.directgain(cards); - player._start_cards = cards; - } - }; - for (var i = 0; i < event.players.length; i++) { - if (event.players[i].isOnline()) { - event.withol = true; - event.players[i].send(send); - event.players[i].wait(sendback); - } - else if (event.players[i] == game.me) { - event.withme = true; - game.me.chooseBool('是否置换手牌?'); - game.me.wait(sendback); - } - } - 'step 1'; - if (event.withme) { - game.me.unwait(result); - } - 'step 2'; - if (event.withol && !event.resultOL) { - game.pause(); - } - }, - /** - * @deprecated - */ - phase: function () { - 'step 0'; - //初始化阶段列表 - if (!event.phaseList) { - event.phaseList = ['phaseZhunbei', 'phaseJudge', 'phaseDraw', 'phaseUse', 'phaseDiscard', 'phaseJieshu']; - } - if (typeof event.num != 'number') { - event.num = 0; - } - //规则集中的“回合开始后①”,更新游戏轮数,触发“一轮游戏开始时” - var isRound = false; - if (!event.skill) { - isRound = _status.roundSkipped; - if (_status.isRoundFilter) { - isRound = _status.isRoundFilter(event, player); - } - else if (_status.seatNumSettled) { - var seatNum = player.getSeatNum(); - if (seatNum != 0) { - if (get.itemtype(_status.lastPhasedPlayer) != 'player' || seatNum < _status.lastPhasedPlayer.getSeatNum()) isRound = true; - _status.lastPhasedPlayer = player; - } - } - else if (player == _status.roundStart) isRound = true; - if (isRound) { - delete _status.roundSkipped; - game.roundNumber++; - event._roundStart = true; - game.updateRoundNumber(); - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isOut() && game.players[i].outCount > 0) { - game.players[i].outCount--; - if (game.players[i].outCount == 0 && !game.players[i].outSkills) { - game.players[i].in(); - } - } - } - event.trigger('roundStart'); - } - } - _status.globalHistory.push({ - cardMove: [], - custom: [], - useCard: [], - changeHp: [], - everything: [], - }); - var players = game.players.slice(0).concat(game.dead); - for (var i = 0; i < players.length; i++) { - var current = players[i]; - current.actionHistory.push({ useCard: [], respond: [], skipped: [], lose: [], gain: [], sourceDamage: [], damage: [], custom: [], useSkill: [] }); - current.stat.push({ card: {}, skill: {} }); - if (isRound) { - current.getHistory().isRound = true; - current.getStat().isRound = true; - } - } - if (isRound) { - game.getGlobalHistory().isRound = true; - } - 'step 1'; - //规则集中的“回合开始后②(1v1武将登场专用)” - event.trigger('phaseBeforeStart'); - 'step 2'; - //规则集中的“回合开始后③(处理“游戏开始时”的时机)” - event.trigger('phaseBefore'); - 'step 3'; - //规则集中的“回合开始后④(卑弥呼〖纵傀〗的时机)” - event.trigger('phaseBeforeEnd'); - 'step 4'; - //规则集中的“回合开始后⑤”,进行翻面检测 - if (player.isTurnedOver() && !event._noTurnOver) { - event.cancel(); - player.turnOver(); - player.phaseSkipped = true; - } - else { - player.phaseSkipped = false; - player.getHistory().isMe = true; - player.getStat().isMe = true; - } - 'step 5'; - //规则集中的“回合开始后⑥”,更新“当前回合角色” - while (ui.dialogs.length) { - ui.dialogs[0].close(); - } - game.phaseNumber++; - player.phaseNumber++; - game.broadcastAll(function (player, num, popup) { - if (lib.config.glow_phase) { - player.classList.add('glow_phase'); - } - player.phaseNumber = num; - _status.currentPhase = player; - if (popup && lib.config.show_phase_prompt) player.popup('回合开始', null, false); - }, player, player.phaseNumber, !player.noPhaseDelay); - _status.currentPhase = player; - _status.discarded = []; - game.syncState(); - game.addVideo('phaseChange', player); - if (game.phaseNumber == 1) { - delete player._start_cards; - if (lib.configOL.observe) { - lib.configOL.observeReady = true; - game.send('server', 'config', lib.configOL); - } - } - game.log(); - game.log(player, '的回合开始'); - player._noVibrate = true; - if (get.config('identity_mode') != 'zhong' && get.config('identity_mode') != 'purple' && !_status.connectMode) { - var num; - switch (get.config('auto_identity')) { - case 'one': num = 1; break; - case 'two': num = 2; break; - case 'three': num = 3; break; - case 'always': num = -1; break; - default: num = 0; break; - } - if (num && !_status.identityShown && game.phaseNumber > game.players.length * num && game.showIdentity) { - if (!_status.video) player.popup('显示身份'); - _status.identityShown = true; - game.showIdentity(false); - } - } - player.ai.tempIgnore = []; - if (ui.land && ui.land.player == player) { - game.addVideo('destroyLand'); - ui.land.destroy(); - } - 'step 6'; - //规则集中的“回合开始后⑦”,国战武将明置武将牌 - event.trigger('phaseBeginStart'); - 'step 7'; - //规则集中的“回合开始后⑨”,进行当先,化身等操作 - //没有⑧ 因为⑧用不到 - event.trigger('phaseBegin'); - //阶段部分 - 'step 8'; - if (num < event.phaseList.length) { - //规则集中没有的新时机 可以用来插入额外阶段啥的 - if (player.isIn()) event.trigger('phaseChange'); - } - else event.goto(11); - 'step 9'; - if (player.isIn() && num < event.phaseList.length) { - var phase = event.phaseList[num].split('|'); - event.currentPhase = phase[0]; - var next = player[event.currentPhase](); - next.phaseIndex = num; - if (phase.length > 1) { - next._extraPhaseReason = phase[1]; - } - if (event.currentPhase == 'phaseDraw' || event.currentPhase == 'phaseDiscard') { - if (!player.noPhaseDelay) { - if (player == game.me) { - game.delay(); - } - else { - game.delayx(); - } - } - } - } - 'step 10'; - if (event.currentPhase == 'phaseUse') { - game.broadcastAll(function () { - if (ui.tempnowuxie) { - ui.tempnowuxie.close(); - delete ui.tempnowuxie; - } - }); - delete player._noSkill; - } - event.num++; - 'step 11'; - if (event.num < event.phaseList.length) { - event.goto(8); - } - else if (!event._phaseEndTriggered) { - event._phaseEndTriggered = true; - event.trigger('phaseEnd'); - event.redo(); - } - 'step 12'; - event.trigger('phaseAfter'); - 'step 13'; - //删除当前回合角色 此时处于“不属于任何角色的回合”的阶段 - game.broadcastAll(function (player) { - player.classList.remove('glow_phase'); - delete _status.currentPhase; - }, player); - }, - /** - * @deprecated - */ - phase_old: function () { - "step 0"; - player.phaseZhunbei(); - "step 1"; - player.phaseJudge(); - "step 2"; - player.phaseDraw(); - if (!player.noPhaseDelay) { - if (player == game.me) { - game.delay(); - } - else { - game.delayx(); - } - } - "step 3"; - player.phaseUse(); - "step 4"; - game.broadcastAll(function () { - if (ui.tempnowuxie) { - ui.tempnowuxie.close(); - delete ui.tempnowuxie; - } - }); - player.phaseDiscard(); - if (!player.noPhaseDelay) game.delayx(); - //delete player.using; - delete player._noSkill; - "step 5"; - player.phaseJieshu(); - }, - phaseZhunbei: function () { - event.trigger(event.name); - game.log(player, '进入了准备阶段'); - }, - phaseJudge: function () { - "step 0"; - game.log(player, '进入了判定阶段'); - event.cards = player.getCards('j'); - if (!event.cards.length) event.finish(); - "step 1"; - if (cards.length && player.getCards('j').includes(cards[0])) { - event.card = cards.shift(); - if (event.card.classList.contains('removing')) { - event.card.remove(); - delete event.card; - event.redo(); - } - else if (event.card.classList.contains('feichu')) { - event.finish(); - return; - } - else { - player.lose(event.card, 'visible', ui.ordering); - player.$phaseJudge(event.card); - event.cancelled = false; - event.trigger('phaseJudge'); - var name = event.card.viewAs || event.card.name; - player.popup(name, 'thunder'); - if (!lib.card[name].effect) { - game.delay(); - event.redo(); - } - else if (!lib.card[name].judge) { - game.delay(); - event.nojudge = true; - } - } - } - else event.finish(); - "step 2"; - if (!event.cancelled && !event.nojudge) player.judge(event.card).set('type', 'phase'); - "step 3"; - var name = event.card.viewAs || event.card.name; - if (event.excluded) { - delete event.excluded; - } - else if (event.cancelled && !event.direct) { - if (lib.card[name].cancel) { - var next = game.createEvent(name + 'Cancel'); - next.setContent(lib.card[name].cancel); - next.cards = [event.card]; - if (!event.card.viewAs) next.card = get.autoViewAs(event.card); - else next.card = get.autoViewAs({ name: name }, next.cards); - next.player = player; - } - } - else { - var next = game.createEvent(name); - next.setContent(lib.card[name].effect); - next._result = result; - next.cards = [event.card]; - if (!event.card.viewAs) next.card = get.autoViewAs(event.card); - else next.card = get.autoViewAs({ name: name }, next.cards); - next.player = player; - } - ui.clear(); - event.goto(1); - }, - /** - * @deprecated - */ - phaseDraw: function () { - "step 0"; - game.log(player, '进入了摸牌阶段'); - event.trigger("phaseDrawBegin1"); - "step 1"; - event.trigger("phaseDrawBegin2"); - "step 2"; - if (game.modPhaseDraw) { - game.modPhaseDraw(player, event.num); - } - else { - if (event.num > 0) { - var num = event.num; - if (event.attachDraw) { - for (var i = 0; i < event.attachDraw.length; i++) { - ui.cardPile.insertBefore(event.attachDraw[i], ui.cardPile.firstChild); - } - num += event.attachDraw.length; - } - var next = player.draw(num); - if (event.attachDraw) { - next.minnum = event.attachDraw.length; - } - } - } - "step 3"; - if (Array.isArray(result)) { - event.cards = result; - } - }, - phaseUse: function () { - "step 0"; - if (!event.logged) { - game.log(player, '进入了出牌阶段'); - event.logged = true; - } - var next = player.chooseToUse(); - if (!lib.config.show_phaseuse_prompt) { - next.set('prompt', false); - } - next.set('type', 'phase'); - "step 1"; - if (result.bool && !event.skipped) { - event.goto(0); - } - game.broadcastAll(function () { - if (ui.tempnowuxie) { - ui.tempnowuxie.close(); - delete ui.tempnowuxie; - } - }); - "step 2"; - var stat = player.getStat(); - for (var i in stat.skill) { - var bool = false; - var info = lib.skill[i]; - if (!info) continue; - if (info.enable != undefined) { - if (typeof info.enable == 'string' && info.enable == 'phaseUse') bool = true; - else if (typeof info.enable == 'object' && info.enable.includes('phaseUse')) bool = true; - } - if (bool) stat.skill[i] = 0; - } - for (var i in stat.card) { - var bool = false; - var info = lib.card[i]; - if (!info) continue; - if (info.updateUsable == 'phaseUse') stat.card[i] = 0; - } - }, - phaseDiscard: function () { - "step 0"; - game.log(player, '进入了弃牌阶段'); - event.num = player.needsToDiscard(); - if (event.num <= 0) event.finish(); - else { - game.broadcastAll(function (player) { - if (lib.config.show_phase_prompt) { - player.popup('弃牌阶段', null, false); - } - }, player); - } - event.trigger('phaseDiscard'); - "step 1"; - player.chooseToDiscard(num, true) - .set('useCache', true); - "step 2"; - event.cards = result.cards; - }, - phaseJieshu: function () { - event.trigger(event.name); - game.log(player, '进入了结束阶段'); - }, - chooseToUse: function () { - "step 0"; - if (event.responded) return; - if (game.modeSwapPlayer && !_status.auto && player.isUnderControl() && !lib.filter.wuxieSwap(event)) { - game.modeSwapPlayer(player); - } - var skills = player.getSkills('invisible').concat(lib.skill.global); - game.expandSkills(skills); - for (var i = 0; i < skills.length; i++) { - var info = lib.skill[skills[i]]; - if (info && info.onChooseToUse) { - info.onChooseToUse(event); - } - } - if (_status.noclearcountdown !== 'direct') _status.noclearcountdown = true; - if (event.type == 'phase') { - if (event.isMine()) { - event.endButton = ui.create.control('结束回合', 'stayleft', function () { - var evt = _status.event; - if (evt.name != 'chooseToUse' || evt.type != 'phase') return; - if (evt.skill) { - ui.click.cancel(); - } - ui.click.cancel(); - }); - event.fakeforce = true; - } - else { - if (event.endButton) { - event.endButton.close(); - delete event.endButton; - } - event.fakeforce = false; - } - } - if (event.player.isUnderControl() && !_status.auto) { - event.result = { - bool: false - }; - return; - } - else if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - if (event.type == 'wuxie') { - if (ui.tempnowuxie) { - var triggerevent = event.getTrigger(); - if (triggerevent && triggerevent.targets && triggerevent.num == triggerevent.targets.length - 1) { - ui.tempnowuxie.close(); - } - } - if (lib.filter.wuxieSwap(event)) { - event.result = { - bool: false - }; - return; - } - } - var ok = game.check(); - if (!ok || !lib.config.auto_confirm) { - game.pause(); - if (lib.config.enable_vibrate && player._noVibrate) { - delete player._noVibrate; - game.vibrate(); - } - if (typeof event.prompt == 'string') { - if (event.openskilldialog) { - event.skillDialog = ui.create.dialog(event.openskilldialog); - delete event.openskilldialog; - event.dialog = event.prompt; - } - else { - event.dialog = ui.create.dialog(event.prompt); - if (event.prompt2) { - event.dialog.addText(event.prompt2); - } - } - } - else if (typeof event.prompt == 'function') { - event.dialog = ui.create.dialog(event.prompt(event)); - } - else if (event.prompt == undefined) { - var str; - if (typeof event.filterCard == 'object') { - var filter = event.filterCard; - str = '请使用' + get.cnNumber(event.selectCard[0]) + '张'; - if (filter.name) { - str += get.translation(filter.name); - } - else { - str += '牌'; - } - } - else { - str = '请选择要使用的牌'; - } - if (event.openskilldialog) { - event.skillDialog = ui.create.dialog(event.openskilldialog); - delete event.openskilldialog; - event.dialog = str; - } - else if (typeof event.skillDialog != 'string') { - event.dialog = ui.create.dialog(str); - } - else { - event.dialog = str; - } - } - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - var ok = game.check(); - if (ok) { - ui.click.ok(); - } - else if (ai.basic.chooseCard(event.ai1) || forced) { - if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - event._aiexcludeclear = true; - } - else { - if (!event.norestore) { - if (event.skill) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - var info = get.info(skill); - if (info.sourceSkill) { - event._aiexclude.add(info.sourceSkill); - } - } - else { - get.card(true).aiexclude(); - game.uncheck(); - } - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - } - else if (event.skill && !event.norestore) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - var info = get.info(skill); - if (info.sourceSkill) { - event._aiexclude.add(info.sourceSkill); - } - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - if (event.aidelay && event.result && event.result.bool) { - game.delayx(); - } - } - "step 2"; - if (event.endButton) { - event.endButton.close(); - delete event.endButton; - } - event.resume(); - if (event.result) { - if (event.result._sendskill) { - lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; - } - if (event.result.skill) { - var info = get.info(event.result.skill); - if (info && info.chooseButton) { - if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); - var dialog = info.chooseButton.dialog(event, player); - if (info.chooseButton.chooseControl) { - var next = player.chooseControl(info.chooseButton.chooseControl(event, player)); - if (dialog.direct) next.direct = true; - if (dialog.forceDirect) next.forceDirect = true; - next.dialog = dialog; - next.set('ai', info.chooseButton.check || function () { return 0; }); - if (event.id) next._parent_id = event.id; - next.type = 'chooseToUse_button'; - } - else { - var next = player.chooseButton(dialog); - if (dialog.direct) next.direct = true; - if (dialog.forceDirect) next.forceDirect = true; - next.set('ai', info.chooseButton.check || function () { return 1; }); - next.set('filterButton', info.chooseButton.filter || function () { return true; }); - next.set('selectButton', info.chooseButton.select || 1); - next.set('filterOk', info.chooseButton.filterOk || (() => true)); - if (event.id) next._parent_id = event.id; - next.type = 'chooseToUse_button'; - } - event.buttoned = event.result.skill; - } - else if (info && info.precontent && !game.online && !event.nouse) { - var next = game.createEvent('pre_' + event.result.skill); - next.setContent(info.precontent); - next.set('result', event.result); - next.set('player', player); - } - } - } - "step 3"; - if (event.buttoned) { - if (result.bool || result.control && result.control != 'cancel2') { - var info = get.info(event.buttoned).chooseButton; - lib.skill[event.buttoned + '_backup'] = info.backup(info.chooseControl ? result : result.links, player); - lib.skill[event.buttoned + '_backup'].sourceSkill = event.buttoned; - if (game.online) { - event._sendskill = [event.buttoned + '_backup', lib.skill[event.buttoned + '_backup']]; - } - else { - game.broadcast((skill, audio) => { - if (!lib.skill[skill]) lib.skill[skill] = {}; - lib.skill[skill].audio = audio; - }, event.buttoned + '_backup', lib.skill[event.buttoned + '_backup'].audio); - } - event.backup(event.buttoned + '_backup'); - if (info.prompt) { - event.openskilldialog = info.prompt(info.chooseControl ? result : result.links, player); - } - } - else { - ui.control.addTempClass('nozoom', 100); - event._aiexclude.add(event.buttoned); - } - event.goto(0); - delete event.buttoned; - } - "step 4"; - if (event._aiexcludeclear) { - delete event._aiexcludeclear; - event._aiexclude.length = 0; - } - delete _status.noclearcountdown; - if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { - event.skillDialog.close(); - } - if (event.result && event.result.bool && !game.online && !event.nouse) { - player.useResult(event.result, event); - } - else if (event._sendskill) { - event.result._sendskill = event._sendskill; - } - if ((!event.result || !event.result.bool || event.result._noHidingTimer) && (event.result.skill || event.logSkill)) { - var info = get.info(event.result.skill || event.logSkill); - if (info.direct && !info.clearTime) { - _status.noclearcountdown = 'direct'; - } - } - if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); - if (!_status.noclearcountdown) { - game.stopCountChoose(); - } - "step 5"; - if (event._result && event.result) { - event.result.result = event._result; - } - }, - chooseToRespond: function () { - "step 0"; - if (event.responded) { - delete event.dialog; - return; - } - var skills = player.getSkills('invisible').concat(lib.skill.global); - game.expandSkills(skills); - for (var i = 0; i < skills.length; i++) { - var info = lib.skill[skills[i]]; - if (info && info.onChooseToRespond) { - info.onChooseToRespond(event); - } - } - if (_status.noclearcountdown !== 'direct') _status.noclearcountdown = true; - if (!_status.connectMode && lib.config.skip_shan && event.autochoose && event.autochoose()) { - event.result = { bool: false }; - } - else { - if (game.modeSwapPlayer && !_status.auto && player.isUnderControl()) { - game.modeSwapPlayer(player); - } - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - var ok = game.check(); - if (!ok || !lib.config.auto_confirm) { - game.pause(); - if (event.openskilldialog) { - event.skillDialog = ui.create.dialog(event.openskilldialog); - delete event.openskilldialog; - event.dialog = event.prompt; - } - else { - if (event.prompt) event.dialog = ui.create.dialog(event.prompt); - if (event.prompt2) event.dialog.addText(event.prompt2); - } - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - var ok = game.check(); - if (ok) { - ui.click.ok(); - } - else if (ai.basic.chooseCard(event.ai1 || event.ai) || forced) { - if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - event._aiexcludeclear = true; - } - else { - if (!event.norestore) { - if (event.skill) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - var info = get.info(skill); - if (info.sourceSkill) { - event._aiexclude.add(info.sourceSkill); - } - } - else { - get.card(true).aiexclude(); - game.uncheck(); - } - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - } - else if (event.skill && !event.norestore) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - var info = get.info(skill); - if (info.sourceSkill) { - event._aiexclude.add(info.sourceSkill); - } - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - if (event.aidelay && event.result && event.result.bool) { - game.delayx(); - } - } - "step 2"; - event.resume(); - if (event.result) { - if (event.result._sendskill) { - lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; - } - if (event.result.skill) { - var info = get.info(event.result.skill); - if (info && info.chooseButton) { - if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); - var dialog = info.chooseButton.dialog(event, player); - if (info.chooseButton.chooseControl) { - var next = player.chooseControl(info.chooseButton.chooseControl(event, player)); - if (dialog.direct) next.direct = true; - if (dialog.forceDirect) next.forceDirect = true; - next.dialog = dialog; - next.set('ai', info.chooseButton.check || function () { return 0; }); - } - else { - var next = player.chooseButton(dialog); - if (dialog.direct) next.direct = true; - if (dialog.forceDirect) next.forceDirect = true; - next.set('ai', info.chooseButton.check || function () { return 1; }); - next.set('filterButton', info.chooseButton.filter || function () { return true; }); - next.set('selectButton', info.chooseButton.select || 1); - next.set('filterOk', info.chooseButton.filterOk || (() => true)); - } - event.buttoned = event.result.skill; - } - else if (info && info.precontent && !game.online) { - var next = game.createEvent('pre_' + event.result.skill); - next.setContent(info.precontent); - next.set('result', event.result); - next.set('player', player); - } - } - } - "step 3"; - if (event.buttoned) { - if (result.bool || result.control && result.control != 'cancel2') { - var info = get.info(event.buttoned).chooseButton; - lib.skill[event.buttoned + '_backup'] = info.backup(info.chooseControl ? result : result.links, player); - lib.skill[event.buttoned + '_backup'].sourceSkill = event.buttoned; - if (game.online) { - event._sendskill = [event.buttoned + '_backup', lib.skill[event.buttoned + '_backup']]; - } - else { - game.broadcast((skill, audio) => { - if (!lib.skill[skill]) lib.skill[skill] = {}; - lib.skill[skill].audio = audio; - }, event.buttoned + '_backup', lib.skill[event.buttoned + '_backup'].audio); - } - event.backup(event.buttoned + '_backup'); - if (info.prompt) { - event.openskilldialog = info.prompt(info.chooseControl ? result : result.links, player); - } - } - else { - ui.control.addTempClass('nozoom', 100); - event._aiexclude.add(event.buttoned); - } - event.goto(0); - delete event.buttoned; - } - "step 4"; - delete _status.noclearcountdown; - if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { - event.skillDialog.close(); - } - if (event.result.bool && !game.online) { - if (event.result._sendskill) { - lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; - } - var info = get.info(event.result.skill); - if (event.onresult) { - event.onresult(event.result); - } - if ((!event.result || !event.result.bool || event.result._noHidingTimer) && (event.result.skill || event.logSkill)) { - if (info.direct && !info.clearTime) { - _status.noclearcountdown = 'direct'; - } - } - if (event.logSkill) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - if (!event.result.card && event.result.skill) { - event.result.used = event.result.skill; - player.useSkill(event.result.skill, event.result.cards, event.result.targets); - } - else { - if (info && info.prerespond) { - info.prerespond(event.result, player); - } - var next = player.respond(event.result.cards, event.result.card, event.animate, event.result.skill, event.source); - if (event.result.noanimate) next.animate = false; - if (event.parent.card && event.parent.type == 'card') { - next.set('respondTo', [event.parent.player, event.parent.card]); - } - if (event.noOrdering) next.noOrdering = true; - } - } - else if (event._sendskill) { - event.result._sendskill = event._sendskill; - } - if (event.dialog && event.dialog.close) event.dialog.close(); - if (!_status.noclearcountdown) { - game.stopCountChoose(); - } - }, - chooseToGive: function () { - "step 0"; - event.result = { - bool: true, - confirm: 'ok', - buttons: [], - links: [], - cards: [], - targets: [], - }; - event.filterCard = (event => { - const filterCard = event.filterCard; - return function (card, player) { - if (!lib.filter.canBeGained(card, this.target, player)) return false; - return filterCard.call(this, card, player); - }; - })(event); - if (event.directresult) { - event.result.cards = event.directresult.slice(0); - event.goto(2); - return; - } - const directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectCard != 'function' && !event.complexCard); - const cards = directFilter ? player.getCards(event.position).filter(card => !card.classList.contains('uncheck') && lib.filter.cardAiIncluded(card) && event.filterCard(card, player)) : []; - const range = get.select(event.selectCard); - if (directFilter && (range[0] >= cards.length || range[1] <= -1)) { - if (player.isOut()) event.result.cards = []; - else event.result.cards = cards; - } - else if (event.isMine()) { - game.check(); - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - game.pause(); - if (range[1] > 1 && typeof event.selectCard != 'function') { - event.aiChoose = ui.create.control('AI代选', function () { - ai.basic.chooseCard(event.ai); - if (_status.event.custom && _status.event.custom.add.card) { - _status.event.custom.add.card(); - } - ui.selected.cards.forEach(i => i.updateTransform(true)); - }); - } - if (Array.isArray(event.dialog)) { - event.dialog = ui.create.dialog.apply(this, event.dialog); - event.dialog.open(); - event.dialog.classList.add('noselect'); - } - else if (event.prompt != false) { - let prompt; - if (typeof event.prompt == 'string') prompt = event.prompt; - else { - let select; - if (range[0] == range[1]) select = get.cnNumber(range[0]); - else if (range[1] == Infinity) select = '至少' + get.cnNumber(range[0]); - else select = get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - const position = event.position == 'h' ? '手' : event.position == 'e' ? '装备' : ''; - prompt = `请交给${get.translation(target)}${select}张${position}牌`; - } - event.dialog = ui.create.dialog(prompt); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - if (Array.isArray(event.promptx)) { - event.promptx.forEach(i => event.dialog.add(i)); - } - if (Array.isArray(event.selectCard)) { - event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); - event.custom.add.card = function () { - _status.event.promptbar.innerHTML = - ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); - }; - } - } - else if (get.itemtype(event.dialog) == 'dialog') { - event.dialog.style.display = ''; - event.dialog.open(); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - } - else if (event.skill) { - ui.click.cancel(); - event._aiexclude.add(event.skill); - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - "step 2"; - event.resume(); - if (event.aiChoose) event.aiChoose.close(); - if (event.glow_result && event.result.cards && !event.directresult) { - event.result.cards.forEach(i => i.classList.add('glow')); - } - if (event.dialog) event.dialog.close(); - "step 3"; - if (event.result.bool && event.result.cards && !game.online) { - event.cards = event.result.cards.slice(0); - if (event.logSkill) { - if (Array.isArray(event.logSkill)) player.logSkill(...event.logSkill); - else player.logSkill(event.logSkill); - } - if (event.autodelay && !event.isMine()) { - if (typeof event.autodelay == 'number') game.delayx(event.autodelay); - else game.delayx(); - } - } - else event.finish(); - "step 4"; - if (event.boolline) player.line(target, 'green'); - event.done = target.gain(event.cards, player); - event.done.giver = player; - if (event.delay !== false) event.done.animate = event.visibleMove ? 'give' : 'giveAuto'; - else { - target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); - if (event.visibleMove) event.done.visible = true; - } - }, - chooseToDiscard: function () { - "step 0"; - if (event.autochoose()) { - event.result = { - bool: true, - autochoose: true, - cards: player.getCards(event.position), - rawcards: player.getCards(event.position), - }; - for (var i = 0; i < event.result.cards.length; i++) { - if (!lib.filter.cardDiscardable(event.result.cards[i], player, event)) { - event.result.cards.splice(i--, 1); - } - } - } - else { - // &&!lib.filter.wuxieSwap(trigger) - if (game.modeSwapPlayer && !_status.auto && player.isUnderControl()) { - game.modeSwapPlayer(player); - } - event.rangecards = player.getCards(event.position); - for (var i = 0; i < event.rangecards.length; i++) { - if (lib.filter.cardDiscardable(event.rangecards[i], player, event)) { - event.rangecards.splice(i--, 1); - } - else { - event.rangecards[i].uncheck('chooseToDiscard'); - } - } - var range = get.select(event.selectCard); - if (event.isMine()) { - game.check(); - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - game.pause(); - if (range[1] > 1 && typeof event.selectCard != 'function') { - event.promptdiscard = ui.create.control('AI代选', function () { - ai.basic.chooseCard(event.ai); - if (_status.event.custom && _status.event.custom.add.card) { - _status.event.custom.add.card(); - } - for (var i = 0; i < ui.selected.cards.length; i++) { - ui.selected.cards[i].updateTransform(true); - } - }); - } - if (Array.isArray(event.dialog)) { - event.dialog = ui.create.dialog.apply(this, event.dialog); - event.dialog.open(); - event.dialog.classList.add('noselect'); - } - else if (event.prompt != false) { - var str; - if (typeof (event.prompt) == 'string') str = event.prompt; - else { - str = '请弃置'; - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '张'; - if (event.position == 'h' || event.position == undefined) str += '手'; - if (event.position == 'e') str += '装备'; - str += '牌'; - } - event.dialog = ui.create.dialog(str); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - if (Array.isArray(event.selectCard)) { - event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); - event.custom.add.card = function () { - _status.event.promptbar.innerHTML = - ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); - }; - } - } - else if (get.itemtype(event.dialog) == 'dialog') { - event.dialog.style.display = ''; - event.dialog.open(); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - } - else if (event.skill) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - if (event.rangecards) { - for (var i = 0; i < event.rangecards.length; i++) { - event.rangecards[i].recheck('chooseToDiscard'); - } - } - "step 2"; - event.resume(); - if (event.promptdiscard) { - event.promptdiscard.close(); - } - "step 3"; - if (event.result.bool && event.result.cards && event.result.cards.length && - !game.online && event.autodelay && !event.isMine()) { - if (typeof event.autodelay == 'number') { - game.delayx(event.autodelay); - } - else { - game.delayx(); - } - } - "step 4"; - if (event.logSkill && event.result.bool && !game.online) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - if (!game.online) { - if (typeof event.delay == 'boolean') { - event.done = player.discard(event.result.cards).set('delay', event.delay); - } - else { - event.done = player.discard(event.result.cards); - } - event.done.discarder = player; - } - if (event.dialog && event.dialog.close) event.dialog.close(); - }, - gaincardMultiple: function () { - 'step 0'; - event.type = 'gain'; - if (event.animate == 'give' || event.animate == 'gain2') event.visible = true; - if (player && cards) { - event._lose = true; - player.lose(cards, ui.special).set('type', 'gain').set('forceDie', true).set('getlx', false); - } - 'step 1'; - switch (event.animate) { - case 'draw': - game.delay(0, get.delayx(500, 500)); - for (var i of event.gain_list) { - if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; - if (event._lose) { - i[1] = i[1].filter(card => { - return !cards.includes(card) || !player.getCards('hejsx').includes(card); - }); - } - if (i[1].length > 0) i[0].$draw(i[1].length); - } - break; - case 'gain': - game.delay(0, get.delayx(700, 700)); - for (var i of event.gain_list) { - if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; - if (event._lose) { - i[1] = i[1].filter(card => { - return !cards.includes(card) || !player.getCards('hejsx').includes(card); - }); - } - if (i[1].length > 0) i[0].$gain(i[1].length); - } - break; - case 'gain2': case 'draw2': - game.delay(0, get.delayx(500, 500)); - for (var i of event.gain_list) { - if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; - if (event._lose) { - i[1] = i[1].filter(card => { - return !cards.includes(card) || !player.getCards('hejsx').includes(card); - }); - } - if (i[1].length > 0) i[0].$gain2(i[1]); - } - break; - case 'give': case 'giveAuto': - if (!player) break; - var evt = event.getl(player); - game.delay(0, get.delayx(500, 500)); - for (var i of event.gain_list) { - if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; - if (event._lose) { - i[1] = i[1].filter(card => { - return !cards.includes(card) || !player.getCards('hejsx').includes(card); - }); - } - var shown = i[1].slice(0), hidden = []; - if (event.animate == 'giveAuto') { - for (var card of i[1]) { - if (evt.hs.includes(card)) { - shown.remove(card); - hidden.push(card); - } - } - } - if (shown.length > 0) player.$give(shown, i[0]); - if (hidden.length > 0) player.$giveAuto(hidden, i[0]); - } - break; - default: - event.finish(); - } - for (var i of event.gain_list) { - if (i[1].length > 0) { - var next = i[0].gain(i[1]); - next.getlx = false; - if (event.visible) next.visible = true; - if (event.giver) next.giver = event.giver; - if (event.gaintag) next.gaintag.addArray(event.gaintag); - } - } - 'step 2'; - game.delayx(); - }, - discardMultiple: function () { - 'step 0'; - event.type = 'discard'; - event.visible = true; - if (!event.position) event.position = ui.discardPile; - var cards = []; - event.cards = cards; - for (var i = 0; i < event.lose_list.length; i++) { - var next = event.lose_list[i][0].lose(event.lose_list[i][1], event.position); - game.log(event.lose_list[i][0], '弃置了', event.lose_list[i][1]); - next.type = 'discard'; - next.animate = false; - next.delay = false; - cards.addArray(event.lose_list[i][1]); - next.getlx = false; - } - var evt = event; - if (evt.animate != false) { - evt.discardid = lib.status.videoId++; - game.broadcastAll(function (list, id, cards) { - for (var i of list) { - for (var j of i[1]) { - j.classList.remove('glow'); - j.classList.remove('glows'); - } - i[0].$throw(i[1], null, 'nobroadcast'); - } - var cardnodes = []; - cardnodes._discardtime = get.time(); - for (var ix of list) { - var card = ix[1]; - for (var i = 0; i < cards.length; i++) { - if (cards[i].clone) { - cardnodes.push(cards[i].clone); - } - } - } - ui.todiscard[id] = cardnodes; - }, event.lose_list, evt.discardid, cards); - if (lib.config.sync_speed && cards[0] && cards[0].clone) { - if (evt.delay != false) { - var waitingForTransition = get.time(); - evt.waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete evt.waitingForTransition; - }); - } - else if (evt.getParent().discardTransition) { - delete evt.getParent().discardTransition; - var waitingForTransition = get.time(); - evt.getParent().waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete evt.getParent().waitingForTransition; - }); - } - } - } - 'step 1'; - if (event.delay != false) { - if (event.waitingForTransition) { - _status.waitingForTransition = event.waitingForTransition; - game.pause(); - } - else { - game.delayx(); - } - } - }, - chooseToCompareLose: function () { - for (var i = 0; i < event.lose_list.length; i++) { - var next = event.lose_list[i][0].lose(event.lose_list[i][1], ui.ordering); - next.relatedEvent = event.getParent(); - next.getlx = false; - } - }, - chooseToCompareMeanwhile: function () { - 'step 0'; - if (player.countCards('h') == 0) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - for (var i = 0; i < targets.length; i++) { - if (targets[i].countCards('h') == 0) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - } - if (!event.multitarget) { - targets.sort(lib.sort.seat); - } - game.log(player, '对', targets, '发起了共同拼点'); - event.compareMeanwhile = true; - 'step 1'; - event._result = []; - event.list = targets.filter(function (current) { - return !event.fixedResult || !event.fixedResult[current.playerid]; - }); - if (event.list.length || !event.fixedResult || !event.fixedResult[player.playerid]) { - if (!event.fixedResult || !event.fixedResult[player.playerid]) event.list.unshift(player); - player.chooseCardOL(event.list, '请选择拼点牌', true).set('type', 'compare').set('ai', event.ai).set('source', player).aiCard = function (target) { - var hs = target.getCards('h'); - var event = _status.event; - event.player = target; - hs.sort(function (a, b) { - return event.ai(b) - event.ai(a); - }); - delete event.player; - return { bool: true, cards: [hs[0]] }; - }; - } - 'step 2'; - var cards = []; - var lose_list = []; - if (event.fixedResult && event.fixedResult[player.playerid]) { - event.list.unshift(player); - result.unshift({ bool: true, cards: [event.fixedResult[player.playerid]] }); - lose_list.push([player, [event.fixedResult[player.playerid]]]); - } - else { - if (result[0].skill && lib.skill[result[0].skill] && lib.skill[result[0].skill].onCompare) { - player.logSkill(result[0].skill); - result[0].cards = lib.skill[result[0].skill].onCompare(player); - } - else lose_list.push([player, result[0].cards]); - } - for (var j = 0; j < targets.length; j++) { - if (event.list.includes(targets[j])) { - var i = event.list.indexOf(targets[j]); - if (result[i].skill && lib.skill[result[i].skill] && lib.skill[result[i].skill].onCompare) { - event.list[i].logSkill(result[i].skill); - result[i].cards = lib.skill[result[i].skill].onCompare(event.list[i]); - } - else lose_list.push([targets[j], result[i].cards]); - cards.push(result[i].cards[0]); - } - else if (event.fixedResult && event.fixedResult[targets[j].playerid]) { - cards.push(event.fixedResult[targets[j].playerid]); - lose_list.push([targets[j], [event.fixedResult[targets[j].playerid]]]); - } - } - if (lose_list.length) { - game.loseAsync({ - lose_list: lose_list, - }).setContent('chooseToCompareLose'); - } - event.lose_list = lose_list; - event.getNum = function (card) { - for (var i of event.lose_list) { - if (i[1].contains && i[1].includes(card)) return get.number(card, i[0]); - } - return get.number(card, false); - }; - event.cardlist = cards; - event.cards = cards; - event.card1 = result[0].cards[0]; - event.num1 = event.getNum(event.card1); - event.iwhile = 0; - event.winner = null; - event.maxNum = -1; - event.tempplayer = event.player; - event.result = { - winner: null, - player: event.card1, - targets: event.cardlist.slice(0), - num1: [], - num2: [], - }; - 'step 3'; - event.trigger('compareCardShowBefore'); - 'step 4'; - player.$compareMultiple(event.card1, targets, cards); - game.log(player, '的拼点牌为', event.card1); - event.cardlist.forEach((card, index) => { - game.log(targets[index], '的拼点牌为', card); - }); - player.addTempClass('target'); - game.delay(0, 1000); - 'step 5'; - event.target = null; - event.trigger('compare'); - 'step 6'; - if (event.iwhile < targets.length) { - event.target = targets[event.iwhile]; - event.target.addTempClass('target'); - event.card2 = event.cardlist[event.iwhile]; - event.num2 = event.getNum(event.card2); - //event.tempplayer.line(event.target); - delete event.player; - event.trigger('compare'); - } - else { - game.delay(0, 1000); - event.goto(9); - } - 'step 7'; - event.result.num1[event.iwhile] = event.num1; - event.result.num2[event.iwhile] = event.num2; - var list = [[event.tempplayer, event.num1], [event.target, event.num2]]; - for (var i of list) { - if (i[1] > event.maxNum) { - event.maxNum = i[1]; - event.winner = i[0]; - } - else if (event.winner && i[1] == event.maxNum && i[0] != event.winner) { - event.winner = null; - } - } - 'step 8'; - event.iwhile++; - event.goto(6); - 'step 9'; - var player = event.tempplayer; - event.player = player; - delete event.tempplayer; - var str = '无人拼点成功'; - if (event.winner) { - event.result.winner = event.winner; - str = get.translation(event.winner) + '拼点成功'; - game.log(event.winner, '拼点成功'); - event.winner.popup('胜'); - } else game.log('#b无人', '拼点成功'); - var list = [player].addArray(targets); - list.remove(event.winner); - for (var i of list) { - i.popup('负'); - } - if (str) { - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - } - game.delay(3); - 'step 10'; - game.broadcastAll(ui.clear); - 'step 11'; - event.cards.add(event.card1); - }, - chooseToCompareMultiple: function () { - "step 0"; - if (player.countCards('h') == 0) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - for (var i = 0; i < targets.length; i++) { - if (targets[i].countCards('h') == 0) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - } - if (!event.multitarget) { - targets.sort(lib.sort.seat); - } - game.log(player, '对', targets, '发起拼点'); - "step 1"; - event._result = []; - event.list = targets.filter(function (current) { - return !event.fixedResult || !event.fixedResult[current.playerid]; - }); - if (event.list.length || !event.fixedResult || !event.fixedResult[player.playerid]) { - if (!event.fixedResult || !event.fixedResult[player.playerid]) event.list.unshift(player); - player.chooseCardOL(event.list, '请选择拼点牌', true).set('type', 'compare').set('ai', event.ai).set('source', player).aiCard = function (target) { - var hs = target.getCards('h'); - var event = _status.event; - event.player = target; - hs.sort(function (a, b) { - return event.ai(b) - event.ai(a); - }); - delete event.player; - return { bool: true, cards: [hs[0]] }; - }; - } - "step 2"; - var cards = []; - var lose_list = []; - if (event.fixedResult && event.fixedResult[player.playerid]) { - event.list.unshift(player); - result.unshift({ bool: true, cards: [event.fixedResult[player.playerid]] }); - lose_list.push([player, [event.fixedResult[player.playerid]]]); - } - else { - if (result[0].skill && lib.skill[result[0].skill] && lib.skill[result[0].skill].onCompare) { - player.logSkill(result[0].skill); - result[0].cards = lib.skill[result[0].skill].onCompare(player); - } - else lose_list.push([player, result[0].cards]); - } - for (var j = 0; j < targets.length; j++) { - if (event.list.includes(targets[j])) { - var i = event.list.indexOf(targets[j]); - if (result[i].skill && lib.skill[result[i].skill] && lib.skill[result[i].skill].onCompare) { - event.list[i].logSkill(result[i].skill); - result[i].cards = lib.skill[result[i].skill].onCompare(event.list[i]); - } - else lose_list.push([targets[j], result[i].cards]); - cards.push(result[i].cards[0]); - } - else if (event.fixedResult && event.fixedResult[targets[j].playerid]) { - cards.push(event.fixedResult[targets[j].playerid]); - lose_list.push([targets[j], [event.fixedResult[targets[j].playerid]]]); - } - } - if (lose_list.length) { - game.loseAsync({ - lose_list: lose_list, - }).setContent('chooseToCompareLose'); - } - event.lose_list = lose_list; - event.getNum = function (card) { - for (var i of event.lose_list) { - if (i[1].contains && i[1].includes(card)) return get.number(card, i[0]); - } - return get.number(card, false); - }; - event.cardlist = cards; - event.cards = cards; - event.card1 = result[0].cards[0]; - event.num1 = event.getNum(event.card1); - event.iwhile = 0; - event.result = { - player: event.card1, - targets: event.cardlist.slice(0), - num1: [], - num2: [], - }; - "step 3"; - event.trigger('compareCardShowBefore'); - "step 4"; - game.log(player, '的拼点牌为', event.card1); - "step 5"; - if (event.iwhile < targets.length) { - event.target = targets[event.iwhile]; - event.target.addTempClass('target'); - player.addTempClass('target'); - event.card2 = event.cardlist[event.iwhile]; - event.num2 = event.getNum(event.card2); - game.log(event.target, '的拼点牌为', event.card2); - player.line(event.target); - player.$compare(event.card1, event.target, event.card2); - event.trigger('compare'); - game.delay(0, 1500); - } - else { - event.goto(9); - } - "step 6"; - event.result.num1[event.iwhile] = event.num1; - event.result.num2[event.iwhile] = event.num2; - var str; - if (event.num1 > event.num2) { - str = get.translation(player) + '拼点成功'; - player.popup('胜'); - target.popup('负'); - } - else { - str = get.translation(player) + '拼点失败'; - if (event.num1 == event.num2) { - player.popup('平'); - target.popup('平'); - } - else { - player.popup('负'); - target.popup('胜'); - } - } - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - game.delay(2); - "step 7"; - if (event.callback) { - game.broadcastAll(function (card1, card2) { - if (card1.clone) card1.clone.style.opacity = 0.5; - if (card2.clone) card2.clone.style.opacity = 0.5; - }, event.card1, event.card2); - var next = game.createEvent('compareMultiple'); - next.player = player; - next.target = event.target; - next.card1 = event.card1; - next.card2 = event.card2; - next.num1 = event.num1; - next.num2 = event.num2; - next.setContent(event.callback); - event.compareMultiple = true; - } - "step 8"; - game.broadcastAll(ui.clear); - event.iwhile++; - event.goto(5); - "step 9"; - event.cards.add(event.card1); - }, - chooseToCompare: function () { - "step 0"; - if (((!event.fixedResult || !event.fixedResult[player.playerid]) && player.countCards('h') == 0) || ((!event.fixedResult || !event.fixedResult[target.playerid]) && target.countCards('h') == 0)) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - game.log(player, '对', target, '发起拼点'); - event.lose_list = []; - "step 1"; - var sendback = function () { - if (_status.event != event) { - return function () { - event.resultOL = _status.event.resultOL; - }; - } - }; - if (event.fixedResult && event.fixedResult[player.playerid]) { - event.card1 = event.fixedResult[player.playerid]; - event.lose_list.push([player, event.card1]); - } - else if (player.isOnline()) { - player.wait(sendback); - event.ol = true; - player.send(function (ai) { - game.me.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = ai; - game.resume(); - }, event.ai); - } - else { - event.localPlayer = true; - player.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = event.ai; - } - if (event.fixedResult && event.fixedResult[target.playerid]) { - event.card2 = event.fixedResult[target.playerid]; - event.lose_list.push([target, event.card2]); - } - else if (target.isOnline()) { - target.wait(sendback); - event.ol = true; - target.send(function (ai) { - game.me.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = ai; - game.resume(); - }, event.ai); - } - else { - event.localTarget = true; - } - "step 2"; - if (event.localPlayer) { - if (result.skill && lib.skill[result.skill] && lib.skill[result.skill].onCompare) { - result.cards = lib.skill[result.skill].onCompare(player); - player.logSkill(result.skill); - } - else event.lose_list.push([player, result.cards[0]]); - event.card1 = result.cards[0]; - } - if (event.localTarget) { - target.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = event.ai; - } - "step 3"; - if (event.localTarget) { - if (result.skill && lib.skill[result.skill] && lib.skill[result.skill].onCompare) { - target.logSkill(result.skill); - result.cards = lib.skill[result.skill].onCompare(target); - } - else event.lose_list.push([target, result.cards[0]]); - event.card2 = result.cards[0]; - } - if (!event.resultOL && event.ol) { - game.pause(); - } - "step 4"; - try { - if (!event.card1) { - if (event.resultOL[player.playerid].skill && lib.skill[event.resultOL[player.playerid].skill] && lib.skill[event.resultOL[player.playerid].skill].onCompare) { - player.logSkill(event.resultOL[player.playerid].skill); - event.resultOL[player.playerid].cards = lib.skill[event.resultOL[player.playerid].skill].onCompare(player); - } - else event.lose_list.push([player, event.resultOL[player.playerid].cards[0]]); - event.card1 = event.resultOL[player.playerid].cards[0]; - } - if (!event.card2) { - if (event.resultOL[target.playerid].skill && lib.skill[event.resultOL[target.playerid].skill] && lib.skill[event.resultOL[target.playerid].skill].onCompare) { - target.logSkill(event.resultOL[target.playerid].skill); - event.resultOL[target.playerid].cards = lib.skill[event.resultOL[target.playerid].skill].onCompare(player); - } - else event.lose_list.push([target, event.resultOL[target.playerid].cards[0]]); - event.card2 = event.resultOL[target.playerid].cards[0]; - } - if (!event.card1 || !event.card2) { - throw ('err'); - } - } - catch (e) { - console.log(e); - game.print(e); - event.finish(); - return; - } - if (event.card2.number >= 10 || event.card2.number <= 4) { - if (target.countCards('h') > 2) { - event.addToAI = true; - } - } - if (event.lose_list.length) { - game.loseAsync({ - lose_list: event.lose_list, - }).setContent('chooseToCompareLose'); - } - "step 5"; - event.trigger('compareCardShowBefore'); - "step 6"; - game.broadcast(function () { - ui.arena.classList.add('thrownhighlight'); - }); - ui.arena.classList.add('thrownhighlight'); - game.addVideo('thrownhighlight1'); - player.$compare(event.card1, target, event.card2); - game.log(player, '的拼点牌为', event.card1); - game.log(target, '的拼点牌为', event.card2); - var getNum = function (card) { - for (var i of event.lose_list) { - if (i[1] == card) return get.number(card, i[0]); - } - return get.number(card, false); - }; - event.num1 = getNum(event.card1); - event.num2 = getNum(event.card2); - event.trigger('compare'); - game.delay(0, 1500); - "step 7"; - event.result = { - player: event.card1, - target: event.card2, - num1: event.num1, - num2: event.num2 - }; - var str; - if (event.num1 > event.num2) { - event.result.bool = true; - event.result.winner = player; - str = get.translation(player) + '拼点成功'; - player.popup('胜'); - target.popup('负'); - } - else { - event.result.bool = false; - str = get.translation(player) + '拼点失败'; - if (event.num1 == event.num2) { - event.result.tie = true; - player.popup('平'); - target.popup('平'); - } - else { - event.result.winner = target; - player.popup('负'); - target.popup('胜'); - } - } - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - game.delay(2); - "step 8"; - if (typeof event.target.ai.shown == 'number' && event.target.ai.shown <= 0.85 && event.addToAI) { - event.target.ai.shown += 0.1; - } - game.broadcastAll(function () { - ui.arena.classList.remove('thrownhighlight'); - }); - game.addVideo('thrownhighlight2'); - if (event.clear !== false) { - game.broadcastAll(ui.clear); - } - if (typeof event.preserve == 'function') { - event.preserve = event.preserve(event.result); - } - else if (event.preserve == 'win') { - event.preserve = event.result.bool; - } - else if (event.preserve == 'lose') { - event.preserve = !event.result.bool; - } - }, - chooseSkill: function () { - 'step 0'; - var list; - if (typeof event.target == 'string') { - list = get.gainableSkillsName(event.target, event.func); - } - else { - list = event.target.getGainableSkills(event.func); - } - if (!list.length) { - event.finish(); - event.result = { bool: false }; - return; - } - event.skillai = function (list) { - return get.max(list, get.skillRank, 'item'); - }; - if (event.isMine()) { - var dialog = ui.create.dialog('forcebutton'); - dialog.add(event.prompt || '选择获得一项技能'); - _status.event.list = list; - var clickItem = function () { - _status.event._result = this.link; - game.resume(); - }; - for (i = 0; i < list.length; i++) { - if (lib.translate[list[i] + '_info']) { - var translation = get.translation(list[i]); - if (translation[0] == '新' && translation.length == 3) { - translation = translation.slice(1, 3); - } - else { - translation = translation.slice(0, 2); - } - var item = dialog.add(''); - item.firstChild.addEventListener('click', clickItem); - item.firstChild.link = list[i]; - } - } - dialog.add(ui.create.div('.placeholder')); - event.dialog = dialog; - event.switchToAuto = function () { - event._result = event.skillai(event.list); - game.resume(); - }; - _status.imchoosing = true; - game.pause(); - } - else { - event._result = event.skillai(list); - } - 'step 1'; - _status.imchoosing = false; - if (event.dialog) { - event.dialog.close(); - } - event.result = { bool: true, skill: result }; - }, - discoverCard: function () { - 'step 0'; - var num = event.num || 3; - var choice; - if (typeof event.list == 'string' || typeof event.list == 'function') { - choice = get.inpile(event.list).randomGets(num); - } - else if (Array.isArray(event.list)) { - choice = event.list.randomGets(num); - } - else { - choice = Array.from(event.list).randomGets(num); - } - if (choice.length) { - var prompt = event.prompt; - if (!prompt) { - prompt = '选择一张牌'; - if (event.use) { - prompt += '使用之'; - } - else if (!event.nogain) { - prompt += '获得之'; - } - } - if (typeof choice[0] === 'string') { - var next = player.chooseVCardButton(choice, prompt, event.forced); - if (event.ai) { - next.set('ai', event.ai); - } - } - else if (get.itemtype(choice[0]) == 'card') { - var next = player.chooseCardButton(choice, prompt, event.forced); - if (event.ai) { - next.set('ai', event.ai); - } - } - else { - event.finish(); - } - } - else { - event.finish(); - } - 'step 1'; - event.result = { - bool: result.bool, - card: null, - choice: null - }; - if (result.bool && result.links.length) { - var link = result.links[0]; - var togain = null; - if (get.itemtype(link) == 'card') { - event.result.card = link; - togain = link; - } - else if (Array.isArray(link)) { - event.result.choice = link[2]; - togain = game.createCard(link[2]); - } - if (togain) { - if (event.use) { - player.chooseUseTarget(togain); - } - else if (!event.nogain) { - player.gain(togain, 'draw'); - game.log(player, '获得了一张牌'); - } - } - } - }, - chooseButton: function () { - "step 0"; - if (typeof event.dialog == 'number') { - event.dialog = get.idDialog(event.dialog); - } - if (event.createDialog && !event.dialog) { - if (Array.isArray(event.createDialog)) { - event.createDialog.add('hidden'); - event.dialog = ui.create.dialog.apply(this, event.createDialog); - } - event.closeDialog = true; - } - if (event.dialog == undefined) event.dialog = ui.dialog; - if (event.isMine() || event.dialogdisplay) { - event.dialog.style.display = ''; - event.dialog.open(); - } - var filterButton = event.filterButton || function () { return true; }; - var selectButton = get.select(event.selectButton); - var buttons = event.dialog.buttons; - var buttonsx = []; - var num = 0; - for (var i = 0; i < buttons.length; i++) { - var button = buttons[i]; - if (filterButton(button, player)) { - num++; - buttonsx.add(button); - } - } - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - else if (event.direct && num == selectButton[0] || event.forceDirect) { - var buttons = buttonsx.slice(0, num); - event.result = { - bool: true, - button: [buttons], - links: get.links(buttons), - }; - event.dialog.close(); - } - else { - game.check(); - game.pause(); - } - } - else if (event.isOnline()) { - if (event.direct && num == 1 || event.forceDirect) { - var buttons = buttonsx.slice(0, num); - event.result = { - bool: true, - button: [buttons], - links: get.links(buttons), - }; - event.dialog.close(); - } - else { - event.send(); - } - delete event.callback; - } - else { - event.result = 'ai'; - } - if (event.onfree) { - lib.init.onfree(); - } - "step 1"; - if (event.result == 'ai') { - if (event.processAI) { - event.result = event.processAI(); - } - else { - game.check(); - if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); - else ui.click.cancel(); - } - } - if (event.closeDialog) { - event.dialog.close(); - } - if (event.callback) { - event.callback(event.player, event.result); - } - event.resume(); - }, - chooseCardOL: function () { - 'step 0'; - event.targets = event.list.slice(0); - if (!_status.connectMode) { - event.result = []; - event.goto(7); - } - else { - for (var i = 0; i < event.list.length; i++) { - var target = event.list[i]; - target.wait(); - if (target.isOnline()) { - target.send(function (args, set) { - game.me.chooseCard.apply(game.me, args).set(set); - game.resume(); - }, event._args, event._set); - event.list.splice(i--, 1); - } - else if (target == game.me) { - event.withme = true; - event.list.splice(i--, 1); - } - } - } - 'step 1'; - if (event.list.length) { - event.target = event.list.shift(); - event.target.chooseCard.apply(event.target, event._args).set(event._set); - } - else { - event.goto(3); - } - 'step 2'; - event.target.unwait(result); - event.goto(1); - 'step 3'; - if (event.withme) { - game.me.chooseCard.apply(game.me, event._args).set(event._set); - } - else { - event.goto(5); - } - 'step 4'; - game.me.unwait(result); - 'step 5'; - if (!event.resultOL) { - game.pause(); - } - 'step 6'; - event.result = []; - for (var i = 0; i < event.targets.length; i++) { - event.result[i] = event.resultOL[event.targets[i].playerid] || {}; - if (event.result[i] == 'ai' && event.aiCard) { - event.result[i] = event.aiCard(event.targets[i]); - } - } - event.finish(); - 'step 7'; - if (event.list.length) { - event.target = event.list.shift(); - event.target.chooseCard.apply(event.target, event._args).set(event._set); - } - else { - for (var i = 0; i < event.targets.length; i++) { - if (!event.result[i]) { - event.result[i] = {}; - } - } - event.finish(); - } - 'step 8'; - event.result[event.targets.indexOf(event.target)] = result; - event.goto(7); - }, - chooseButtonOL: function () { - 'step 0'; - //ui.arena.classList.add('markhidden'); - for (var i = 0; i < event.list.length; i++) { - var current = event.list[i]; - current[0].wait(); - if (current[0].isOnline()) { - var target = current.shift(); - target.send(function (args, callback, switchToAuto, processAI) { - //ui.arena.classList.add('markhidden'); - var next = game.me.chooseButton.apply(game.me, args); - next.callback = callback; - next.switchToAuto = switchToAuto; - next.processAI = processAI; - next.complexSelect = true; - game.resume(); - }, current, event.callback, event.switchToAuto, event.processAI); - target._choose_button_ol = current; - event.list.splice(i--, 1); - } - else if (current[0] == game.me) { - event.last = current; - event.last.shift(); - event.list.splice(i--, 1); - } - } - 'step 1'; - if (event.list.length) { - var current = event.list.shift(); - event.target = current.shift(); - var next = event.target.chooseButton.apply(event.target, current); - next.callback = event.callback; - next.switchToAuto = event.switchToAuto; - next.processAI = event.processAI; - } - else { - event.goto(3); - } - 'step 2'; - event.target.unwait(result); - event.goto(1); - 'step 3'; - if (event.last) { - var next = game.me.chooseButton.apply(game.me, event.last); - next.callback = event.callback; - next.switchToAuto = event.switchToAuto; - next.processAI = event.processAI; - } - else { - event.goto(5); - } - 'step 4'; - game.me.unwait(result); - 'step 5'; - if (!event.resultOL) { - game.pause(); - } - 'step 6'; - /*game.broadcastAll(function(){ - ui.arena.classList.remove('markhidden'); - });*/ - event.result = event.resultOL; - }, - chooseCard: function () { - "step 0"; - if (event.directresult) { - event.result = { - buttons: [], - cards: event.directresult.slice(0), - targets: [], - confirm: 'ok', - bool: true, - links: [] - }; - } - else { - if (event.isMine()) { - game.check(); - game.pause(); - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - if (event.prompt != false) { - var str; - if (typeof event.prompt == 'string') str = event.prompt; - else { - str = '请选择'; - var range = get.select(event.selectCard); - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '张'; - if (event.position == 'h' || event.position == undefined) str += '手'; - if (event.position == 'e') str += '装备'; - str += '牌'; - } - event.dialog = ui.create.dialog(str); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - if (Array.isArray(event.promptx)) { - for (var i = 0; i < event.promptx.length; i++) { - event.dialog.add(event.promptx[i]); - } - } - if (Array.isArray(event.selectCard)) { - event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); - event.custom.add.card = function () { - _status.event.promptbar.innerHTML = - ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); - }; - } - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - } - else if (event.skill) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - "step 2"; - event.resume(); - if (event.glow_result && event.result.cards && !event.directresult) { - for (var i = 0; i < event.result.cards.length; i++) { - event.result.cards[i].classList.add('glow'); - } - } - if (event.dialog) event.dialog.close(); - }, - chooseTarget: function () { - "step 0"; - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - game.check(); - game.pause(); - if (event.createDialog && !event.dialog && Array.isArray(event.createDialog)) { - event.dialog = ui.create.dialog.apply(this, event.createDialog); - } - else if (event.prompt != false) { - var str; - if (typeof event.prompt == 'string') str = event.prompt; - else { - str = '请选择'; - var range = get.select(event.selectTarget); - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '个目标'; - } - event.dialog = ui.create.dialog(str); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - if (event.promptbar != 'none') { - event.promptbar = event.dialog.add('0/' + get.numStr(get.select(event.selectTarget)[1], 'target')); - event.custom.add.target = function () { - _status.event.promptbar.innerHTML = - ui.selected.targets.length + '/' + get.numStr(get.select(event.selectTarget)[1], 'target'); - }; - } - } - else if (get.itemtype(event.dialog) == 'dialog') { - event.dialog.open(); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseTarget(event.ai) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - } - else { - ui.click.cancel(); - } - } - if (event.result.bool && event.animate !== false) { - for (var i = 0; i < event.result.targets.length; i++) { - event.result.targets[i].addTempClass('target'); - } - } - if (event.dialog) event.dialog.close(); - event.resume(); - "step 2"; - if (event.onresult) { - event.onresult(event.result); - } - if (event.result.bool && event.autodelay && !event.isMine()) { - if (typeof event.autodelay == 'number') { - game.delayx(event.autodelay); - } - else { - game.delayx(); - } - } - }, - chooseCardTarget: function () { - "step 0"; - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - game.check(); - game.pause(); - if (event.prompt != false) { - event.dialog = ui.create.dialog(event.prompt || '请选择卡牌和目标'); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if (ai.basic.chooseCard(event.ai1) || forced) { - if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - _status.event._aiexclude.length = 0; - } - else { - ui.click.cancel(); - } - } - else { - ui.click.cancel(); - } - } - "step 2"; - event.resume(); - if (event.result.bool && event.animate !== false) { - for (var i = 0; i < event.result.targets.length; i++) { - event.result.targets[i].addTempClass('target'); - } - } - if (event.dialog) event.dialog.close(); - }, - chooseControl: function () { - "step 0"; - if (event.controls.length == 0) { - if (event.sortcard) { - var sortnum = 2; - if (event.sorttop) { - sortnum = 1; - } - for (var i = 0; i < event.sortcard.length + sortnum; i++) { - event.controls.push(get.cnNumber(i, true)); - } - } - else if (event.choiceList) { - for (var i = 0; i < event.choiceList.length; i++) { - event.controls.push('选项' + get.cnNumber(i + 1, true)); - } - } - else { - event.finish(); - return; - } - } - else if (event.choiceList && event.controls.length == 1 && event.controls[0] == 'cancel2') { - event.controls.shift(); - for (var i = 0; i < event.choiceList.length; i++) { - event.controls.push('选项' + get.cnNumber(i + 1, true)); - } - event.controls.push('cancel2'); - } - if (event.isMine()) { - if (event.arrangeSkill) { - var hidden = player.hiddenSkills.slice(0); - game.expandSkills(hidden); - if (hidden.length) { - for (var i of event.controls) { - if (_status.prehidden_skills.includes(i) && hidden.includes(i)) { - event.result = { - bool: true, - control: i, - }; - return; - } - } - } - } - else if (event.hsskill && _status.prehidden_skills.includes(event.hsskill) && event.controls.includes('cancel2')) { - event.result = { - bool: true, - control: 'cancel2', - }; - return; - } - if (event.sortcard) { - var prompt = event.prompt || '选择一个位置'; - if (event.tosort) { - prompt += '放置' + get.translation(event.tosort); - } - event.dialog = ui.create.dialog(prompt, 'hidden'); - if (event.sortcard && event.sortcard.length) { - event.dialog.addSmall(event.sortcard); - } - else { - event.dialog.buttons = []; - event.dialog.add(ui.create.div('.buttons')); - } - var buttons = event.dialog.content.lastChild; - var sortnum = 2; - if (event.sorttop) { - sortnum = 1; - } - for (var i = 0; i < event.dialog.buttons.length + sortnum; i++) { - var item = ui.create.div('.button.card.pointerdiv.mebg'); - item.style.width = '50px'; - buttons.insertBefore(item, event.dialog.buttons[i]); - item.innerHTML = '
第' + get.cnNumber(i + 1, true) + '张
'; - if (i == event.dialog.buttons.length + 1) { - item.firstChild.innerHTML = '牌堆底'; - } - item.link = get.cnNumber(i, true); - item.listen(ui.click.dialogcontrol); - } - - event.dialog.forcebutton = true; - event.dialog.classList.add('forcebutton'); - event.dialog.open(); - } - else if (event.dialogcontrol) { - event.dialog = ui.create.dialog(event.prompt || '选择一项', 'hidden'); - for (var i = 0; i < event.controls.length; i++) { - var item = event.dialog.add(''); - item.firstChild.listen(ui.click.dialogcontrol); - item.firstChild.link = event.controls[i]; - } - event.dialog.forcebutton = true; - event.dialog.classList.add('forcebutton'); - if (event.addDialog) { - for (var i = 0; i < event.addDialog.length; i++) { - if (get.itemtype(event.addDialog[i]) == 'cards') { - event.dialog.addSmall(event.addDialog[i]); - } - else { - event.dialog.add(event.addDialog[i]); - } - } - event.dialog.add(ui.create.div('.placeholder.slim')); - } - event.dialog.open(); - } - else { - if (event.seperate || lib.config.seperate_control) { - var controls = event.controls.slice(0); - var num = 0; - controls.remove('cancel2'); - if (event.direct && controls.length == 1 || event.forceDirect) { - event.result = { - control: event.controls[0].link, - links: get.links([event.controls[0]]), - }; - return; - } - else { - event.controlbars = []; - for (var i = 0; i < event.controls.length; i++) { - event.controlbars.push(ui.create.control([event.controls[i]])); - } - } - } - else { - var controls = event.controls.slice(0); - var num = 0; - controls.remove('cancel2'); - if (event.direct && controls.length == 1 || event.forceDirect) { - event.result = { - control: event.controls[0].link, - links: get.links([event.controls[0]]), - }; - return; - } - event.controlbar = ui.create.control(event.controls); - } - if (event.dialog) { - if (Array.isArray(event.dialog)) { - event.dialog = ui.create.dialog.apply(this, event.dialog); - } - event.dialog.open(); - } - else if (event.choiceList) { - event.dialog = ui.create.dialog(event.prompt || '选择一项', 'hidden'); - event.dialog.forcebutton = true; - event.dialog.open(); - for (var i = 0; i < event.choiceList.length; i++) { - event.dialog.add(''); - } - } - else if (event.prompt) { - event.dialog = ui.create.dialog(event.prompt); - if (event.prompt2) { - event.dialog.addText(event.prompt2, Boolean(event.prompt2.length <= 20 || event.centerprompt2)); - } - } - } - game.pause(); - game.countChoose(); - event.choosing = true; - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - event.result = {}; - if (event.ai) { - var result = event.ai(event.getParent(), player); - if (typeof result == 'number') event.result.control = event.controls[result]; - else event.result.control = result; - } - else event.result.control = event.controls[event.choice]; - } - event.result.index = event.controls.indexOf(event.result.control); - event.choosing = false; - _status.imchoosing = false; - if (event.dialog && event.dialog.close) event.dialog.close(); - if (event.controlbar) event.controlbar.close(); - if (event.controlbars) { - for (var i = 0; i < event.controlbars.length; i++) { - event.controlbars[i].close(); - } - } - event.resume(); - }, - chooseBool: function () { - "step 0"; - if (event.isMine()) { - if (event.frequentSkill && !lib.config.autoskilllist.includes(event.frequentSkill)) { - ui.click.ok(); - return; - } - else if (event.hsskill && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - ui.create.confirm('oc'); - if (event.createDialog && !event.dialog) { - if (Array.isArray(event.createDialog)) { - event.dialog = ui.create.dialog.apply(this, event.createDialog); - if (event.dialogselectx) { - for (var i = 0; i < event.dialog.buttons.length; i++) { - event.dialog.buttons[i].classList.add('selectedx'); - } - } - } - } - if (event.dialog) { - event.dialog.open(); - } - else if (event.prompt) { - event.dialog = ui.create.dialog(event.prompt); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - } - game.pause(); - game.countChoose(); - event.choosing = true; - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - if (event.ai) { - event.choice = event.ai(event.getParent(), player); - } - event.result = { bool: event.choice }; - } - _status.imchoosing = false; - event.choosing = false; - if (event.dialog) event.dialog.close(); - event.resume(); - }, - chooseDrawRecover: function () { - 'step 0'; - if (player.isHealthy() && event.forced) { - player.draw(event.num1); - event.finish(); - return; - } - var controls = ['draw_card']; - if (player.isDamaged()) { - event.num2 = Math.min(event.num2, player.maxHp - player.hp); - controls.push('recover_hp'); - } - if (!event.forced) { - controls.push('cancel2'); - } - var prompt = event.prompt; - if (!prompt) { - if (player.isHealthy()) { - prompt = '是否摸' + get.cnNumber(event.num1) + '张牌?'; - } - else { - prompt = '摸' + get.cnNumber(event.num1) + '张牌或回复' + get.cnNumber(event.num2) + '点体力'; - } - } - var next = player.chooseControl(controls); - next.set('prompt', prompt); - if (event.hsskill) next.setHiddenSkill(event.hsskill); - if (event.ai) { - next.set('ai', event.ai); - } - else { - var choice; - if (player.isDamaged() && get.recoverEffect(player) > 0 && ( - player.hp == 1 || player.needsToDiscard() || - player.hasSkillTag('maixie_hp') || event.num2 > event.num1 || - (event.num2 == event.num1 && player.needsToDiscard(1)) - )) { - choice = 'recover_hp'; - } - else { - choice = 'draw_card'; - } - next.set('ai', function () { - return _status.event.choice; - }); - next.set('choice', choice); - } - 'step 1'; - if (result.control != 'cancel2') { - if (event.logSkill) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - if (result.control == 'draw_card') { - player.draw(event.num1); - } - else { - player.recover(event.num2); - } - } - event.result = result; - }, - choosePlayerCard: function () { - "step 0"; - if (!event.dialog) event.dialog = ui.create.dialog('hidden'); - else if (!event.isMine()) { - event.dialog.style.display = 'none'; - } - if (event.prompt) { - event.dialog.add(event.prompt); - } - else { - event.dialog.add('选择' + get.translation(target) + '的一张牌'); - } - if (event.prompt2) { - event.dialog.addText(event.prompt2); - } - var expand_length = 0; - var directh = (!lib.config.unauto_choose && !event.complexSelect); - for (var i = 0; i < event.position.length; i++) { - if (event.position[i] == 'h') { - var hs = target.getCards('h'); - if (hs.length) { - expand_length += Math.ceil(hs.length / 6); - var title = event.dialog.add('
手牌区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - hs.randomSort(); - if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { - event.dialog.add(hs); - directh = false; - } - else { - var shown = hs.filter(card => get.is.shownCard(card)); - if (shown.length) { - var hidden = hs.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else { - event.dialog.add([hs, 'blank']); - } - } - } - } - else if (event.position[i] == 'e') { - var es = target.getCards('e'); - if (es.length) { - expand_length += Math.ceil(es.length / 6); - var title = event.dialog.add('
装备区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(es); - directh = false; - } - } - else if (event.position[i] == 'j') { - var js = target.getCards('j'); - if (js.length) { - expand_length += Math.ceil(js.length / 6); - var title = event.dialog.add('
判定区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(js); - directh = false; - } - } - } - if (event.dialog.buttons.length == 0) { - event.finish(); - return; - } var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); - var cs = target.getCards(event.position); - var select = get.select(event.selectButton); - if (directFilter && select[0] >= cs.length) { - event.result = { - bool: true, - buttons: event.dialog.buttons, - links: cs - }; - } - else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { - event.result = { - bool: true, - buttons: event.dialog.buttons.randomGets(select[0]), - links: [] - }; - for (var i = 0; i < event.result.buttons.length; i++) { - event.result.links[i] = event.result.buttons[i].link; - } - } - else { - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - event.dialog.open(); - game.check(); - game.pause(); - if (expand_length > 2) { - ui.arena.classList.add('choose-player-card'); - event.dialog.classList.add('fullheight'); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); - else ui.click.cancel(); - } - event.dialog.close(); - if (event.result.links) { - event.result.cards = event.result.links.slice(0); - } - event.resume(); - setTimeout(function () { - ui.arena.classList.remove('choose-player-card'); - }, 500); - }, - discardPlayerCard: function () { - "step 0"; - if (event.directresult) { - event.result = { - buttons: [], - cards: event.directresult.slice(0), - links: event.directresult.slice(0), - targets: [], - confirm: 'ok', - bool: true - }; - event.cards = event.directresult.slice(0); - event.goto(2); - return; - } - if (!event.dialog) event.dialog = ui.create.dialog('hidden'); - else if (!event.isMine()) { - event.dialog.style.display = 'none'; - } - if (event.prompt == undefined) { - var str = '弃置' + get.translation(target); - var range = get.select(event.selectButton); - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '张'; - if (event.position == 'h' || event.position == undefined) str += '手'; - if (event.position == 'e') str += '装备'; - str += '牌'; - event.prompt = str; - } - if (event.prompt) { - event.dialog.add(event.prompt); - } - if (event.prompt2) { - event.dialog.addText(event.prompt2); - } - var directh = (!lib.config.unauto_choose && !event.complexSelect); - var expand_length = 0; - for (var i = 0; i < event.position.length; i++) { - if (event.position[i] == 'h') { - var hs = target.getDiscardableCards(player, 'h'); - expand_length += Math.ceil(hs.length / 6); - if (hs.length) { - var title = event.dialog.add('
手牌区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - hs.randomSort(); - if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { - event.dialog.add(hs); - directh = false; - } - else { - var shown = hs.filter(card => get.is.shownCard(card)); - if (shown.length) { - var hidden = hs.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else { - event.dialog.add([hs, 'blank']); - } - } - } - } - else if (event.position[i] == 'e') { - var es = target.getDiscardableCards(player, 'e'); - if (es.length) { - expand_length += Math.ceil(es.length / 6); - var title = event.dialog.add('
装备区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(es); - directh = false; - } - } - else if (event.position[i] == 'j') { - var js = target.getDiscardableCards(player, 'j'); - if (js.length) { - expand_length += Math.ceil(js.length / 6); - var title = event.dialog.add('
判定区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(js); - directh = false; - } - } - } - if (event.dialog.buttons.length == 0) { - event.finish(); - return; - } - var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); - var cs = target.getCards(event.position); - var select = get.select(event.selectButton); - if (directFilter && select[0] >= cs.length) { - event.result = { - bool: true, - buttons: event.dialog.buttons, - links: cs - }; - } - else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { - event.result = { - bool: true, - buttons: event.dialog.buttons.randomGets(select[0]), - links: [] - }; - for (var i = 0; i < event.result.buttons.length; i++) { - event.result.links[i] = event.result.buttons[i].link; - } - } - else { - if (event.isMine()) { - event.dialog.open(); - game.check(); - game.pause(); - if (expand_length > 2) { - ui.arena.classList.add('discard-player-card'); - event.dialog.classList.add('fullheight'); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); - else ui.click.cancel(); - } - event.dialog.close(); - "step 2"; - event.resume(); - setTimeout(function () { - ui.arena.classList.remove('discard-player-card'); - }, 500); - if (event.result.bool && event.result.links && !game.online) { - if (event.logSkill) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - var cards = []; - for (var i = 0; i < event.result.links.length; i++) { - cards.push(event.result.links[i]); - } - event.result.cards = event.result.links.slice(0); - event.cards = cards; - event.trigger("rewriteDiscardResult"); - } - "step 3"; - if (event.boolline) { - player.line(target, 'green'); - } - if (!event.chooseonly) { - var next = target.discard(event.cards); - if (player != target) next.notBySelf = true; - next.discarder = player; - event.done = next; - if (event.delay === false) { - next.set('delay', false); - } - } - }, - gainPlayerCard: function () { - "step 0"; - if (event.directresult) { - event.result = { - buttons: [], - cards: event.directresult.slice(0), - links: event.directresult.slice(0), - targets: [], - confirm: 'ok', - bool: true - }; - event.cards = event.directresult.slice(0); - event.goto(2); - return; - } - if (!event.dialog) event.dialog = ui.create.dialog('hidden'); - else if (!event.isMine()) { - event.dialog.style.display = 'none'; - } - if (event.prompt == undefined) { - var str = '获得' + get.translation(target); - var range = get.select(event.selectButton); - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '张'; - if (event.position == 'h' || event.position == undefined) str += '手'; - if (event.position == 'e') str += '装备'; - str += '牌'; - event.prompt = str; - } - if (event.prompt) { - event.dialog.add(event.prompt); - } - if (event.prompt2) { - event.dialog.addText(event.prompt2); - } - var expand_length = 0; - var directh = (!lib.config.unauto_choose && !event.complexSelect); - for (var i = 0; i < event.position.length; i++) { - if (event.position[i] == 'h') { - var hs = target.getGainableCards(player, 'h'); - if (hs.length) { - expand_length += Math.ceil(hs.length / 6); - var title = event.dialog.add('
手牌区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - hs.randomSort(); - if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { - event.dialog.add(hs); - directh = false; - } - else { - var shown = hs.filter(card => get.is.shownCard(card)); - if (shown.length) { - var hidden = hs.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else { - event.dialog.add([hs, 'blank']); - } - } - } - } - else if (event.position[i] == 'e') { - var es = target.getGainableCards(player, 'e'); - if (es.length) { - expand_length += Math.ceil(es.length / 6); - var title = event.dialog.add('
装备区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(es); - directh = false; - } - } - else if (event.position[i] == 'j') { - var js = target.getGainableCards(player, 'j'); - if (js.length) { - expand_length += Math.ceil(js.length / 6); - var title = event.dialog.add('
判定区
'); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(js); - directh = false; - } - } - } - if (event.dialog.buttons.length == 0) { - event.dialog.close(); - event.finish(); - return; - } - var cs = target.getCards(event.position); - var select = get.select(event.selectButton); - var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); - if (directFilter && select[0] >= cs.length) { - event.result = { - bool: true, - buttons: event.dialog.buttons, - links: cs - }; - } - else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { - event.result = { - bool: true, - buttons: event.dialog.buttons.randomGets(select[0]), - links: [] - }; - for (var i = 0; i < event.result.buttons.length; i++) { - event.result.links[i] = event.result.buttons[i].link; - } - } - else { - if (event.isMine()) { - event.dialog.open(); - game.check(); - game.pause(); - if (expand_length > 2) { - ui.arena.classList.add('gain-player-card'); - event.dialog.classList.add('fullheight'); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); - else ui.click.cancel(); - } - event.dialog.close(); - "step 2"; - event.resume(); - setTimeout(function () { - ui.arena.classList.remove('gain-player-card'); - }, 500); - if (game.online || !event.result.bool) { - event.finish(); - } - "step 3"; - if (event.logSkill && event.result.bool && !game.online) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - var cards = []; - for (var i = 0; i < event.result.links.length; i++) { - cards.push(event.result.links[i]); - } - event.result.cards = event.result.links.slice(0); - event.cards = cards; - event.trigger("rewriteGainResult"); - "step 4"; - if (event.boolline) { - player.line(target, 'green'); - } - if (!event.chooseonly) { - if (event.delay !== false) { - var next = player.gain(event.cards, target, event.visibleMove ? 'give' : 'giveAuto', 'bySelf'); - event.done = next; - } - else { - var next = player.gain(event.cards, target, 'bySelf'); - event.done = next; - target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); - if (event.visibleMove) next.visible = true; - } - } - else target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); - }, - showHandcards: function () { - "step 0"; - if (player.countCards('h') == 0) { - event.finish(); - return; - } - var cards = player.getCards('h'); - player.showCards(cards).setContent(function () { }); - var str = get.translation(player.name) + '的手牌'; - if (typeof event.prompt == 'string') { - str = event.prompt; - } - event.dialog = ui.create.dialog(str, cards); - event.dialogid = lib.status.videoId++; - event.dialog.videoId = event.dialogid; - game.broadcast(function (str, cards, id) { - ui.create.dialog(str, cards).videoId = id; - }, str, cards, event.dialogid); - game.log(player, '展示了', cards); - game.addVideo('showCards', player, [str, get.cardsInfo(cards)]); - game.delayx(2); - "step 1"; - game.broadcast('closeDialog', event.dialogid); - event.dialog.close(); - }, - showCards: function () { - "step 0"; - if (get.itemtype(cards) != 'cards') { - event.finish(); - return; - } - if (!event.str) { - event.str = get.translation(player.name) + '展示的牌'; - } - event.dialog = ui.create.dialog(event.str, cards); - event.dialogid = lib.status.videoId++; - event.dialog.videoId = event.dialogid; - - if (event.hiddencards) { - for (var i = 0; i < event.dialog.buttons.length; i++) { - if (event.hiddencards.includes(event.dialog.buttons[i].link)) { - event.dialog.buttons[i].className = 'button card'; - event.dialog.buttons[i].innerHTML = ''; - } - } - } - game.broadcast(function (str, cards, cards2, id) { - var dialog = ui.create.dialog(str, cards); - dialog.forcebutton = true; - dialog.videoId = id; - if (cards2) { - for (var i = 0; i < dialog.buttons.length; i++) { - if (cards2.includes(dialog.buttons[i].link)) { - dialog.buttons[i].className = 'button card'; - dialog.buttons[i].innerHTML = ''; - } - } - } - }, event.str, cards, event.hiddencards, event.dialogid); - if (event.hiddencards) { - var cards2 = cards.slice(0); - for (var i = 0; i < event.hiddencards.length; i++) { - cards2.remove(event.hiddencards[i]); - } - game.log(player, '展示了', cards2); - } - else { - game.log(player, '展示了', cards); - } - game.addCardKnower(cards, 'everyone'); - game.delayx(event.delay_time || 2.5); - game.addVideo('showCards', player, [event.str, get.cardsInfo(cards)]); - "step 1"; - game.broadcast('closeDialog', event.dialogid); - event.dialog.close(); - }, - viewCards: function () { - "step 0"; - game.addCardKnower(event.cards, player); - if (player == game.me) { - event.dialog = ui.create.dialog(event.str, event.cards); - if (event.isMine()) { - game.pause(); - ui.create.confirm('o'); - game.countChoose(); - event.choosing = true; - } - else { - event.finish(); - event.result = 'viewed'; - setTimeout(function () { - event.dialog.close(); - }, 2 * lib.config.duration); - game.delayx(2); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.finish(); - } - "step 1"; - event.result = 'viewed'; - _status.imchoosing = false; - event.choosing = false; - if (event.dialog) event.dialog.close(); - }, - moveCard: function () { - 'step 0'; - if (!player.canMoveCard(null, event.nojudge, event.sourceTargets, event.aimTargets, event.filter, event.canReplace ? 'canReplace' : 'noReplace')) { - event.finish(); - return; - } - var next = player.chooseTarget(2, function (card, player, target) { - var filterCard = get.event('filter'); - if (ui.selected.targets.length) { - if (!get.event('aimTargets').includes(target)) return false; - var from = ui.selected.targets[0]; - var js = from.getCards('j', filterCard); - for (var i = 0; i < js.length; i++) { - if (_status.event.nojudge) break; - if (target.canAddJudge(js[i])) return true; - } - if (target.isMin()) return false; - var es = from.getCards('e', filterCard); - for (var i = 0; i < es.length; i++) { - if (target.canEquip(es[i], _status.event.canReplace)) return true; - } - return false; - } - else { - if (!get.event('sourceTargets').includes(target)) return false; - var range = 'ej'; - if (_status.event.nojudge) range = 'e'; - return target.countCards(range, filterCard) > 0; - } - }); - next.set('nojudge', event.nojudge || false); - next.set('ai', function (target) { - var player = _status.event.player; - var att = get.attitude(player, target); - var sgnatt = get.sgn(att); - var aimTargets = get.event('aimTargets'), filterCard = get.event('filter'); - if (ui.selected.targets.length == 0) { - if (att > 0) { - if (!_status.event.nojudge && target.countCards('j', function (card) { - if (!filterCard(card)) return false; - return game.hasPlayer(function (current) { - if (!aimTargets.includes(current)) return false; - return current != target && current.canAddJudge(card) && get.attitude(player, current) < 0; - }); - })) return 14; - if (target.countCards('e', function (card) { - if (!filterCard(card)) return false; - return get.value(card, target) < 0 && game.hasPlayer(function (current) { - if (!aimTargets.includes(current)) return false; - return current != target && get.attitude(player, current) < 0 && current.canEquip(card, _status.event.canReplace) && get.effect(target, card, player, player) < 0; - }); - }) > 0) return 9; - } - else if (att < 0) { - if (game.hasPlayer(function (current) { - if (current != target && get.attitude(player, current) > 0) { - var es = target.getCards('e', filterCard); - for (var i = 0; i < es.length; i++) { - if (get.value(es[i], target) > 0 && current.canEquip(es[i], _status.event.canReplace) && get.effect(current, es[i], player, player) > (_status.event.canReplace ? get.effect(target, es[i], player, player) : 0)) return true; - } - } - })) { - return -att; - } - } - return 0; - } - var es = ui.selected.targets[0].getCards('e', filterCard); - var i; - var att2 = get.sgn(get.attitude(player, ui.selected.targets[0])); - for (i = 0; i < es.length; i++) { - if (sgnatt != 0 && att2 != 0 && sgnatt != att2 && - get.sgn(get.value(es[i], ui.selected.targets[0])) == -att2 && - get.sgn(get.effect(target, es[i], player, target)) == sgnatt && - target.canEquip(es[i], _status.event.canReplace)) { - return Math.abs(att); - } - } - if (i == es.length && (_status.event.nojudge || !ui.selected.targets[0].countCards('j', function (card) { - if (!filterCard(card)) return false; - return target.canAddJudge(card); - }) || att2 <= 0)) { - return 0; - } - return -att * att2; - }); - next.set('multitarget', true); - next.set('targetprompt', _status.event.targetprompt || ['被移走', '移动目标']); - next.set('prompt', event.prompt || '移动场上的一张牌'); - next.set('filter', event.filter); - next.set('sourceTargets', event.sourceTargets || game.filterPlayer()); - next.set('aimTargets', event.aimTargets || game.filterPlayer()); - next.set('canReplace', event.canReplace); - next.set('custom', get.copy(event.custom)); - if (event.prompt2) next.set('prompt2', event.prompt2); - if (event.forced) next.set('forced', true); - 'step 1'; - event.result = result; - if (result.bool) { - if (event.logSkill) player.logSkill(event.logSkill, result.targets, false); - player.line2(result.targets, 'green'); - event.targets = result.targets; - } - else { - event.finish(); - } - 'step 2'; - game.delay(); - 'step 3'; - if (targets.length == 2) { - player.choosePlayerCard('ej', true, function (button) { - var player = _status.event.player; - var targets0 = _status.event.targets0; - var targets1 = _status.event.targets1; - if (get.attitude(player, targets0) > 0 && get.attitude(player, targets1) < 0) { - if (get.position(button.link) == 'j') return 12; - if (get.value(button.link, targets0) < 0 && get.effect(targets1, button.link, player, targets1) > 0) return 10; - return 0; - } - else { - if (get.position(button.link) == 'j') return -10; - return get.value(button.link) * get.effect(targets1, button.link, player, targets1); - } - }, targets[0]).set('nojudge', event.nojudge || false).set('targets0', targets[0]).set('targets1', targets[1]).set('filterButton', function (button) { - var targets1 = _status.event.targets1; - if (!get.event('filter')(button.link)) return false; - if (get.position(button.link) == 'j') { - if (_status.event.nojudge) return false; - return targets1.canAddJudge(button.link); - } - else { - return targets1.canEquip(button.link, _status.event.canReplace); - } - }).set('filter', event.filter).set('canReplace', event.canReplace).set('custom', get.copy(event.custom)); - } - else { - event.finish(); - } - 'step 4'; - if (result.bool && result.links.length) { - var link = result.links[0]; - if (get.position(link) == 'e') { - event.targets[1].equip(link); - } - else if (link.viewAs) { - event.targets[1].addJudge({ name: link.viewAs }, [link]); - } - else { - event.targets[1].addJudge(link); - } - event.targets[0].$give(link, event.targets[1], false); - game.log(event.targets[0], '的', link, '被移动给了', event.targets[1]); - event.result.card = link; - event.result.position = get.position(link); - game.delay(); - } - }, - useCard: function () { - "step 0"; - if (!card) { - console.log('err: no card', get.translation(event.player)); - event.finish(); - return; - } - if (!get.info(card, false).noForceDie) event.forceDie = true; - if (cards.length) { - var owner = (get.owner(cards[0]) || player); - var next = owner.lose(cards, 'visible', ui.ordering).set('type', 'use'); - var directDiscard = []; - for (var i = 0; i < cards.length; i++) { - if (!next.cards.includes(cards[i])) { - directDiscard.push(cards[i]); - } - } - if (directDiscard.length) game.cardsGotoOrdering(directDiscard); - } - //player.using=cards; - var cardaudio = true; - if (event.skill) { - if (lib.skill[event.skill].audio) { - cardaudio = false; - } - if (lib.skill[event.skill].log != false) { - player.logSkill(event.skill); - } - if (get.info(event.skill).popname) { - player.tryCardAnimate(card, event.card.name, 'metal', true); - } - } - else if (!event.nopopup) { - if (lib.translate[event.card.name + '_pop']) { - player.tryCardAnimate(card, lib.translate[event.card.name + '_pop'], 'metal'); - } - else { - player.tryCardAnimate(card, event.card.name, 'metal'); - } - } - if (event.audio === false) { - cardaudio = false; - } - if (cardaudio) game.broadcastAll((player, card) => { - game.playCardAudio(card, player); - /* - if(!lib.config.background_audio||get.type(card)=='equip'&&!lib.config.equip_audio) return; - const sex=player.sex=='female'?'female':'male'; - var nature=get.natureList(card)[0]; - if(card.name=='sha'&&['fire','thunder','ice','stab'].includes(nature)){ - game.playAudio('card',sex,`${card.name}_${nature}`); - return; - } - const audio=lib.card[card.name].audio; - if(typeof audio=='string'){ - const audioInfo=audio.split(':'); - if(audio.startsWith('db:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,audioInfo[2],`${card.name}_${sex}.${audioInfo[3]||'mp3'}`); - else if(audio.startsWith('ext:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${card.name}_${sex}.${audioInfo[2]||'mp3'}`); - else game.playAudio('card',sex,`${audioInfo[0]}.${audioInfo[1]||'mp3'}`); - } - else game.playAudio('card',sex,card.name);*/ - }, player, card); - if (event.animate != false && event.line != false) { - if (card.name == 'wuxie' && event.getParent()._info_map) { - var evtmap = event.getParent()._info_map; - if (evtmap._source) evtmap = evtmap._source; - var lining = (evtmap.multitarget ? evtmap.targets : evtmap.target) || event.player; - if (Array.isArray(lining) && event.getTrigger().name == 'jiedao') { - player.line(lining[0], 'green'); - } - else { - player.line(lining, 'green'); - } - } - else if (card.name == 'youdishenru' && event.getParent().source) { - var lining = event.getParent().sourcex || event.getParent().source2 || event.getParent().source; - if (lining == player && event.getParent().sourcex2) { - lining = event.getParent().sourcex2; - } - if (Array.isArray(lining) && event.getTrigger().name == 'jiedao') { - player.line(lining[0], 'green'); - } - else { - player.line(lining, 'green'); - } - } - else { - var config = {}; - var nature = get.natureList(card)[0]; - if (nature || card.classList && card.classList.contains(nature)) config.color = nature; - if (event.addedTarget) { - player.line2(targets.concat(event.addedTargets), config); - } - else if (get.info(card, false).multitarget && targets.length > 1 && !get.info(card, false).multiline) { - player.line2(targets, config); - } - else { - player.line(targets, config); - } - } - if (event.throw !== false) player.$throw(cards); - if (lib.config.sync_speed && cards[0] && cards[0].clone) { - var waitingForTransition = get.time(); - event.waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete event.waitingForTransition; - }); - } - } - event.id = get.id(); - if (!Array.isArray(event.excluded)) event.excluded = []; - if (!Array.isArray(event.directHit)) event.directHit = []; - if (typeof event.customArgs != 'object' || typeof event.customArgs.default != 'object') event.customArgs = { default: {} }; - if (typeof event.baseDamage != 'number') event.baseDamage = get.info(card, false).baseDamage || 1; - if (typeof event.effectCount != 'number') event.effectCount = get.info(card, false).effectCount || 1; - event.effectedCount = 0; - if (event.oncard) { - event.oncard(event.card, event.player); - } - player.actionHistory[player.actionHistory.length - 1].useCard.push(event); - game.getGlobalHistory().useCard.push(event); - if (event.addCount !== false) { - if (player.stat[player.stat.length - 1].card[card.name] == undefined) { - player.stat[player.stat.length - 1].card[card.name] = 1; - } - else { - player.stat[player.stat.length - 1].card[card.name]++; - } - } - if (event.skill) { - if (player.stat[player.stat.length - 1].skill[event.skill] == undefined) { - player.stat[player.stat.length - 1].skill[event.skill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[event.skill]++; - } - var sourceSkill = get.info(event.skill).sourceSkill; - if (sourceSkill) { - if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { - player.stat[player.stat.length - 1].skill[sourceSkill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[sourceSkill]++; - } - } - } - if (targets.length) { - var str = (targets.length == 1 && targets[0] == player) ? '#b自己' : targets; - if (cards.length && !card.isCard) { - if (event.addedTarget) { - game.log(player, '对', str, '使用了', card, '(', cards, ',指向', event.addedTargets, ')'); - } - else { - game.log(player, '对', str, '使用了', card, '(', cards, ')'); - } - } - else { - if (event.addedTarget) { - game.log(player, '对', str, '使用了', card, '(指向', event.addedTargets, ')'); - } - else { - game.log(player, '对', str, '使用了', card); - } - } - } - else { - if (cards.length && !card.isCard) { - if (event.addedTarget) { - game.log(player, '使用了', card, '(', cards, ',指向', event.addedTargets, ')'); - } - else { - game.log(player, '使用了', card, '(', cards, ')'); - } - } - else { - if (event.addedTarget) { - game.log(player, '使用了', card, '(指向', event.addedTargets, ')'); - } - else { - game.log(player, '使用了', card); - } - } - } - if (card.name == 'wuxie') { - game.logv(player, [card, cards], [event.getTrigger().card]); - } - else { - game.logv(player, [card, cards], targets); - } - event.trigger('useCard1'); - "step 1"; - event.trigger('yingbian'); - "step 2"; - event.trigger('useCard2'); - "step 3"; - event.trigger('useCard'); - event._oncancel = function () { - game.broadcastAll(function (id) { - if (ui.tempnowuxie && ui.tempnowuxie._origin == id) { - ui.tempnowuxie.close(); - delete ui.tempnowuxie; - } - }, event.id); - }; - "step 4"; - event.sortTarget = function (animate, sort) { - var info = get.info(card, false); - if (num == 0 && targets.length > 1) { - if (!info.multitarget) { - if (!event.fixedSeat && !sort) { - targets.sortBySeat((_status.currentPhase || player)); - } - if (animate) for (var i = 0; i < targets.length; i++) { - targets[i].addTempClass('target'); - } - } - else if (animate) { - for (var i = 0; i < targets.length; i++) { - targets[i].addTempClass('target'); - } - } - } - }; - event.sortTarget(); - event.getTriggerTarget = function (list1, list2) { - var listx = list1.slice(0).sortBySeat((_status.currentPhase || player)); - for (var i = 0; i < listx.length; i++) { - if (get.numOf(list2, listx[i]) < get.numOf(listx, listx[i])) return listx[i]; - } - return null; - }; - "step 5"; - if (event.all_excluded) return; - if (!event.triggeredTargets1) event.triggeredTargets1 = []; - var target = event.getTriggerTarget(targets, event.triggeredTargets1); - if (target) { - event.triggeredTargets1.push(target); - var next = game.createEvent('useCardToPlayer', false); - if (!event.isFirstTarget1) { - event.isFirstTarget1 = true; - next.isFirstTarget = true; - } - next.setContent('emptyEvent'); - next.targets = targets; - next.target = target; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.excluded = event.excluded; - next.directHit = event.directHit; - next.customArgs = event.customArgs; - if (event.forceDie) next.forceDie = true; - event.redo(); - } - "step 6"; - if (event.all_excluded) return; - if (!event.triggeredTargets2) event.triggeredTargets2 = []; - var target = event.getTriggerTarget(targets, event.triggeredTargets2); - if (target) { - event.triggeredTargets2.push(target); - var next = game.createEvent('useCardToTarget', false); - if (!event.isFirstTarget2) { - event.isFirstTarget2 = true; - next.isFirstTarget = true; - } - next.setContent('emptyEvent'); - next.targets = targets; - next.target = target; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.excluded = event.excluded; - next.directHit = event.directHit; - next.customArgs = event.customArgs; - if (event.forceDie) next.forceDie = true; - event.redo(); - } - "step 7"; - var info = get.info(card, false); - if (!info.nodelay && event.animate != false) { - if (event.delayx !== false) { - if (event.waitingForTransition) { - _status.waitingForTransition = event.waitingForTransition; - game.pause(); - } - else { - game.delayx(); - } - } - } - "step 8"; - if (event.all_excluded) return; - if (!event.triggeredTargets3) event.triggeredTargets3 = []; - var target = event.getTriggerTarget(targets, event.triggeredTargets3); - if (target) { - event.triggeredTargets3.push(target); - var next = game.createEvent('useCardToPlayered', false); - if (!event.isFirstTarget3) { - event.isFirstTarget3 = true; - next.isFirstTarget = true; - } - next.setContent('emptyEvent'); - next.targets = targets; - next.target = target; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.excluded = event.excluded; - next.directHit = event.directHit; - next.customArgs = event.customArgs; - if (event.forceDie) next.forceDie = true; - event.redo(); - } - "step 9"; - if (event.all_excluded) return; - if (!event.triggeredTargets4) event.triggeredTargets4 = []; - var target = event.getTriggerTarget(targets, event.triggeredTargets4); - if (target) { - event.triggeredTargets4.push(target); - var next = game.createEvent('useCardToTargeted', false); - if (!event.isFirstTarget4) { - event.isFirstTarget4 = true; - next.isFirstTarget = true; - } - next.setContent('emptyEvent'); - next.targets = targets; - next.target = target; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.excluded = event.excluded; - next.directHit = event.directHit; - next.customArgs = event.customArgs; - if (event.forceDie) next.forceDie = true; - if (targets.length == event.triggeredTargets4.length) { - event.sortTarget(); - } - event.redo(); - } - "step 10"; - if (event.all_excluded) return; - event.effectedCount++; - event.num = 0; - var info = get.info(card, false); - if (info.contentBefore) { - var next = game.createEvent(card.name + 'ContentBefore'); - next.setContent(info.contentBefore); - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.type = 'precard'; - if (event.forceDie) next.forceDie = true; - } - else if (info.reverseOrder && get.is.versus() && targets.length > 1) { - var next = game.createEvent(card.name + 'ContentBefore'); - next.setContent('reverseOrder'); - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.type = 'precard'; - if (event.forceDie) next.forceDie = true; - } - else if (info.singleCard && info.filterAddedTarget && event.addedTargets && event.addedTargets.length < targets.length) { - var next = game.createEvent(card.name + 'ContentBefore'); - next.setContent('addExtraTarget'); - next.target = target; - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.type = 'precard'; - next.addedTarget = event.addedTarget; - next.addedTargets = event.addedTargets; - if (event.forceDie) next.forceDie = true; - } - "step 11"; - if (event.all_excluded) return; - var info = get.info(card, false); - if (num == 0 && targets.length > 1) { - event.sortTarget(true, true); - } - if (targets[num] && targets[num].isDead()) return; - if (targets[num] && targets[num].isOut()) return; - if (targets[num] && targets[num].removed) return; - if (targets[num] && info.ignoreTarget && info.ignoreTarget(card, player, targets[num])) return; - if (targets.length == 0 && !info.notarget) return; - if (targets[num] && event.excluded.includes(targets[num])) { - var next = game.createEvent('useCardToExcluded', false); - next.setContent('emptyEvent'); - next.targets = targets; - next.target = targets[num]; - next.num = num; - next.card = card; - next.cards = cards; - next.player = player; - return; - } - var next = game.createEvent(card.name); - next.setContent(info.content); - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.num = num; - next.type = 'card'; - next.skill = event.skill; - next.multitarget = info.multitarget; - next.preResult = event.preResult; - next.baseDamage = event.baseDamage; - if (event.forceDie) next.forceDie = true; - if (event.addedTargets) { - next.addedTargets = event.addedTargets; - next.addedTarget = event.addedTargets[num]; - next._targets = event._targets; - } - if (info.targetDelay === false) { - event.targetDelay = false; - } - next.target = targets[num]; - for (var i in event.customArgs.default) next[i] = event.customArgs.default[i]; - if (next.target && event.customArgs[next.target.playerid]) { - var customArgs = event.customArgs[next.target.playerid]; - for (var i in customArgs) next[i] = customArgs[i]; - } - if (next.target && event.directHit.includes(next.target)) next.directHit = true; - if (next.target && !info.multitarget) { - if (num == 0 && targets.length > 1) { - // var ttt=next.target; - // setTimeout(function(){ttt.addTempClass('target');},0.5*lib.config.duration); - } - else { - next.target.addTempClass('target'); - } - } - if (!info.nodelay && num > 0) { - if (event.targetDelay !== false) { - game.delayx(0.5); - } - } - "step 12"; - if (event.all_excluded) return; - if (!get.info(event.card, false).multitarget && num < targets.length - 1 && !event.cancelled) { - event.num++; - event.goto(11); - } - "step 13"; - if (event.all_excluded) return; - if (get.info(card, false).contentAfter) { - var next = game.createEvent(card.name + 'ContentAfter'); - next.setContent(get.info(card, false).contentAfter); - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.preResult = event.preResult; - next.type = 'postcard'; - if (event.forceDie) next.forceDie = true; - } - "step 14"; - if (event.all_excluded) return; - if (event.effectedCount < event.effectCount) { - if (document.getElementsByClassName('thrown').length) { - if (event.delayx !== false && get.info(event.card, false).finalDelay !== false) game.delayx(); - } - event.goto(10); - } - "step 15"; - if (event.postAi) { - event.player.logAi(event.targets, event.card); - } - if (event._result) { - event.result = event._result; - } - //delete player.using; - if (document.getElementsByClassName('thrown').length) { - if (event.delayx !== false && get.info(event.card, false).finalDelay !== false) game.delayx(); - } - else { - event.finish(); - } - "step 16"; - event._oncancel(); - }, - useSkill: function () { - "step 0"; - var info = get.info(event.skill); - if (!info.noForceDie) event.forceDie = true; - if (!info.noForceOut) event.includeOut = true; - event._skill = event.skill; - game.trySkillAudio(event.skill, player); - var checkShow = player.checkShow(event.skill); - if (info.discard != false && info.lose != false && !info.viewAs) { - player.discard(cards).delay = false; - if (lib.config.low_performance) { - event.discardTransition = true; - } - } - else { - if (info.lose != false) { - if (info.losetrigger == false) { - var losecard = player.lose(cards, ui.special)._triggered = null; - } - else { - var losecard = player.lose(cards, ui.special); - if (info.visible) losecard.visible = true; - if (info.loseTo) losecard.position = ui[info.loseTo]; - if (info.insert) losecard.insert_card = true; - if (losecard.position == ui.special && info.toStorage) losecard.toStorage = true; - } - } - if (!info.prepare && info.viewAs) { - player.$throw(cards); - if (losecard) losecard.visible = true; - if (lib.config.sync_speed && cards[0] && cards[0].clone) { - var waitingForTransition = get.time(); - event.waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete event.waitingForTransition; - }); - } - } - } - if (info.line != false && targets.length) { - var config = {}; - if (get.is.object(info.line)) config = info.line; - else if (info.line == 'fire') { - config.color = 'fire'; - } - else if (info.line == 'thunder') { - config.color = 'thunder'; - } - else if (info.line === undefined || info.line == 'green') { - config.color = 'green'; - } - if (info.multitarget && !info.multiline && targets.length > 1) { - player.line2(targets, config); - } - else { - player.line(targets, config); - } - } - var str = ''; - if (targets && targets.length && info.log != 'notarget') { - str += '对' + (targets[0] == player ? '自己' : get.translation(targets[0])); - for (var i = 1; i < targets.length; i++) { - str += '、' + (targets[i] == player ? '自己' : get.translation(targets[i])); - } - str += ''; - } - str += '发动了'; - if (!info.direct && info.log !== false) { - game.log(player, str, '【' + get.skillTranslation(skill, player) + '】'); - if (info.logv !== false) game.logv(player, skill, targets); - player.trySkillAnimate(skill, skill, checkShow); - } - if (event.addCount != false) { - if (player.stat[player.stat.length - 1].skill[skill] == undefined) { - player.stat[player.stat.length - 1].skill[skill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[skill]++; - } - var sourceSkill = get.info(skill).sourceSkill; - if (sourceSkill) { - if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { - player.stat[player.stat.length - 1].skill[sourceSkill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[sourceSkill]++; - } - } - } - if (player.stat[player.stat.length - 1].allSkills == undefined) { - player.stat[player.stat.length - 1].allSkills = 1; - } - else { - player.stat[player.stat.length - 1].allSkills++; - } - if (info.prepare) { - switch (info.prepare) { - case 'give': if (losecard) losecard.visible = true; player.$give(cards, targets[0]); break; - case 'give2': player.$give(cards.length, targets[0]); break; - case 'throw': if (losecard) losecard.visible = true; player.$throw(cards); break; - case 'throw2': player.$throw(cards.length); break; - default: info.prepare(cards, player, targets); - } - } - if (info.round) { - var roundname = skill + '_roundcount'; - player.storage[roundname] = game.roundNumber; - player.syncStorage(roundname); - player.markSkill(roundname); - } - var name = event.skill; - var players = player.getSkills(false, false, false); - var equips = player.getSkills('e'); - var global = lib.skill.global.slice(0); - var logInfo = { - skill: name, - targets: targets, - event: _status.event, - }; - if (info.sourceSkill) { - logInfo.sourceSkill = info.sourceSkill; - if (global.includes(info.sourceSkill)) { - logInfo.type = 'global'; - } - else if (players.includes(info.sourceSkill)) { - logInfo.type = 'player'; - } - else if (equips.includes(info.sourceSkill)) { - logInfo.type = 'equip'; - } - } - else { - if (global.includes(name)) { - logInfo.sourceSkill = name; - logInfo.type = 'global'; - } - else if (players.includes(name)) { - logInfo.sourceSkill = name; - logInfo.type = 'player'; - } - else if (equips.includes(name)) { - logInfo.sourceSkill = name; - logInfo.type = 'equip'; - } - else { - var bool = false; - for (var i of players) { - var expand = [i]; - game.expandSkills(expand); - if (expand.includes(name)) { - bool = true; - logInfo.sourceSkill = i; - logInfo.type = 'player'; - break; - } - } - if (!bool) { - for (var i of players) { - var expand = [i]; - game.expandSkills(expand); - if (expand.includes(name)) { - logInfo.sourceSkill = i; - logInfo.type = 'equip'; - break; - } - } - } - } - } - event.sourceSkill = logInfo.sourceSkill; - event.type = logInfo.type; - player.getHistory('useSkill').push(logInfo); - event.trigger('useSkill'); - "step 1"; - var info = get.info(event.skill); - if (info && info.contentBefore) { - var next = game.createEvent(event.skill + 'ContentBefore'); - next.setContent(info.contentBefore); - next.targets = targets; - next.cards = cards; - next.player = player; - if (event.forceDie) next.forceDie = true; - if (event.includeOut) next.includeOut = true; - } - "step 2"; - if (!event.skill) { - console.log('error: no skill', get.translation(event.player), event.player.getSkills()); - if (event._skill) { - event.skill = event._skill; - console.log(event._skill); - } - else { - event.finish(); - return; - } - } - var info = get.info(event.skill); - if (targets[num] && targets[num].isDead() || - targets[num] && targets[num].isOut() || - targets[num] && targets[num].removed) { - if (!info.multitarget && num < targets.length - 1) { - event.num++; - event.redo(); - } - return; - } - var next = game.createEvent(event.skill); - next.setContent(info.content); - next.targets = targets; - next.cards = cards; - next.player = player; - next.num = num; - next.multitarget = info.multitarget; - if (num == 0 && next.targets.length > 1) { - if (!info.multitarget) { - lib.tempSortSeat = player; - targets.sort(lib.sort.seat); - delete lib.tempSortSeat; - } - for (var i = 0; i < targets.length; i++) { - targets[i].addTempClass('target'); - } - } - next.target = targets[num]; - if (event.forceDie) next.forceDie = true; - if (event.includeOut) next.includeOut = true; - if (next.target && !info.multitarget) { - if (num == 0 && targets.length > 1) { - // var ttt=next.target; - // setTimeout(function(){ttt.addTempClass('target');},0.5*lib.config.duration); - } - else { - next.target.addTempClass('target'); - } - } - if (num == 0) { - if (typeof info.delay == 'number') game.delay(info.delay); - else if (info.delay !== false && info.delay !== 0) { - if (event.waitingForTransition) { - _status.waitingForTransition = event.waitingForTransition; - game.pause(); - } - else { - game.delayx(); - } - } - } - else game.delayx(0.5); - if (!info.multitarget && num < targets.length - 1) { - event.num++; - event.redo(); - } - "step 3"; - var info = get.info(event.skill); - if (info && info.contentAfter) { - var next = game.createEvent(event.skill + 'ContentAfter'); - next.setContent(info.contentAfter); - next.targets = targets; - next.cards = cards; - next.player = player; - if (event.forceDie) next.forceDie = true; - if (event.includeOut) next.includeOut = true; - } - "step 4"; - if (player.getStat().allSkills > 200) { - player._noSkill = true; - console.log(player.name, event.skill); - } - if (document.getElementsByClassName('thrown').length) { - if (event.skill && get.info(event.skill).delay !== false && get.info(event.skill).delay !== 0) game.delayx(); - } - else { - event.finish(); - } - "step 5"; - ui.clear(); - }, - draw: async (event, _trigger, player) => { - let { num } = event; - // if(lib.config.background_audio){ - // game.playAudio('effect','draw'); - // } - // game.broadcast(function(){ - // if(lib.config.background_audio){ - // game.playAudio('effect','draw'); - // } - // }); - if (typeof event.minnum == 'number' && num < event.minnum) { - num = event.minnum; - } - if (event.drawDeck) { - if (event.drawDeck > num) { - event.drawDeck = num; - } - num -= event.drawDeck; - } - if (event.log != false) { - if (num > 0) { - if (event.bottom) game.log(player, '从牌堆底摸了' + get.cnNumber(num) + '张牌'); - else game.log(player, '摸了' + get.cnNumber(num) + '张牌'); - } - if (event.drawDeck) { - game.log(player, '从牌库中获得了' + get.cnNumber(event.drawDeck) + '张牌'); - } - } - let cards; - if (num > 0) { - if (event.bottom) cards = get.bottomCards(num); - else if (player.getTopCards) cards = player.getTopCards(num); - else cards = get.cards(num); - } - else { - cards = []; - } - if (event.drawDeck) { - cards = cards.concat(player.getDeckCards(event.drawDeck)); - } - let next; - if (event.animate != false) { - if (event.visible) { - next = player.gain(cards, 'gain2'); - if (event.bottom) game.log(player, '从牌堆底摸了' + get.cnNumber(num) + '张牌(', cards, ')'); - else game.log(player, '摸了' + get.cnNumber(num) + '张牌(', cards, ')'); - } - else { - next = player.gain(cards, 'draw'); - } - } - else { - next = player.gain(cards); - if (event.$draw) { - player.$draw(cards.length); - } - } - if (event.gaintag) next.gaintag.addArray(event.gaintag); - event.result = cards; - await next; - }, - discard: function () { - "step 0"; - game.log(player, '弃置了', cards); - event.done = player.lose(cards, event.position, 'visible'); - event.done.type = 'discard'; - if (event.discarder) event.done.discarder = event.discarder; - "step 1"; - event.trigger('discard'); - }, - loseToDiscardpile: function () { - "step 0"; - if (event.log != false) game.log(player, '将', cards, '置入了弃牌堆'); - var next = player.lose(cards, event.position); - if (event.insert_index) next.insert_index = event.insert_index; - if (event.insert_card) next.insert_card = true; - if (!event.blank) next.visible = true; - next.type = 'loseToDiscardpile'; - event.done = next; - "step 1"; - event.trigger('loseToDiscardpile'); - }, - respond: function () { - 'step 0'; - var cardaudio = true; - if (event.skill) { - if (lib.skill[event.skill].audio) { - cardaudio = false; - } - player.logSkill(event.skill); - player.checkShow(event.skill, true); - if (lib.skill[event.skill].onrespond && !game.online) { - lib.skill[event.skill].onrespond(event, player); - } - } - else if (!event.nopopup) player.tryCardAnimate(card, card.name, 'wood'); - if (cardaudio && event.getParent(3).name == 'useCard') game.broadcastAll((player, card) => { - game.playCardAudio(card, player); - /* - if(!lib.config.background_audio) return; - const sex=player.sex=='female'?'female':'male',audio=lib.card[card.name].audio; - if(typeof audio=='string'){ - const audioInfo=audio.split(':'); - if(audio.startsWith('db:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,audioInfo[2],`${card.name}_${sex}.${audioInfo[3]||'mp3'}`); - else if(audio.startsWith('ext:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${card.name}_${sex}.${audioInfo[2]||'mp3'}`); - else game.playAudio('card',sex,`${audioInfo[0]}.${audioInfo[1]||'mp3'}`); - } - else game.playAudio('card',sex,card.name);*/ - }, player, card); - if (event.skill) { - if (player.stat[player.stat.length - 1].skill[event.skill] == undefined) { - player.stat[player.stat.length - 1].skill[event.skill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[event.skill]++; - } - var sourceSkill = get.info(event.skill).sourceSkill; - if (sourceSkill) { - if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { - player.stat[player.stat.length - 1].skill[sourceSkill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[sourceSkill]++; - } - } - } - if (cards.length && (cards.length > 1 || cards[0].name != card.name)) { - game.log(player, '打出了', card, '(', cards, ')'); - } - else { - game.log(player, '打出了', card); - } - player.actionHistory[player.actionHistory.length - 1].respond.push(event); - if (cards.length) { - var owner = (get.owner(cards[0]) || player); - var next = owner.lose(cards, 'visible', ui.ordering).set('type', 'use'); - var directDiscard = []; - for (var i = 0; i < cards.length; i++) { - if (!next.cards.includes(cards[i])) { - directDiscard.push(cards[i]); - } - } - if (directDiscard.length) game.cardsGotoOrdering(directDiscard); - } - if (event.animate != false && event.throw !== false) { - for (var i = 0; i < cards.length; i++) { - player.$throw(cards[i]); - if (event.highlight) { - cards[i].clone.classList.add('thrownhighlight'); - game.addVideo('highlightnode', player, get.cardInfo(cards[i])); - } - } - if (event.highlight) { - game.broadcast(function (cards) { - for (var i = 0; i < cards.length; i++) { - if (cards[i].clone) { - cards[i].clone.classList.add('thrownhighlight'); - } - } - }, cards); - } - } - event.trigger('respond'); - 'step 1'; - game.delayx(0.5); - }, - swapHandcards: function () { - 'step 0'; - event.cards1 = event.cards1 || player.getCards('h'); - event.cards2 = event.cards2 || target.getCards('h'); - game.loseAsync({ - player: player, - target: target, - cards1: event.cards1, - cards2: event.cards2, - }).setContent('swapHandcardsx'); - 'step 1'; - game.loseAsync({ - gain_list: [ - [player, event.cards2.filterInD()], - [target, event.cards1.filterInD()] - ], - }).setContent('gaincardMultiple'); - 'step 2'; - game.delayx(); - }, - swapHandcardsx: function () { - 'step 0'; - player.$giveAuto(event.cards1, target); - target.$giveAuto(event.cards2, player); - 'step 1'; - event.cards = event.cards1; - var next = player.lose(event.cards, ui.ordering); - next.getlx = false; - next.relatedEvent = event.getParent(); - if (player == game.me) { - event.delayed = true; - } - else { - next.delay = false; - } - 'step 2'; - event.cards = event.cards2; - var next = target.lose(event.cards, ui.ordering); - next.getlx = false; - next.relatedEvent = event.getParent(); - if (target == game.me) { - event.delayed = true; - } - else { - next.delay = false; - } - 'step 3'; - if (!event.delayed) game.delay(); - }, - gainMultiple: function () { - 'step 0'; - event.delayed = false; - event.num = 0; - event.cards = []; - 'step 1'; - player.gainPlayerCard(targets[num], event.position, true).set('boolline', false).set('delay', num == targets.length - 1); - 'step 2'; - if (result.bool) { - event.cards.addArray(result.cards); - if (num == targets.length - 1) event.delayed = true; - } - event.num++; - if (event.num < targets.length) { - event.goto(1); - } - 'step 3'; - if (!event.delayed) game.delay(); - }, - gain: function () { - "step 0"; - if (event.animate == 'give') event.visible = true; - if (cards) { - var map = {}; - for (var i of cards) { - var owner = get.owner(i, 'judge'); - if (owner && (owner != player || get.position(i) != 'h')) { - var id = owner.playerid; - if (!map[id]) map[id] = [[], [], []]; - map[id][0].push(i); - var position = get.position(i); - if (position == 'h') map[id][1].push(i); - else map[id][2].push(i); - } - else if (!event.updatePile && get.position(i) == 'c') event.updatePile = true; - } - event.losing_map = map; - for (var i in map) { - var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - var next = owner.lose(map[i][0], ui.special).set('type', 'gain').set('forceDie', true).set('getlx', false); - if (event.visible == true) { - next.visible = true; - } - event.relatedLose = next; - } - } - else { - event.finish(); - } - "step 1"; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('handcard', player, event)) { - cards[i].selfDestroy(event); - cards.splice(i--, 1); - } - else if (event.losing_map) { - for (var id in event.losing_map) { - if (event.losing_map[id][0].includes(cards[i])) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; - var hs = source.getCards('hejsx'); - if (hs.includes(cards[i])) { - cards.splice(i--, 1); - } else { - cards[i].addKnower(event.visible ? 'everyone' : source); - } - } - } - } - } - if (cards.length == 0) { - event.finish(); - return; - } - player.getHistory('gain').push(event); - //if(event.source&&event.delay!==false) game.delayx(); - "step 2"; - if (player.getStat().gain == undefined) { - player.getStat().gain = cards.length; - } - else { - player.getStat().gain += cards.length; - } - "step 3"; - var sort; - var frag1 = document.createDocumentFragment(); - var frag2 = document.createDocumentFragment(); - var hs = player.getCards('hs'); - for (var i = 0; i < cards.length; i++) { - if (hs.includes(cards[i])) { - cards.splice(i--, 1); - } - } - for (var num = 0; num < cards.length; num++) { - sort = lib.config.sort_card(cards[num]); - if (lib.config.reverse_sort) sort = -sort; - if (['o', 'd'].includes(get.position(cards[num], true))) { - cards[num].addKnower('everyone'); - } - cards[num].fix(); - cards[num].style.transform = ''; - cards[num].addGaintag(event.gaintag); - if (event.knowers) { - cards[num].addKnower(event.knowers);//添加事件设定的知情者。 - } - if (_status.discarded) { - _status.discarded.remove(cards[num]); - } - // cards[num].vanishtag.length=0; - for (var num2 = 0; num2 < cards[num].vanishtag.length; num2++) { - if (cards[num].vanishtag[num2][0] != '_') { - cards[num].vanishtag.splice(num2--, 1); - } - } - if (player == game.me) { - cards[num].classList.add('drawinghidden'); - } - if (get.is.singleHandcard() || sort > 1) frag1.appendChild(cards[num]); - else frag2.appendChild(cards[num]); - } - var addv = function () { - if (player == game.me) { - game.addVideo('gain12', player, [get.cardsInfo(frag1.childNodes), get.cardsInfo(frag2.childNodes), event.gaintag]); - } - }; - var broadcast = function () { - game.broadcast(function (player, cards, num, gaintag) { - player.directgain(cards, null, gaintag); - _status.cardPileNum = num; - }, player, cards, ui.cardPile.childNodes.length, event.gaintag); - }; - if (event.animate == 'draw') { - player.$draw(cards.length); - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(500, 500)); - } - else if (event.animate == 'gain') { - player.$gain(cards, event.log); - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(700, 700)); - } - else if (event.animate == 'gain2' || event.animate == 'draw2') { - var gain2t = 300; - if (player.$gain2(cards, event.log) && player == game.me) { - gain2t = 500; - } - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(gain2t, gain2t)); - } - else if (event.animate == 'give' || event.animate == 'giveAuto') { - var evtmap = event.losing_map; - if (event.animate == 'give') { - for (var i in evtmap) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - source.$give(evtmap[i][0], player, event.log); - } - } - else { - for (var i in evtmap) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - if (evtmap[i][1].length) source.$giveAuto(evtmap[i][1], player, event.log); - if (evtmap[i][2].length) source.$give(evtmap[i][2], player, event.log); - } - } - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(500, 500)); - } - else if (typeof event.animate == 'function') { - var time = event.animate(event); - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(time, time)); - } - else { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - event.finish(); - } - "step 4"; - game.delayx(); - if (event.updatePile) game.updateRoundNumber(); - }, - addToExpansion: function () { - "step 0"; - if (event.animate == 'give') event.visible = true; - if (cards) { - var map = {}; - for (var i of cards) { - var owner = get.owner(i, 'judge'); - if (owner && (owner != player || get.position(i) != 'x')) { - var id = owner.playerid; - if (!map[id]) map[id] = [[], [], []]; - map[id][0].push(i); - var position = get.position(i); - if (position == 'h') map[id][1].push(i); - else map[id][2].push(i); - } - else if (!event.updatePile && get.position(i) == 'c') event.updatePile = true; - } - event.losing_map = map; - for (var i in map) { - var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - var next = owner.lose(map[i][0], ui.special).set('type', 'loseToExpansion').set('forceDie', true).set('getlx', false); - if (event.visible == true) next.visible = true; - event.relatedLose = next; - } - } - else { - event.finish(); - } - "step 1"; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('expansion', player, event)) { - cards[i].selfDestroy(event); - cards.splice(i--, 1); - } - else if (event.losing_map) { - for (var id in event.losing_map) { - if (event.losing_map[id][0].includes(cards[i])) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; - var hs = source.getCards('hejsx'); - if (hs.includes(cards[i])) { - cards.splice(i--, 1); - } - } - } - } - } - if (cards.length == 0) { - event.finish(); - return; - } - "step 2"; - var hs = player.getCards('x'); - for (var i = 0; i < cards.length; i++) { - if (hs.includes(cards[i])) { - cards.splice(i--, 1); - } - } - for (var num = 0; num < cards.length; num++) { - if (_status.discarded) { - _status.discarded.remove(cards[num]); - } - for (var num2 = 0; num2 < cards[num].vanishtag.length; num2++) { - if (cards[num].vanishtag[num2][0] != '_') { - cards[num].vanishtag.splice(num2--, 1); - } - } - } - if (event.animate == 'draw') { - player.$draw(cards.length); - if (event.log) game.log(player, '将', get.cnNumber(cards.length), '张牌置于了武将牌上'); - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(500, 500)); - } - else if (event.animate == 'gain') { - player.$gain(cards, false); - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(700, 700)); - } - else if (event.animate == 'gain2' || event.animate == 'draw2') { - var gain2t = 300; - if (player.$gain2(cards) && player == game.me) { - gain2t = 500; - } - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(gain2t, gain2t)); - } - else if (event.animate == 'give' || event.animate == 'giveAuto') { - var evtmap = event.losing_map; - if (event.animate == 'give') { - for (var i in evtmap) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - source.$give(evtmap[i][0], player, false); - if (event.log) game.log(player, '将', evtmap[i][0], '置于了武将牌上'); - } - } - else { - for (var i in evtmap) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - if (evtmap[i][1].length) { - source.$giveAuto(evtmap[i][1], player, false); - if (event.log) game.log(player, '将', get.cnNumber(evtmap[i][1].length), '张牌置于了武将牌上'); - } - if (evtmap[i][2].length) { - source.$give(evtmap[i][2], player, false); - if (event.log) game.log(player, '将', evtmap[i][2], '置于了武将牌上'); - } - } - } - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(500, 500)); - } - else if (typeof event.animate == 'function') { - var time = event.animate(event); - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(time, time)); - } - else { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - event.finish(); - } - "step 4"; - game.delayx(); - if (event.updatePile) game.updateRoundNumber(); - }, - lose: function () { - "step 0"; - var evt = event.getParent(); - if ((evt.name != 'discard' || event.type != 'discard') && (evt.name != 'loseToDiscardpile' || event.type != 'loseToDiscardpile')) { - event.delay = false; - return; - } - if (evt.delay === false) event.delay = false; - if (evt.animate != false) { - evt.discardid = lib.status.videoId++; - game.broadcastAll(function (player, cards, id, visible) { - player.$throw(cards, null, 'nobroadcast'); - var cardnodes = []; - cardnodes._discardtime = get.time(); - for (var i = 0; i < cards.length; i++) { - if (cards[i].clone) { - cardnodes.push(cards[i].clone); - if (!visible) { - cards[i].clone.classList.add('infohidden'); - cards[i].clone.classList.add('infoflip'); - } - } - } - ui.todiscard[id] = cardnodes; - }, player, cards, evt.discardid, event.visible); - if (lib.config.sync_speed && cards[0] && cards[0].clone) { - if (evt.delay != false) { - var waitingForTransition = get.time(); - evt.waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete evt.waitingForTransition; - }); - } - else if (evt.getParent().discardTransition) { - delete evt.getParent().discardTransition; - var waitingForTransition = get.time(); - evt.getParent().waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete evt.getParent().waitingForTransition; - }); - } - } - } - "step 1"; - event.gaintag_map = {}; - var hs = [], es = [], js = [], ss = [], xs = []; - var unmarks = []; - if (event.insert_card && event.position == ui.cardPile) event.cards.reverse(); - var hej = player.getCards('hejsx'); - event.stockcards = cards.slice(0); - for (var i = 0; i < cards.length; i++) { - if (!hej.includes(cards[i])) { - cards.splice(i--, 1); - continue; - } - else if (cards[i].parentNode) { - if (cards[i].parentNode.classList.contains('equips')) { - cards[i].original = 'e'; - es.push(cards[i]); - } - else if (cards[i].parentNode.classList.contains('judges')) { - cards[i].original = 'j'; - js.push(cards[i]); - } - else if (cards[i].parentNode.classList.contains('expansions')) { - cards[i].original = 'x'; - xs.push(cards[i]); - if (cards[i].gaintag && cards[i].gaintag.length) unmarks.addArray(cards[i].gaintag); - } - else if (cards[i].parentNode.classList.contains('handcards')) { - if (cards[i].classList.contains('glows')) { - cards[i].original = 's'; - ss.push(cards[i]); - } - else { - cards[i].original = 'h'; - hs.push(cards[i]); - } - } - else { - cards[i].original = null; - } - } - if (cards[i].gaintag && cards[i].gaintag.length) { - event.gaintag_map[cards[i].cardid] = cards[i].gaintag.slice(0); - cards[i].removeGaintag(true); - } - - cards[i].style.transform += ' scale(0.2)'; - cards[i].classList.remove('glow'); - cards[i].classList.remove('glows'); - cards[i].recheck(); - - var info = lib.card[cards[i].name]; - if ('_destroy' in cards[i]) { - if (cards[i]._destroy) { - cards[i].delete(); - cards[i].destroyed = cards[i]._destroy; - continue; - } - } - else if ('destroyed' in cards[i]) { - if (event.getlx !== false && event.position && cards[i].willBeDestroyed(event.position.id, null, event)) { - cards[i].selfDestroy(event); - continue; - } - } - else if (info.destroy) { - cards[i].delete(); - cards[i].destroyed = info.destroy; - continue; - } - if (event.position) { - if (_status.discarded) { - if (event.position == ui.discardPile) { - _status.discarded.add(cards[i]); - } - else { - _status.discarded.remove(cards[i]); - } - } - if (event.insert_index) { - cards[i].fix(); - event.position.insertBefore(cards[i], event.insert_index(event, cards[i])); - } - else if (event.insert_card) { - cards[i].fix(); - event.position.insertBefore(cards[i], event.position.firstChild); - } - else if (event.position == ui.cardPile) { - cards[i].fix(); - event.position.appendChild(cards[i]); - } - else cards[i].goto(event.position); - } - else { - cards[i].remove(); - } - //if(ss.includes(cards[i])) cards.splice(i--,1); - } - if (player == game.me) ui.updatehl(); - ui.updatej(player); - game.broadcast(function (player, cards, num) { - for (var i = 0; i < cards.length; i++) { - cards[i].classList.remove('glow'); - cards[i].classList.remove('glows'); - cards[i].fix(); - cards[i].remove(); - } - if (player == game.me) { - ui.updatehl(); - } - ui.updatej(player); - _status.cardPileNum = num; - }, player, cards, ui.cardPile.childNodes.length); - game.addVideo('lose', player, [get.cardsInfo(hs), get.cardsInfo(es), get.cardsInfo(js), get.cardsInfo(ss)]); - event.cards2 = hs.concat(es); - player.getHistory('lose').push(event); - game.getGlobalHistory().cardMove.push(event); - player.update(); - game.addVideo('loseAfter', player); - event.num = 0; - if (event.position == ui.ordering) { - var evt = event.relatedEvent || event.getParent(); - if (!evt.orderingCards) evt.orderingCards = []; - if (!evt.noOrdering && !evt.cardsOrdered) { - evt.cardsOrdered = true; - var next = game.createEvent('orderingDiscard', false, evt.getParent()); - next.relatedEvent = evt; - next.setContent('orderingDiscard'); - } - if (!evt.noOrdering) { - evt.orderingCards.addArray(cards); - } - } - else if (event.position == ui.cardPile) { - game.updateRoundNumber(); - } - if (unmarks.length) { - for (var i of unmarks) { - player[(lib.skill[i] && lib.skill[i].mark || player.hasCard((card) => card.hasGaintag(i), 'x')) ? 'markSkill' : 'unmarkSkill'](i); - } - } - event.hs = hs; - event.es = es; - event.js = js; - event.ss = ss; - event.xs = xs; - game.clearCardKnowers(hs); - if (hs.length && !event.visible) { - player.getCards('h').forEach(hcard => { hcard.clearKnowers(); }); - } - "step 2"; - if (num < cards.length) { - if (event.es.includes(cards[num])) { - event.loseEquip = true; - player.removeEquipTrigger(cards[num]); - var info = get.info(cards[num]); - if (info.onLose && (!info.filterLose || info.filterLose(cards[num], player))) { - event.goto(3); - return; - } - } - event.num++; - event.redo(); - } - else { - if (event.loseEquip) { - player.addEquipTrigger(); - } - event.goto(4); - } - "step 3"; - var info = get.info(cards[num]); - if (info.loseDelay != false && (player.isAlive() || info.forceDie)) { - player.popup(cards[num].name); - game.delayx(); - } - if (Array.isArray(info.onLose)) { - for (var i = 0; i < info.onLose.length; i++) { - var next = game.createEvent('lose_' + cards[num].name); - next.setContent(info.onLose[i]); - if (info.forceDie) next.forceDie = true; - next.player = player; - next.card = cards[num]; - } - } - else { - var next = game.createEvent('lose_' + cards[num].name); - next.setContent(info.onLose); - next.player = player; - if (info.forceDie) next.forceDie = true; - next.card = cards[num]; - } - event.num++; - event.goto(2); - "step 4"; - if (event.toRenku) { - _status.renku.addArray(cards.filter(function (card) { - return !card.willBeDestroyed('renku', null, event); - })); - if (_status.renku.length > 6) { - var cards = _status.renku.splice(0, _status.renku.length - 6); - game.log(cards, '从仁库进入了弃牌堆'); - game.cardsDiscard(cards).set('outRange', true).fromRenku = true; - } - game.updateRenku(); - } - "step 5"; - var evt = event.getParent(); - if ((evt.name != 'discard' && event.type != 'discard') && (evt.name != 'loseToDiscardpile' && event.type != 'loseToDiscardpile')) return; - if (event.animate === false || event.delay === false) return; - if (evt.delay != false) { - if (evt.waitingForTransition) { - _status.waitingForTransition = evt.waitingForTransition; - game.pause(); - } - else { - game.delayx(); - } - } - }, - damage: function () { - "step 0"; - event.forceDie = true; - if (event.unreal) { event.goto(4); return; } - event.trigger('damageBegin1'); - "step 1"; - event.trigger('damageBegin2'); - "step 2"; - event.trigger('damageBegin3'); - "step 3"; - event.trigger('damageBegin4'); - "step 4"; - //moved changeHujia to changeHp - if (player.hujia > 0 && !player.hasSkillTag('nohujia')) { - var damageAudioInfo = lib.natureAudio.hujia_damage[event.nature]; - if (!damageAudioInfo || damageAudioInfo == 'normal') { - damageAudioInfo = 'effect/hujia_damage' + (num > 1 ? '2' : '') + '.mp3'; - } else if (damageAudioInfo == 'default') { - damageAudioInfo = 'effect/hujia_damage_' + event.nature + (num > 1 ? '2' : '') + '.mp3'; - } else { - damageAudioInfo = damageAudioInfo[num > 1 ? 2 : 1]; - } - game.broadcastAll(function (damageAudioInfo) { - if (lib.config.background_audio) game.playAudio(damageAudioInfo); - }, damageAudioInfo); - } else { - var damageAudioInfo = lib.natureAudio.damage[event.nature]; - if (!damageAudioInfo || damageAudioInfo == 'normal') { - damageAudioInfo = 'effect/damage' + (num > 1 ? '2' : '') + '.mp3'; - } else if (damageAudioInfo == 'default') { - damageAudioInfo = 'effect/damage_' + event.nature + (num > 1 ? '2' : '') + '.mp3'; - } else { - damageAudioInfo = damageAudioInfo[num > 1 ? 2 : 1]; - } - game.broadcastAll(function (damageAudioInfo) { - if (lib.config.background_audio) game.playAudio(damageAudioInfo); - }, damageAudioInfo); - } - var str = event.unreal ? '视为受到了' : '受到了'; - if (source) str += '来自' + (source == player ? '自己' : get.translation(source)) + '的'; - str += get.cnNumber(num) + '点'; - if (event.nature) str += get.translation(event.nature) + '属性'; - str += '伤害'; - game.log(player, str); - if (player.stat[player.stat.length - 1].damaged == undefined) { - player.stat[player.stat.length - 1].damaged = num; - } - else { - player.stat[player.stat.length - 1].damaged += num; - } - if (source) { - source.getHistory('sourceDamage').push(event); - if (source.stat[source.stat.length - 1].damage == undefined) { - source.stat[source.stat.length - 1].damage = num; - } - else { - source.stat[source.stat.length - 1].damage += num; - } - } - player.getHistory('damage').push(event); - if (!event.unreal) { - if (event.notrigger) { - player.changeHp(-num, false)._triggered = null; - } - else { - player.changeHp(-num, false); - } - } - if (event.animate !== false) { - player.$damage(source); - var natures = (event.nature || '').split(lib.natureSeparator); - game.broadcastAll(function (natures, player) { - if (lib.config.animation && !lib.config.low_performance) { - if (natures.includes('fire')) { - player.$fire(); - } - if (natures.includes('thunder')) { - player.$thunder(); - } - } - }, natures, player); - var numx = player.hasSkillTag('nohujia') ? num : Math.max(0, num - player.hujia); - player.$damagepop(-numx, natures[0]); - } - if (event.unreal) event.goto(6); - if (!event.notrigger) { - if (num == 0) { - event.trigger('damageZero'); - event._triggered = null; - } - else { - event.trigger('damage'); - } - } - "step 5"; - if (player.hp <= 0 && player.isAlive() && !event.nodying) { - game.delayx(); - event._dyinged = true; - player.dying(event); - } - if (source && lib.config.border_style == 'auto') { - var dnum = 0; - for (var j = 0; j < source.stat.length; j++) { - if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; - } - if (dnum >= 2) { - if (lib.config.autoborder_start == 'silver') { - dnum += 4; - } - else if (lib.config.autoborder_start == 'gold') { - dnum += 8; - } - } - if (lib.config.autoborder_count == 'damage') { - source.node.framebg.dataset.decoration = ''; - if (dnum >= 10) { - source.node.framebg.dataset.auto = 'gold'; - if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; - } - else if (dnum >= 6) { - source.node.framebg.dataset.auto = 'silver'; - if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; - } - else if (dnum >= 2) { - source.node.framebg.dataset.auto = 'bronze'; - if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; - } - if (dnum >= 2) { - source.classList.add('topcount'); - } - } - else if (lib.config.autoborder_count == 'mix') { - source.node.framebg.dataset.decoration = ''; - switch (source.node.framebg.dataset.auto) { - case 'bronze': if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; break; - case 'silver': if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; break; - case 'gold': if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; break; - } - } - } - "step 6"; - if (!event.notrigger) event.trigger('damageSource'); - }, - recover: function () { - if (lib.config.background_audio) { - game.playAudio('effect', 'recover'); - } - game.broadcast(function () { - if (lib.config.background_audio) { - game.playAudio('effect', 'recover'); - } - }); - if (num > player.maxHp - player.hp) { - num = player.maxHp - player.hp; - event.num = num; - } - if (num > 0) { - player.changeHp(num, false); - game.broadcastAll(function (player) { - if (lib.config.animation && !lib.config.low_performance) { - player.$recover(); - } - }, player); - player.$damagepop(num, 'wood'); - game.log(player, '回复了' + get.cnNumber(num) + '点体力'); - } - }, - loseHp: function () { - "step 0"; - if (lib.config.background_audio) { - game.playAudio('effect', 'loseHp'); - } - game.broadcast(function () { - if (lib.config.background_audio) { - game.playAudio('effect', 'loseHp'); - } - }); - game.log(player, '失去了' + get.cnNumber(num) + '点体力'); - player.changeHp(-num); - "step 1"; - if (player.hp <= 0 && !event.nodying) { - game.delayx(); - event._dyinged = true; - player.dying(event); - } - }, - doubleDraw: function () { - "step 0"; - player.chooseBool('你的主副将体力上限之和是奇数,是否摸一张牌?'); - "step 1"; - if (result.bool) { - player.draw(); - } - }, - loseMaxHp: function () { - "step 0"; - game.log(player, '减少了' + get.cnNumber(num) + '点体力上限'); - player.maxHp -= num; - event.loseHp = Math.max(0, player.hp - player.maxHp); - player.update(); - "step 1"; - if (player.maxHp <= 0) { - player.die(event); - } - }, - gainMaxHp: function () { - "step 0"; - game.log(player, '增加了' + get.cnNumber(num) + '点体力上限'); - player.maxHp += num; - player.update(); - }, - changeHp: function () { - //add to GlobalHistory - game.getGlobalHistory().changeHp.push(event); - //changeHujia moved here - if (num < 0 && player.hujia > 0 && event.getParent().name == 'damage' && !player.hasSkillTag('nohujia')) { - event.hujia = Math.min(-num, player.hujia); - event.getParent().hujia = event.hujia; - event.num += event.hujia; - //log moved to changeHujia - //game.log(player,'的护甲抵挡了'+get.cnNumber(event.hujia)+'点伤害'); - player.changeHujia(-event.hujia).type = 'damage'; - } - //old part - num = event.num; - player.hp += num; - if (isNaN(player.hp)) player.hp = 0; - if (player.hp > player.maxHp) player.hp = player.maxHp; - player.update(); - if (event.popup !== false) { - player.$damagepop(num, 'water'); - } - if (_status.dying.includes(player) && player.hp > 0) { - _status.dying.remove(player); - game.broadcast(function (list) { - _status.dying = list; - }, _status.dying); - var evt = event.getParent('_save'); - if (evt && evt.finish) evt.finish(); - evt = event.getParent('dying'); - if (evt && evt.finish) evt.finish(); - } - event.trigger('changeHp'); - }, - changeHujia: function () { - if (num > 0) { - game.log(player, '获得了' + get.cnNumber(num) + '点护甲'); - } - else if (num < 0) { - if (-num > player.hujia) { - num = -player.hujia; - event.num = num; - } - switch (event.type) { //log moved here - case 'damage': - game.log(player, '的护甲抵挡了' + get.cnNumber(-num) + '点伤害'); - break; - case 'lose': - game.log(player, '失去了' + get.cnNumber(-num) + '点护甲'); - break; - } - } - player.hujia += num; - //if(player.hujia<0){ - // player.hujia=0; - //} - player.update(); - }, - dying: function () { - "step 0"; - event.forceDie = true; - if (player.isDying() || player.hp > 0) { - event.finish(); - return; - } - _status.dying.unshift(player); - game.broadcast(function (list) { - _status.dying = list; - }, _status.dying); - event.trigger('dying'); - game.log(player, '濒死'); - "step 1"; - delete event.filterStop; - if (player.hp > 0 || event.nodying) { - _status.dying.remove(player); - game.broadcast(function (list) { - _status.dying = list; - }, _status.dying); - event.finish(); - } - else if (!event.skipTao) { - var next = game.createEvent('_save'); - var start = false; - var starts = [_status.currentPhase, event.source, event.player, game.me, game.players[0]]; - for (var i = 0; i < starts.length; i++) { - if (get.itemtype(starts[i]) == 'player') { - start = starts[i]; break; - } - } - next.player = start; - next._trigger = event; - next.triggername = '_save'; - next.forceDie = true; - next.setContent(lib.skill._save.content); - } - "step 2"; - _status.dying.remove(player); - game.broadcast(function (list) { - _status.dying = list; - }, _status.dying); - if (player.hp <= 0 && !event.nodying && !player.nodying) player.die(event.reason); - }, - die: function () { - "step 0"; - event.forceDie = true; - if (_status.roundStart == player) { - _status.roundStart = player.next || player.getNext() || game.players[0]; - } - if (ui.land && ui.land.player == player) { - game.addVideo('destroyLand'); - ui.land.destroy(); - } - var unseen = false; - if (player.classList.contains('unseen')) { - player.classList.remove('unseen'); - unseen = true; - } - var logvid = game.logv(player, 'die', source); - event.logvid = logvid; - if (unseen) { - player.classList.add('unseen'); - } - if (source) { - game.log(player, '被', source, '杀害'); - if (source.stat[source.stat.length - 1].kill == undefined) { - source.stat[source.stat.length - 1].kill = 1; - } - else { - source.stat[source.stat.length - 1].kill++; - } - } - else { - game.log(player, '阵亡'); - } - - - // player.removeEquipTrigger(); - - // for(var i in lib.skill.globalmap){ - // if(lib.skill.globalmap[i].includes(player)){ - // lib.skill.globalmap[i].remove(player); - // if(lib.skill.globalmap[i].length==0&&!lib.skill[i].globalFixed){ - // game.removeGlobalSkill(i); - // } - // } - // } - game.broadcastAll(function (player) { - player.classList.add('dead'); - player.removeLink(); - player.classList.remove('turnedover'); - player.classList.remove('out'); - player.node.count.innerHTML = '0'; - player.node.hp.hide(); - player.node.equips.hide(); - player.node.count.hide(); - player.previous.next = player.next; - player.next.previous = player.previous; - game.players.remove(player); - game.dead.push(player); - _status.dying.remove(player); - - if (lib.config.background_speak) { - if (lib.character[player.name] && lib.character[player.name][4].some(tag => /^die:.+$/.test(tag))) { - var tag = lib.character[player.name][4].find(tag => /^die:.+$/.test(tag)); - var reg = new RegExp("^ext:(.+)?/"); - var match = tag.match(/^die:(.+)$/); - if (match) { - var path = match[1]; - if (reg.test(path)) path = path.replace(reg, (_o, p) => `../extension/${p}/`); - game.playAudio(path); - } - } - else if (lib.character[player.name] && lib.character[player.name][4].some(tag => tag.startsWith('die_audio'))) { - var tag = lib.character[player.name][4].find(tag => tag.startsWith('die_audio')); - var list = tag.split(':').slice(1); - game.playAudio('die', list.length ? list[0] : player.name); - } - else { - game.playAudio('die', player.name, function () { - game.playAudio('die', player.name.slice(player.name.indexOf('_') + 1)); - }); - } - } - }, player); - - game.addVideo('diex', player); - if (event.animate !== false) { - player.$die(source); - } - if (player.hp != 0) { - player.changeHp(0 - player.hp, false).forceDie = true; - } - "step 1"; - if (player.dieAfter) player.dieAfter(source); - "step 2"; - event.trigger('die'); - "step 3"; - if (player.isDead()) { - if (!game.reserveDead) { - for (var mark in player.marks) { - player.unmarkSkill(mark); - } - while (player.node.marks.childNodes.length > 1) { - player.node.marks.lastChild.remove(); - } - game.broadcast(function (player) { - while (player.node.marks.childNodes.length > 1) { - player.node.marks.lastChild.remove(); - } - }, player); - } - for (var i in player.tempSkills) { - player.removeSkill(i); - } - var skills = player.getSkills(); - for (var i = 0; i < skills.length; i++) { - if (lib.skill[skills[i]].temp) { - player.removeSkill(skills[i]); - } - } - if (_status.characterlist) { - if (lib.character[player.name] && !player.name.startsWith('gz_shibing') && !player.name.startsWith('gz_jun_')) _status.characterlist.add(player.name); - if (lib.character[player.name1] && !player.name1.startsWith('gz_shibing') && !player.name1.startsWith('gz_jun_')) _status.characterlist.add(player.name1); - if (lib.character[player.name2] && !player.name2.startsWith('gz_shibing') && !player.name2.startsWith('gz_jun_')) _status.characterlist.add(player.name2); - } - event.cards = player.getCards('hejsx'); - if (event.cards.length) { - player.discard(event.cards).forceDie = true; - //player.$throw(event.cards,1000); - } - } - "step 4"; - if (player.dieAfter2) player.dieAfter2(source); - "step 5"; - game.broadcastAll(function (player) { - if (game.online && player == game.me && !_status.over && !game.controlOver && !ui.exit) { - if (lib.mode[lib.configOL.mode].config.dierestart) { - ui.create.exit(); - } - } - }, player); - if (!_status.connectMode && player == game.me && !_status.over && !game.controlOver) { - ui.control.show(); - if (get.config('revive') && lib.mode[lib.config.mode].config.revive && !ui.revive) { - ui.revive = ui.create.control('revive', ui.click.dierevive); - } - if (get.config('continue_game') && !ui.continue_game && lib.mode[lib.config.mode].config.continue_game && !_status.brawl && !game.no_continue_game) { - ui.continue_game = ui.create.control('再战', game.reloadCurrent); - } - if (get.config('dierestart') && lib.mode[lib.config.mode].config.dierestart && !ui.restart) { - ui.restart = ui.create.control('restart', game.reload); - } - } - - if (!_status.connectMode && player == game.me && !game.modeSwapPlayer) { - // _status.auto=false; - if (ui.auto) { - // ui.auto.classList.remove('glow'); - ui.auto.hide(); - } - if (ui.wuxie) ui.wuxie.hide(); - } - - if (typeof _status.coin == 'number' && source && !_status.auto) { - if (source == game.me || source.isUnderControl()) { - _status.coin += 10; - } - } - if (source && lib.config.border_style == 'auto' && (lib.config.autoborder_count == 'kill' || lib.config.autoborder_count == 'mix')) { - switch (source.node.framebg.dataset.auto) { - case 'gold': case 'silver': source.node.framebg.dataset.auto = 'gold'; break; - case 'bronze': source.node.framebg.dataset.auto = 'silver'; break; - default: source.node.framebg.dataset.auto = lib.config.autoborder_start || 'bronze'; - } - if (lib.config.autoborder_count == 'kill') { - source.node.framebg.dataset.decoration = source.node.framebg.dataset.auto; - } - else { - var dnum = 0; - for (var j = 0; j < source.stat.length; j++) { - if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; - } - source.node.framebg.dataset.decoration = ''; - switch (source.node.framebg.dataset.auto) { - case 'bronze': if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; break; - case 'silver': if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; break; - case 'gold': if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; break; - } - } - source.classList.add('topcount'); - } - }, - addJudge: function () { - "step 0"; - if (cards) { - var owner = get.owner(cards[0]); - if (owner) { - event.relatedLose = owner.lose(cards, 'visible', ui.special).set('getlx', false); - } - else if (get.position(cards[0]) == 'c') event.updatePile = true; - } - "step 1"; - if (cards[0].willBeDestroyed('judge', player, event)) { - cards[0].selfDestroy(event); - event.finish(); - return; - } - else if (event.relatedLose) { - var owner = event.relatedLose.player; - if (owner.getCards('hejsx').includes(card)) { - event.finish(); - return; - } - } - cards[0].fix(); - cards[0].style.transform = ''; - cards[0].classList.remove('drawinghidden'); - delete cards[0]._transform; - var viewAs = typeof card == 'string' ? card : card.name; - if (!lib.card[viewAs] || !lib.card[viewAs].effect) { - game.cardsDiscard(cards[0]); - } - else { - cards[0].style.transform = ''; - cards[0].classList.add('drawinghidden'); - player.node.judges.insertBefore(cards[0], player.node.judges.firstChild); - if (_status.discarded) { - _status.discarded.remove(cards[0]); - } - ui.updatej(player); - game.broadcast(function (player, card, viewAs) { - card.fix(); - card.style.transform = ''; - card.classList.add('drawinghidden'); - card.viewAs = viewAs; - if (viewAs && viewAs != card.name && (card.classList.contains('fullskin') || card.classList.contains('fullborder'))) { - card.classList.add('fakejudge'); - card.node.background.innerHTML = lib.translate[viewAs + '_bg'] || get.translation(viewAs)[0]; - } - else { - card.classList.remove('fakejudge'); - } - player.node.judges.insertBefore(card, player.node.judges.firstChild); - ui.updatej(player); - if (card.clone && (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena)) { - card.clone.moveDelete(player); - game.addVideo('gain2', player, get.cardsInfo([card])); - } - }, player, cards[0], viewAs); - if (cards[0].clone && (cards[0].clone.parentNode == player.parentNode || cards[0].clone.parentNode == ui.arena)) { - cards[0].clone.moveDelete(player); - game.addVideo('gain2', player, get.cardsInfo(cards)); - } - // player.$gain2(cards); - if (get.itemtype(card) != 'card') { - if (typeof card == 'string') cards[0].viewAs = card; - else cards[0].viewAs = card.name; - } - else { - delete cards[0].viewAs; - } - if (cards[0].viewAs && cards[0].viewAs != cards[0].name) { - if (cards[0].classList.contains('fullskin') || cards[0].classList.contains('fullborder')) { - cards[0].classList.add('fakejudge'); - cards[0].node.background.innerHTML = lib.translate[cards[0].viewAs + '_bg'] || get.translation(cards[0].viewAs)[0]; - } - game.log(player, '被贴上了' + get.translation(cards[0].viewAs) + '(', cards, ')'); - } - else { - cards[0].classList.remove('fakejudge'); - game.log(player, '被贴上了', cards); - } - game.addVideo('addJudge', player, [get.cardInfo(cards[0]), cards[0].viewAs]); - } - if (event.updatePile) game.updateRoundNumber(); - }, - judge: function () { - "step 0"; - var judgestr = get.translation(player) + '的' + event.judgestr + '判定'; - event.videoId = lib.status.videoId++; - var cardj = event.directresult; - if (!cardj) { - if (player.getTopCards) cardj = player.getTopCards()[0]; - else cardj = get.cards()[0]; - } - var owner = get.owner(cardj); - if (owner) { - owner.lose(cardj, 'visible', ui.ordering); - } - else { - var nextj = game.cardsGotoOrdering(cardj); - if (event.position != ui.discardPile) nextj.noOrdering = true; - } - player.judging.unshift(cardj); - game.addVideo('judge1', player, [get.cardInfo(player.judging[0]), judgestr, event.videoId]); - game.broadcastAll(function (player, card, str, id, cardid) { - var event; - if (game.online) { - event = {}; - } - else { - event = _status.event; - } - if (game.chess) { - event.node = card.copy('thrown', 'center', ui.arena).addTempClass('start'); - } - else { - event.node = player.$throwordered(card.copy(), true); - } - if (lib.cardOL) lib.cardOL[cardid] = event.node; - event.node.cardid = cardid; - event.node.classList.add('thrownhighlight'); - ui.arena.classList.add('thrownhighlight'); - event.dialog = ui.create.dialog(str); - event.dialog.classList.add('center'); - event.dialog.videoId = id; - }, player, player.judging[0], judgestr, event.videoId, get.id()); - - game.log(player, '进行' + event.judgestr + '判定,亮出的判定牌为', player.judging[0]); - game.delay(2); - if (!event.noJudgeTrigger) event.trigger('judge'); - "step 1"; - event.result = { - card: player.judging[0], - name: player.judging[0].name, - number: get.number(player.judging[0]), - suit: get.suit(player.judging[0]), - color: get.color(player.judging[0]), - node: event.node, - }; - if (event.fixedResult) { - for (var i in event.fixedResult) { - event.result[i] = event.fixedResult[i]; - } - } - event.result.judge = event.judge(event.result); - if (event.result.judge > 0) event.result.bool = true; - else if (event.result.judge < 0) event.result.bool = false; - else event.result.bool = null; - player.judging.shift(); - game.checkMod(player, event.result, 'judge', player); - if (event.judge2) { - var judge2 = event.judge2(event.result); - if (typeof judge2 == 'boolean') player.tryJudgeAnimate(judge2); - } - if (event.clearArena != false) { - game.broadcastAll(ui.clear); - } - game.broadcast(function (id) { - var dialog = get.idDialog(id); - if (dialog) { - dialog.close(); - } - ui.arena.classList.remove('thrownhighlight'); - }, event.videoId); - event.dialog.close(); - game.addVideo('judge2', null, event.videoId); - ui.arena.classList.remove('thrownhighlight'); - game.log(player, '的判定结果为', event.result.card); - event.trigger('judgeFixing'); - if (event.callback) { - var next = game.createEvent('judgeCallback', false); - next.player = player; - next.card = event.result.card; - next.judgeResult = get.copy(event.result); - next.setContent(event.callback); - } - else { - if (!get.owner(event.result.card)) { - if (event.position != ui.discardPile) event.position.appendChild(event.result.card); - } - } - }, - turnOver: function () { - game.log(player, '翻面'); - player.classList.toggle('turnedover'); - game.broadcast(function (player) { - player.classList.toggle('turnedover'); - }, player); - game.addVideo('turnOver', player, player.classList.contains('turnedover')); - }, - link: function () { - if (player.isLinked()) { - game.log(player, '解除连环'); - } - else { - game.log(player, '被连环'); - } - if (lib.config.background_audio) { - game.playAudio('effect', 'link'); - } - game.broadcast(function () { - if (lib.config.background_audio) { - game.playAudio('effect', 'link'); - } - }); - player.classList.remove('target'); - if (get.is.linked2(player)) { - player.classList.toggle('linked2'); - } - else { - player.classList.toggle('linked'); - } - ui.updatej(player); - ui.updatem(player); - game.broadcast(function (player, linked) { - player.classList.remove('target'); - if (get.is.linked2(player)) { - if (linked) { - player.classList.add('linked2'); - } - else { - player.classList.remove('linked2'); - } - } - else { - if (linked) { - player.classList.add('linked'); - } - else { - player.classList.remove('linked'); - } - } - ui.updatej(player); - ui.updatem(player); - }, player, player.isLinked()); - game.addVideo('link', player, player.isLinked()); - }, - /** - * @deprecated - */ - chooseToGuanxing: function () { - "step 0"; - var cards = get.cards(num); - game.cardsGotoOrdering(cards); - var next = player.chooseToMove(); - next.set('list', [ - ['牌堆顶', cards], - ['牌堆底'], - ]); - next.set('prompt', '点击将牌移动到牌堆顶或牌堆底'); - next.processAI = event.processAI || function (list) { - var cards = list[0][1], player = _status.event.player; - var top = []; - var bottom; - cards.sort(function (a, b) { - return get.value(b, player) - get.value(a, player); - }); - while (cards.length) { - if (get.value(cards[0], player) <= 5) break; - top.unshift(cards.shift()); - } - bottom = cards; - return [top, bottom]; - }; - "step 1"; - var top = result.moved[0]; - var bottom = result.moved[1]; - top.reverse(); - for (var i = 0; i < top.length; i++) { - ui.cardPile.insertBefore(top[i], ui.cardPile.firstChild); - } - for (i = 0; i < bottom.length; i++) { - ui.cardPile.appendChild(bottom[i]); - } - game.addCardKnower(top, player); - game.addCardKnower(bottom, player); - player.popup(get.cnNumber(top.length) + '上' + get.cnNumber(bottom.length) + '下'); - game.log(player, '将' + get.cnNumber(top.length) + '张牌置于牌堆顶'); - game.updateRoundNumber(); - game.delayx(); - } -} +import { AI as ai } from '../../ai/index.js'; +import { Get as get } from '../../get/index.js'; +import { Game as game } from '../../game/index.js'; +import { Library as lib } from "../index.js"; +import { status as _status } from '../../status/index.js'; +import { UI as ui } from '../../ui/index.js'; +import { GNC as gnc } from '../../gnc/index.js'; + +// 未来再改 +export const Content = { + emptyEvent: () => { + event.trigger(event.name); + }, + //增加明置手牌 + addShownCards: () => { + const hs = player.getCards('h'), showingCards = event._cards.filter(showingCard => hs.includes(showingCard)), shown = player.getShownCards(); + event.gaintag.forEach(tag => player.addGaintag(showingCards, tag)); + if (!(event.cards = showingCards.filter(showingCard => !shown.includes(showingCard))).length) return; + game.log(player, '明置了', event.cards); + if (event.animate != false) player.$give(event.cards, player, false); + event.trigger('addShownCardsAfter'); + }, + //隐藏明置手牌 + hideShownCards: () => { + var shown = player.getShownCards(), hidingCards = event._cards.filter(hidingCard => shown.includes(hidingCard)); + if (!hidingCards.length) return; + if (event.gaintag.length) event.gaintag.forEach(tag => player.removeGaintag(tag, hidingCards)); + else { + var map = hidingCards.reduce((constructingMap, hidingCard) => { + hidingCard.gaintag.forEach(tag => { + if (!tag.startsWith('visible_')) return; + if (!constructingMap[tag]) constructingMap[tag] = []; + constructingMap[tag].push(hidingCard); + }); + return constructingMap; + }, {}); + Object.keys(map).forEach(key => player.removeGaintag(key, map[key])); + } + hidingCards.removeArray(player.getShownCards()); + if (!hidingCards.length) return; + game.log(player, '取消明置了', event.cards = hidingCards); + if (event.animate != false) player.$give(hidingCards, player, false); + event.trigger('hideShownCardsAfter'); + }, + //Execute the delay card effect + //执行延时锦囊牌效果 + executeDelayCardEffect: () => { + 'step 0'; + target.$phaseJudge(card); + event.cancelled = false; + event.trigger('executeDelayCardEffect'); + event.cardName = card.viewAs || card.name; + target.popup(event.cardName, 'thunder'); + if (!lib.card[event.cardName].effect) { + game.delay(); + event.finish(); + } + else if (!lib.card[event.cardName].judge) { + game.delay(); + event.nojudge = true; + } + 'step 1'; + if (event.cancelled || event.nojudge) return; + var next = player.judge(card), judge = event.judge; + if (typeof judge == 'function') next.judge = judge; + var judge2 = event.judge2; + if (typeof judge2 == 'function') next.judge2 = judge2; + 'step 2'; + if (event.excluded) delete event.excluded; + else { + var cardName = event.cardName; + if (event.cancelled && !event.direct) { + var cardCancel = lib.card[cardName].cancel; + if (cardCancel) { + var next = game.createEvent(`${cardName}Cancel`); + next.setContent(cardCancel); + next.cards = [card]; + if (!card.viewAs) { + var autoViewAs = next.card = get.autoViewAs(card); + autoViewAs.expired = card.expired; + } + else { + var autoViewAs = next.card = get.autoViewAs({ + name: cardName + }, next.cards); + autoViewAs.expired = card.expired; + } + next.player = player; + } + } + else { + var next = game.createEvent(cardName); + next.setContent(lib.card[cardName].effect); + next._result = result; + next.cards = [card]; + if (!card.viewAs) { + var autoViewAs = next.card = get.autoViewAs(card); + autoViewAs.expired = card.expired; + } + else { + var autoViewAs = next.card = get.autoViewAs({ + name: cardName + }, next.cards); + autoViewAs.expired = card.expired; + } + next.player = player; + } + } + ui.clear(); + card.delete(); + }, + //Gift + //赠予 + gift: () => { + 'step 0'; + event.num = 0; + 'step 1'; + if (num < cards.length) { + event.card = cards[num]; + event.trigger('gift'); + } + else { + game.delayx(); + event.finish(); + } + 'step 2'; + if (event.deniedGifts.includes(card)) { + game.log(target, '拒绝了', player, '赠予的', card); + event.trigger('giftDeny'); + player.loseToDiscardpile(card).log = false; + event.trigger('giftDenied'); + return; + } + game.log(player, '将', card, '赠予了', target); + player.$give(card, target, false); + game.delay(0.5); + event.trigger('giftAccept'); + if (get.type(card, false) == 'equip') target.equip(card).log = false; + else target.gain(card, player).visible = true; + event.trigger('giftAccepted'); + 'step 3'; + event.num++; + event.goto(1); + }, + //Recast + //重铸 + recast: () => { + 'step 0'; + game.log(player, '重铸了', cards); + if (typeof event.recastingLose != 'function') return; + event.trigger('recastingLose'); + event.recastingLose(player, cards); + event.trigger('recastingLost'); + event.recastingLosingEvents.push(...event.next.filter(value => value.name != 'arrangeTrigger')); + 'step 1'; + event.trigger('recast'); + 'step 2'; + if (typeof event.recastingGain != 'function') return; + event.trigger('recastingGain'); + event.recastingGain(player, cards); + event.trigger('recastingGained'); + event.recastingGainingEvents.push(...event.next.filter(value => value.name != 'arrangeTrigger')); + }, + //装备栏相关 + disableEquip: function () { + 'step 0'; + event.cards = []; + event.num = 0; + event.slotsx = []; + if (get.is.mountCombined()) { + event.slots.forEach(type => { + if (type == 'equip3' || type == 'equip4') event.slotsx.add('equip3_4'); + else event.slotsx.add(type); + }); + } + else { + event.slotsx.addArray(event.slots); + } + event.slotsx.sort(); + if (!event.slots.length) event.finish(); + 'step 1'; + var slot = event.slotsx[event.num]; + var slot_key = slot; + var left = player.countEnabledSlot(slot), lose; + if (slot == 'equip3_4') { + lose = Math.min(left, Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4'))); + slot_key = 'equip3'; + } + else lose = Math.min(left, get.numOf(event.slots, slot)); + if (lose <= 0) event.goto(3); + else { + game.log(player, '废除了' + get.cnNumber(lose) + '个', '#g' + get.translation(slot) + '栏'); + if (!player.disabledSlots) player.disabledSlots = {}; + if (!player.disabledSlots[slot_key]) player.disabledSlots[slot_key] = 0; + player.disabledSlots[slot_key] += lose; + var cards = player.getEquips(slot).filter(card => !event.cards.includes(card)); + if (cards.length > 0) { + if (lose >= left) { + event._result = { bool: true, links: cards }; + } + else if (cards.length > (left - lose)) { + var source = event.source, num = (cards.length - (left - lose)); + if (!source || !source.isIn()) source = player; + source.chooseButton([ + '选择' + (player == source ? '你' : get.translation(player)) + '的' + get.cnNumber(num) + '张' + get.translation(slot) + '牌置入弃牌堆', + cards, + ], true, [1, num]).set('filterOk', function () { + var evt = _status.event; + return ui.selected.buttons.reduce(function (num, button) { + if (evt.slot == 'equip3_4') return num + Math.max(get.numOf(get.subtypes(button.link, false), 'equip3'), get.numOf(get.subtypes(button.link, false), 'equip4')); + return num + get.numOf(get.subtypes(button.link, false), evt.slot); + }, 0) == evt.required; + }).set('required', num).set('slot', slot); + } + else event.goto(3); + } + else event.goto(3); + } + 'step 2'; + if (result.bool) event.cards.addArray(result.links); + 'step 3'; + event.num++; + if (event.num < event.slotsx.length) event.goto(1); + else { + player.$syncDisable(); + if (cards.length > 0) player.loseToDiscardpile(cards); + } + }, + enableEquip: function () { + if (!event.slots.length) return; + var slotsx = [...new Set(event.slots)].sort(); + for (var slot of slotsx) { + var lost = player.countDisabledSlot(slot), gain = Math.min(lost, get.numOf(event.slots, slot)); + if (lost <= 0) continue; + else { + game.log(player, '恢复了' + get.cnNumber(gain) + '个', '#g' + get.translation(slot) + '栏'); + if (!player.disabledSlots) player.disabledSlots = {}; + if (!player.disabledSlots[slot]) player.disabledSlots[slot] = 0; + player.disabledSlots[slot] -= gain; + } + } + player.$syncDisable(); + }, + expandEquip: function () { + if (!event.slots.length) return; + var slotsx = []; + if (get.is.mountCombined()) { + event.slots.forEach(type => { + if (type == 'equip3' || type == 'equip4') slotsx.add('equip3_4'); + else slotsx.add(type); + }); + } + else { + slotsx.addArray(event.slots); + } + slotsx.sort(); + for (var slot of slotsx) { + var expand = get.numOf(event.slots, slot), slot_key = slot; + if (slot == 'equip3_4') { + expand = Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4')); + slot_key = 'equip3'; + } + game.log(player, '获得了' + get.cnNumber(expand) + '个额外的', '#g' + get.translation(slot) + '栏'); + if (!player.expandedSlots) player.expandedSlots = {}; + if (!player.expandedSlots[slot_key]) player.expandedSlots[slot_key] = 0; + player.expandedSlots[slot_key] += expand; + } + player.$syncExpand(); + }, + //选择顶装备要顶的牌 + replaceEquip: function () { + 'step 0'; + event.cards = []; + var types = get.subtypes(card, false); + if (types.length) { + var info = get.info(card, false); + if (info.customSwap) { + event.cards.addArray(player.getCards('e', function (card) { + return info.customSwap(card); + })); + event.goto(4); + } + else { + event.num = 0; + event.slots = types; + event.slotsx = []; + if (get.is.mountCombined()) { + event.slots.forEach(type => { + if (type == 'equip3' || type == 'equip4') event.slotsx.add('equip3_4'); + else event.slotsx.add(type); + }); + } + else { + event.slotsx.addArray(event.slots); + } + event.slotsx.sort(); + } + } + else event.goto(4); + 'step 1'; + var slot = event.slotsx[event.num]; + var left = player.countEquipableSlot(slot), lose; + if (slot == 'equip3_4') lose = Math.min(left, Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4'))); + else lose = Math.min(left, get.numOf(event.slots, slot)); + if (lose <= 0) event.goto(3); + else { + var cards = player.getEquips(slot).filter(card => { + return !event.cards.includes(card) && lib.filter.canBeReplaced(card, player); + }); + if (cards.length > 0) { + if (lose >= left) { + event._result = { bool: true, links: cards }; + } + else if (cards.length > (left - lose)) { + var source = event.source, num = (cards.length - (left - lose)); + if (!source || !source.isIn()) source = player; + source.chooseButton([ + '选择替换掉' + get.cnNumber(num) + '张' + get.translation(slot) + '牌', + cards, + ], true, [1, num]).set('filterOk', function () { + var evt = _status.event; + return ui.selected.buttons.reduce(function (num, button) { + if (evt.slot == 'equip3_4') return num + Math.max(get.numOf(get.subtypes(button.link, false), 'equip3'), get.numOf(get.subtypes(button.link, false), 'equip4')); + return num + get.numOf(get.subtypes(button.link, false), evt.slot); + }, 0) == evt.required; + }).set('required', num).set('slot', slot); + } + else event.goto(3); + } + else event.goto(3); + } + 'step 2'; + if (result.bool) event.cards.addArray(result.links); + 'step 3'; + event.num++; + if (event.num < event.slotsx.length) event.goto(1); + 'step 4'; + event.result = cards; + }, + //装备牌 + equip: function () { + "step 0"; + var owner = get.owner(card); + if (owner) { + event.owner = owner; + owner.lose(card, ui.special, 'visible').set('type', 'equip').set('getlx', false); + } + else if (get.position(card) == 'c') event.updatePile = true; + "step 1"; + if (event.cancelled) { + event.finish(); + return; + } + if (card.willBeDestroyed('equip', player, event)) { + card.selfDestroy(event); + event.finish(); + return; + } + else if (event.owner) { + if (event.owner.getCards('hejsx').includes(card)) { + event.finish(); + return; + } + } + if (event.draw) { + game.delay(0, 300); + player.$draw(card); + } + "step 2"; + if (card.clone) { + game.broadcast(function (card, player) { + if (card.clone) { + card.clone.moveDelete(player); + } + }, card, player); + card.clone.moveDelete(player); + game.addVideo('gain2', player, get.cardsInfo([card.clone])); + } + player.equiping = true; + "step 3"; + var info = get.info(card, false); + var next = game.createEvent('replaceEquip'); + next.player = player; + next.card = card; + next.setContent(info.replaceEquip || 'replaceEquip'); + "step 4"; + var info = get.info(card, false); + if (get.itemtype(result) == 'cards') { + player.lose(result, 'visible').set('type', 'equip').set('getlx', false).swapEquip = true; + if (info.loseThrow) { + player.$throw(result, 1000); + } + event.swapped = true; + } + "step 5"; + //if(player.isMin() || player.countCards('e',{subtype:get.subtype(card)})){ + if (player.isMin() || !player.canEquip(card)) { + event.finish(); + game.cardsDiscard(card); + delete player.equiping; + return; + } + var subtype = get.subtype(card); + if (subtype == 'equip6') subtype = 'equip3'; + game.broadcastAll(function (type) { + if (lib.config.background_audio) { + game.playAudio('effect', type); + } + }, subtype); + player.$equip(card); + game.addVideo('equip', player, get.cardInfo(card)); + if (event.log != false) game.log(player, '装备了', card); + if (event.updatePile) game.updateRoundNumber(); + "step 6"; + var info = get.info(card, false); + if (info.onEquip && (!info.filterEquip || info.filterEquip(card, player))) { + if (Array.isArray(info.onEquip)) { + for (var i = 0; i < info.onEquip.length; i++) { + var next = game.createEvent('equip_' + card.name); + next.setContent(info.onEquip[i]); + next.player = player; + next.card = card; + } + } + else { + var next = game.createEvent('equip_' + card.name); + next.setContent(info.onEquip); + next.player = player; + next.card = card; + } + if (info.equipDelay != false) game.delayx(); + } + delete player.equiping; + if (event.delay) { + game.delayx(); + } + }, + //装备栏 END + changeGroup: function () { + 'step 0'; + event.originGroup = player.group; + if (!event.group) event.group = player.group; + var group = event.group; + player.getHistory('custom').push(event); + if (event.broadcast !== false) { + game.broadcast(function (player, group) { + player.group = group; + player.node.name.dataset.nature = get.groupnature(group); + }, player, group); + } + player.group = group; + player.node.name.dataset.nature = get.groupnature(group); + if (event.log !== false) game.log(player, '将势力变为了', '#y' + get.translation(group + 2)); + }, + chooseToDebate: function () { + 'step 0'; + event.targets = event.list.filter(function (i) { + return i.countCards('h') > 0; + }); + if (!event.targets.length) event.result = { bool: false }; + else { + var next = player.chooseCardOL(event.targets, get.translation(player) + '发起了议事,请选择展示的手牌', true).set('type', 'debate').set('source', player).set('ai', event.ai || function (card) { + return Math.random(); + }).set('aiCard', event.aiCard || function (target) { + var hs = target.getCards('h'); + return { bool: true, cards: [hs.randomGet()] }; + }); + next._args.remove('glow_result'); + } + 'step 1'; + var red = [], black = []; + event.videoId = lib.status.videoId++; + for (var i = 0; i < event.targets.length; i++) { + var card = result[i].cards[0], target = event.targets[i]; + if (get.color(card, target) == 'red') red.push([target, card]); + else black.push([target, card]); + } + event.red = red; event.black = black; + if (red.length) { + game.log(red.map(function (i) { + return i[0]; + }), '意见为红色,展示了', red.map(function (i) { + return i[1]; + })); + } + else game.log('#b无人', '意见为红色'); + if (black.length) { + game.log(black.map(function (i) { + return i[0]; + }), '意见为', '#g黑色', ',展示了', black.map(function (i) { + return i[1]; + })); + } + else game.log('#b无人', '意见为', '#g黑色'); + game.broadcastAll(function (name, id, redArgs, blackArgs) { + var dialog = ui.create.dialog(name + '发起了议事', 'hidden', 'forcebutton'); + dialog.videoId = id; + dialog.classList.add('scroll1'); + dialog.classList.add('scroll2'); + dialog.classList.add('fullwidth'); + dialog.classList.add('fullheight'); + dialog.buttonss = []; + + var list = ['意见为红色的角色', '意见为黑色的角色']; + for (var i = 0; i < list.length; i++) { + dialog.add('
' + list[i] + '
'); + var buttons = ui.create.div('.buttons', dialog.content); + dialog.buttonss.push(buttons); + buttons.classList.add('popup'); + buttons.classList.add('guanxing'); + } + var func = function (target) { + if (target._tempTranslate) return target._tempTranslate; + var name = target.name; + if (lib.translate[name + '_ab']) return lib.translate[name + '_ab']; + return get.translation(name); + }; + for (var i = 0; i < redArgs.length; i++) { + var list = redArgs[i]; + var button = ui.create.button(list[1], 'card', dialog.buttonss[0]); + button.querySelector('.info').innerHTML = func(list[0]); + } + for (var i = 0; i < blackArgs.length; i++) { + var list = blackArgs[i]; + var button = ui.create.button(list[1], 'card', dialog.buttonss[1]); + button.querySelector('.info').innerHTML = func(list[0]); + } + dialog.open(); + }, get.translation(player), event.videoId, red, black); + game.delay(4); + 'step 2'; + game.broadcastAll('closeDialog', event.videoId); + var opinion = null; + if (event.red.length > event.black.length) opinion = 'red'; + else if (event.red.length < event.black.length) opinion = 'black'; + if (opinion) game.log(player, '本次发起的议事结果为', opinion == 'red' ? '红色' : '#g黑色'); + else game.log(player, '本次发起的议事无结果'); + event.result = { + bool: true, + opinion: opinion, + red: event.red, + black: event.black, + targets: event.targets + }; + 'step 3'; + if (event.callback) { + var next = game.createEvent('debateCallback', false); + next.player = player; + next.debateResult = get.copy(event.result); + next.setContent(event.callback); + } + }, + delay: function () { + game[event.name].apply(game, event._args); + }, + chooseCooperationFor: function () { + 'step 0'; + var next = player.chooseButton([ + '选择和' + get.translation(target) + '的协力方式', + [event.cardlist, 'vcard'], + ], true); + next.set('ai', event.ai || function () { + return Math.random(); + }); + 'step 1'; + if (result.bool) { + player.cooperationWith(target, result.links[0][2].slice(12), event.reason); + } + }, + chooseToPlayBeatmap: function () { + 'step 0'; + if (game.online) return; + if (_status.connectMode) event.time = lib.configOL.choose_timeout; + event.videoId = lib.status.videoId++; + //给其他角色看的演奏框 + game.broadcastAll(function (player, id, beatmap) { + if (_status.connectMode) lib.configOL.choose_timeout = (Math.ceil((beatmap.timeleap[beatmap.timeleap.length - 1] + beatmap.speed * 100 + (beatmap.current || 0)) / 1000) + 5).toString(); + if (player == game.me) return; + var str = get.translation(player) + '正在演奏《' + beatmap.name + '》...'; + if (!_status.connectMode) str += '
(点击屏幕可以跳过等待AI操作)'; + ui.create.dialog(str).videoId = id; + if (ui.backgroundMusic) ui.backgroundMusic.pause(); + if (lib.config.background_audio) { + if (beatmap.filename.startsWith('ext:')) game.playAudio(beatmap.filename); + else game.playAudio('effect', beatmap.filename); + } + }, player, event.videoId, event.beatmap); + 'step 1'; + var beatmap = event.beatmap; + if (event.isMine()) { + var timeleap = beatmap.timeleap.slice(0); + var current = beatmap.current; + //获取两个音符的时间间隔 + var getTimeout = function () { + var time = timeleap.shift(); + var out = time - current; + current = time; + return out; + }; + //初始化一堆变量 + var score = 0; + var added = timeleap.length; + var number_of_tracks = beatmap.number_of_tracks || 6; + var custom_mapping = Array.isArray(beatmap.mapping); + var mapping = custom_mapping ? beatmap.mapping.slice() : beatmap.mapping; + var hitsound = beatmap.hitsound || 'hitsound.wav'; + if (hitsound.startsWith('ext:')) hitsound = lib.assetURL + 'extension/' + hitsound.slice(4); + else hitsound = lib.assetURL + 'audio/effect/' + hitsound; + var hitsound_audio = new Audio(hitsound); + hitsound_audio.volume = 0.25; + var abs = 1; + var node_pos = 0; + if (custom_mapping) { + node_pos = mapping.shift(); + } + else if (mapping == 'random') { + abs = get.rand(number_of_tracks); + node_pos = abs; + } + var combo = 0; + var max_combo = 0; + var nodes = []; + var roundmenu = false; + //隐藏菜单按钮 + if (ui.roundmenu && ui.roundmenu.display != 'none') { + roundmenu = true; + ui.roundmenu.style.display = 'none'; + } + if (ui.backgroundMusic) ui.backgroundMusic.pause(); + var event = _status.event; + event.settleed = false; + //建个框框 + var dialog = ui.create.dialog('forcebutton', 'hidden'); + event.dialog = dialog; + event.dialog.textPrompt = event.dialog.add('
' + (beatmap.prompt || '在音符滑条和底部判定区重合时点击屏幕!') + '
'); + event.switchToAuto = function () { }; + event.dialog.classList.add('fixed'); + event.dialog.classList.add('scroll1'); + event.dialog.classList.add('scroll2'); + event.dialog.classList.add('fullwidth'); + event.dialog.classList.add('fullheight'); + event.dialog.classList.add('noupdate'); + event.dialog.style.overflow = 'hidden'; + //结束后操作 + event.settle = function () { + if (event.settleed) return; + event.settleed = true; + //评分 + var acc = Math.floor(score / (added * 5) * 100); + if (!Array.isArray(lib.config.choose_to_play_beatmap_accuracies)) lib.config.choose_to_play_beatmap_accuracies = []; + lib.config.choose_to_play_beatmap_accuracies.push(acc); + if (lib.config.choose_to_play_beatmap_accuracies.length > 5) lib.config.choose_to_play_beatmap_accuracies.shift(); + game.saveConfigValue("choose_to_play_beatmap_accuracies"); + var rank; + if (acc == 100) rank = ['SS', 'metal']; + else if (acc >= 94) rank = ['S', 'orange']; + else if (acc >= 87) rank = ['A', 'wood']; + else if (acc >= 80) rank = ['B', 'water']; + else if (acc >= 65) rank = ['C', 'thunder']; + else rank = ['D', 'fire']; + event.dialog.textPrompt.innerHTML = '
演奏结束!
最大连击数:' + max_combo + ' 精准度:' + acc + '%
'; + game.me.$fullscreenpop('演奏评级:' + rank[0] + '', null, null, false); + //返回结果并继续游戏 + setTimeout(function () { + event._result = { + bool: true, + accuracy: acc, + rank: rank, + }; + event.dialog.close(); + game.resume(); + _status.imchoosing = false; + if (roundmenu) ui.roundmenu.style.display = ''; + if (ui.backgroundMusic) ui.backgroundMusic.play(); + hitsound_audio.remove(); + }, 1000); + }; + event.dialog.open(); + //操作容差 + var height = event.dialog.offsetHeight; + var width = event.dialog.offsetWidth; + var range1 = (beatmap.range1 || [90, 110]); + var range2 = (beatmap.range2 || [93, 107]); + var range3 = (beatmap.range3 || [96, 104]); + var speed = (beatmap.speed || 25); + //初始化底部的条子 + var judger = ui.create.div(''); + judger.style["background-image"] = (beatmap.judgebar_color || 'linear-gradient(rgba(240, 235, 3, 1), rgba(230, 225, 5, 1))'); + judger.style["border-radius"] = '3px'; + judger.style.position = 'absolute'; + judger.style.opacity = '0.3'; + var heightj = Math.ceil(height * (beatmap.judgebar_height || 0.1)); + judger.style.height = heightj + 'px'; + judger.style.width = width + 'px'; + judger.style.left = '0px'; + judger.style.top = (height - heightj) + 'px'; + event.dialog.appendChild(judger); + //生成每个音符 + var addNode = function () { + var node = ui.create.div(''); + nodes.push(node); + node.style["background-image"] = (beatmap.node_color || 'linear-gradient(rgba(120, 120, 240, 1), rgba(100, 100, 230, 1))'); + node.style["border-radius"] = '3px'; + node.style.position = 'absolute'; + node.style.height = Math.ceil(height / 10) + 'px'; + node.style.width = Math.ceil(width / number_of_tracks) - 10 + 'px'; + node._position = get.utc(); + event.dialog.appendChild(node); + + node.style.left = Math.ceil(width * node_pos / number_of_tracks + 5) + 'px'; + node.style.top = '-' + (Math.ceil(height / 10)) + 'px'; + ui.refresh(node); + node.style.transition = 'all ' + speed * 110 + 'ms linear'; + node.style.transform = 'translateY(' + Math.ceil(height * 1.1) + 'px)'; + node.timeout = setTimeout(function () { + if (nodes.includes(node)) { + nodes.remove(node); + player.popup('Miss', 'fire', false); + if (player.damagepopups.length) player.$damagepop(); + combo = 0; + } + }, speed * 110); + + if (custom_mapping) { + node_pos = mapping.shift(); + } + else if (mapping == 'random') { + while (node_pos == abs) { + node_pos = get.rand(number_of_tracks); + } + abs = node_pos; + } + else { + node_pos += abs; + if (node_pos > number_of_tracks - 1) { + abs = -1; + node_pos = number_of_tracks - 2; + } + else if (node_pos < 0) { + abs = 1; + node_pos = 1; + } + } + if (timeleap.length) { + setTimeout(function () { + addNode(); + }, getTimeout()); + } + else { + setTimeout(function () { + event.settle(); + }, speed * 110 + 100); + } + }; + //点击时的判断操作 + var click = function () { + if (!nodes.length) return; + for (var node of nodes) { + //用生成到点击的时间差来判断距离 + var time = get.utc(); + var top = (time - node._position) / speed; + if (top > range1[1]) continue; + else if (top < range1[0]) return; + nodes.remove(node); + clearTimeout(node.timeout); + node.style.transform = ''; + node.style.transition = 'all 0s'; + node.style.top = (height * ((top - 10) / 100)) + 'px'; + ui.refresh(node); + node.style.transition = 'all 0.5s'; + node.style.transform = 'scale(1.2)'; + node.delete(); + if (top >= range3[0] && top < range3[1]) { + score += 5; + player.popup('Perfect', 'orange', false); + } + else if (top >= range2[0] && top < range2[1]) { + score += 3; + player.popup('Great', 'wood', false); + } + else { + score += 1; + player.popup('Good', 'soil', false); + } + if (player.damagepopups.length) player.$damagepop(); + combo++; + max_combo = Math.max(combo, max_combo); + hitsound_audio.currentTime = 0; + if (hitsound_audio.paused) Promise.resolve(hitsound_audio.play()).catch(() => void 0); + break; + } + }; + document.addEventListener(lib.config.touchscreen ? 'touchstart' : 'mousedown', click); + + game.pause(); + game.countChoose(); + setTimeout(() => { + if (!lib.config.background_audio) return; + if (beatmap.filename.startsWith('ext:')) game.playAudio(beatmap.filename); + else game.playAudio('effect', beatmap.filename); + }, Math.floor(speed * 100 * (0.9 + beatmap.judgebar_height)) + beatmap.current); + setTimeout(function () { + addNode(); + }, getTimeout()); + } + else if (event.isOnline()) { + event.send(); + } + else { + game.pause(); + game.countChoose(); + var settle = function () { + _status.imchoosing = false; + //Algorithm: Generate the random number range using the mean and the half standard deviation of accuracies of the player's last 5 plays + //算法:用玩家的上5次游玩的准确率的平均数和半标准差生成随机数范围 + var choose_to_play_beatmap_accuracies = (lib.config.choose_to_play_beatmap_accuracies || []).concat(Array.from({ + length: 6 - (lib.config.choose_to_play_beatmap_accuracies || []).length + }, () => get.rand(70, 100))); + var mean = Math.round(choose_to_play_beatmap_accuracies.reduce((previousValue, currentValue) => previousValue + currentValue) / choose_to_play_beatmap_accuracies.length); + var half_standard_deviation = Math.round(Math.sqrt(choose_to_play_beatmap_accuracies.reduce((previousValue, currentValue) => previousValue + Math.pow(currentValue - mean, 2), 0)) / 2); + var acc = Math.min(Math.max(get.rand.apply(get, beatmap.aiAcc || [mean - half_standard_deviation - get.rand(0, half_standard_deviation), mean + half_standard_deviation + get.rand(0, half_standard_deviation)]), 0), 100); + var rank; + if (acc == 100) rank = ['SS', 'metal']; + else if (acc >= 94) rank = ['S', 'orange']; + else if (acc >= 87) rank = ['A', 'green']; + else if (acc >= 80) rank = ['B', 'water']; + else if (acc >= 65) rank = ['C', 'thunder']; + else rank = ['D', 'fire']; + event._result = { + bool: true, + accuracy: acc, + rank: rank, + }; + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); + game.resume(); + }; + var song_duration = beatmap.timeleap[beatmap.timeleap.length - 1] + beatmap.speed * 100 + 1000 + (beatmap.current || 0); + var settle_timeout = setTimeout(settle, song_duration); + if (!_status.connectMode) { + var skip_timeout; + var skip = () => { + settle(); + Array.from(ui.window.getElementsByTagName('audio')).forEach(audio => { + if (audio.currentSrc.includes(beatmap.filename.startsWith('ext:') ? beatmap.name : beatmap.filename)) audio.remove(); + }); + document.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip); + clearTimeout(settle_timeout); + clearTimeout(skip_timeout); + }; + document.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip); + skip_timeout = setTimeout(() => document.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip), song_duration); + } + } + 'step 2'; + game.broadcastAll(function (id, time) { + if (_status.connectMode) lib.configOL.choose_timeout = time; + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + if (ui.backgroundMusic) ui.backgroundMusic.play(); + }, event.videoId, event.time); + var result = event.result || result; + event.result = result; + }, + chooseToMove: function () { + 'step 0'; + if (event.chooseTime && _status.connectMode && !game.online) { + event.time = lib.configOL.choose_timeout; + game.broadcastAll(function (time) { + lib.configOL.choose_timeout = time; + }, event.chooseTime); + } + if (event.isMine()) { + delete ui.selected.guanxing_button; + var list = event.list, filterMove = event.filterMove, filterOk = event.filterOk; + _status.imchoosing = true; + var event = _status.event; + event.settleed = false; + event.dialog = ui.create.dialog(event.prompt || '请选择要操作的牌', 'hidden', 'forcebutton'); + event.switchToAuto = function () { + if (!filterOk(event.moved)) { + if (!event.forced) event._result = { bool: false }; + else event._result = 'ai'; + } + else { + event._result = { + bool: true, + moved: event.moved, + }; + } + event.dialog.close(); + if (ui.confirm) ui.confirm.close(); + game.resume(); + _status.imchoosing = false; + setTimeout(function () { + ui.arena.classList.remove('choose-to-move'); + }, 500); + }; + event.dialog.classList.add('scroll1'); + event.dialog.classList.add('scroll2'); + event.dialog.classList.add('fullwidth'); + if (list.length > 1) { + ui.arena.classList.add('choose-to-move'); + event.dialog.classList.add('fullheight'); + } + + event.moved = []; + var buttonss = []; + event.buttonss = buttonss; + var updateButtons = function () { + for (var i of buttonss) { + event.moved[i._link] = get.links(Array.from(i.childNodes)); + if (i.textPrompt) i.previousSibling.innerHTML = ('
' + i.textPrompt(event.moved[i._link]) + '
'); + } + if (filterOk(event.moved)) { + ui.create.confirm('o'); + } + else { + if (!event.forced) ui.create.confirm('c'); + else if (ui.confirm) ui.confirm.close(); + } + }; + var clickButtons = function () { + if (!ui.selected.guanxing_button) return; + if (ui.selected.guanxing_button.parentNode == this) return; + if (!filterMove(ui.selected.guanxing_button, this._link, event.moved)) return; + ui.selected.guanxing_button.classList.remove('glow2'); + this.appendChild(ui.selected.guanxing_button); + delete ui.selected.guanxing_button; + updateButtons(); + }; + + for (var i = 0; i < list.length; i++) { + var tex = event.dialog.add('
' + list[i][0] + '
'); + tex.classList.add('choosetomove'); + var buttons = ui.create.div('.buttons', event.dialog.content, clickButtons); + buttonss.push(buttons); + buttons.classList.add('popup'); + buttons.classList.add('guanxing'); + buttons._link = i; + if (list[i][1]) { + if (get.itemtype(list[i][1]) == 'cards') { + var cardsb = ui.create.buttons(list[i][1], 'card', buttons); + if (list[i][2] && typeof list[i][2] == 'string') { + for (var ij of cardsb) ij.node.gaintag.innerHTML = get.translation(list[i][2]); + } + } + else if (list[i][1].length == 2) { + ui.create.buttons(list[i][1][0], list[i][1][1], buttons); + } + } + if (list[i][2] && typeof list[i][2] == 'function') buttons.textPrompt = list[i][2]; + } + var tex = event.dialog.add('
点击两张牌以交换位置;点击一张牌并点击其他区域以移动卡牌
'); + tex.classList.add('choosetomove'); + + event.dialog.open(); + updateButtons(); + + event.custom.replace.button = function (button) { + var node = button.parentNode; + if (!buttonss.includes(node)) return; + if (!ui.selected.guanxing_button) { + ui.selected.guanxing_button = button; + button.classList.add('glow2'); + return; + } + if (ui.selected.guanxing_button == button) { + button.classList.remove('glow2'); + delete ui.selected.guanxing_button; + return; + } + if (!filterMove(button, ui.selected.guanxing_button, event.moved)) return; + var par1 = ui.selected.guanxing_button.parentNode, ind1 = ui.selected.guanxing_button.nextSibling, par2 = button.parentNode, ind2 = button.nextSibling; + ui.selected.guanxing_button.classList.remove('glow2'); + par1.insertBefore(button, ind1); + par2.insertBefore(ui.selected.guanxing_button, ind2); + delete ui.selected.guanxing_button; + updateButtons(); + }; + event.custom.replace.confirm = function (bool) { + if (bool) event._result = { + bool: true, + moved: event.moved, + }; + else event._result = { bool: false }; + event.dialog.close(); + if (ui.confirm) ui.confirm.close(); + game.resume(); + _status.imchoosing = false; + setTimeout(function () { + ui.arena.classList.remove('choose-to-move'); + }, 500); + }; + + game.pause(); + game.countChoose(); + event.choosing = true; + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + "step 1"; + if (event.time) game.broadcastAll(function (time) { + lib.configOL.choose_timeout = time; + }, event.time); + var result = event.result || result; + if ((!result || result == 'ai' || (event.forced && !result.bool)) && event.processAI) { + var moved = event.processAI(event.list); + if (moved) result = { + bool: true, + moved: moved, + }; + else result = { bool: false }; + } + event.result = result; + }, + showCharacter: function () { + 'step 0'; + event.trigger('showCharacterEnd'); + 'step 1'; + event.trigger('showCharacterAfter'); + if (get.mode() == 'identity' && player.isZhu) event.trigger('zhuUpdate'); + }, + removeCharacter: function () { + player.$removeCharacter(event.num); + }, + chooseUseTarget: function () { + 'step 0'; + if (get.is.object(card) && !event.viewAs) card.isCard = true; + if (cards && get.itemtype(card) != 'card') { + card = get.copy(card); + card.cards = cards.slice(0); + event.card = card; + } + if (!lib.filter.cardEnabled(card, player) || (event.addCount !== false && !lib.filter.cardUsable(card, player))) { + event.result = { bool: false }; + event.finish(); + return; + } + var info = get.info(card); + var range; + if (!info.notarget) { + var select = get.copy(info.selectTarget); + range = get.select(select); + if (event.selectTarget) range = get.select(event.selectTarget); + game.checkMod(card, player, range, 'selectTarget', player); + } + if (info.notarget || range[1] <= -1) { + if (!info.notarget && range[1] <= -1) { + for (var i = 0; i < targets.length; i++) { + if (event.filterTarget) { + if (!event.filterTarget(card, player, targets[i])) { + targets.splice(i--, 1); + } + } + else if (!player.canUse(card, targets[i], event.nodistance ? false : null, event.addCount === false ? null : true)) { + targets.splice(i--, 1); + } + } + if (targets.length) { + event.targets2 = targets; + } + else { + event.finish(); + return; + } + } + else event.targets2 = []; + if (event.forced) { + event._result = { bool: true }; + return; + } + else { + var next = player.chooseBool(); + next.set('prompt', event.prompt || ('是否' + (event.targets2.length ? '对' : '') + get.translation(event.targets2) + '使用' + get.translation(card) + '?')); + if (event.hsskill) next.setHiddenSkill(event.hsskill); + if (event.prompt2) next.set('prompt2', event.prompt2); + next.ai = function () { + var eff = 0; + for (var i = 0; i < event.targets2.length; i++) { + eff += get.effect(event.targets2[i], card, player, player); + } + return eff > 0; + }; + } + } + else { + if (event.filterTarget) { + var targets = game.filterPlayer(function (current) { + return event.filterTarget(card, player, current); + }); + if (targets.length < range[0]) { + event._result = { bool: false }; + return; + } + else if (!info.complexTarget && targets.length == range[0] && range[0] == range[1]) { + event.targets2 = targets; + event._result = { bool: true }; + return; + } + } + var next = player.chooseTarget(); + next.set('_get_card', card); + next.set('filterTarget', event.filterTarget || function (card, player, target) { + if (!_status.event.targets.includes(target)) return false; + if (!_status.event.nodistance && !lib.filter.targetInRange(card, player, target)) return false; + return lib.filter.targetEnabledx(card, player, target); + }); + next.set('ai', event.ai || get.effect_use); + next.set('selectTarget', event.selectTarget || lib.filter.selectTarget); + if (event.nodistance) next.set('nodistance', true); + if (event.forced) next.set('forced', true); + if (event.addCount !== false) next.set('addCount_extra', true); + next.set('targets', targets); + next.set('prompt', event.prompt || ('选择' + get.translation(card) + '的目标')); + if (event.prompt2) next.set('prompt2', event.prompt2); + if (event.hsskill) next.setHiddenSkill(event.hsskill); + } + 'step 1'; + if (result.bool) { + event.result = { + bool: true, + targets: event.targets2 || result.targets, + }; + var args = [card, event.targets2 || result.targets]; + if (cards) args.push(cards.slice()); + var next = player.useCard(...args); + next.oncard = event.oncard; + if (cards) next.cards = cards.slice(0); + if (event.nopopup) next.nopopup = true; + if (event.animate === false) next.animate = false; + if (event.throw === false) next.throw = false; + if (event.addCount === false) next.addCount = false; + if (event.noTargetDelay) next.targetDelay = false; + if (event.nodelayx) next.delayx = false; + if (event.logSkill) { + if (typeof event.logSkill == 'string') { + next.skill = event.logSkill; + } + else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + } + else event.result = { bool: false }; + }, + chooseToDuiben: function () { + 'step 0'; + if (!event.namelist) event.namelist = ['全军出击', '分兵围城', '奇袭粮道', '开城诱敌']; + game.broadcastAll(function (list) { + var list2 = ['db_atk1', 'db_atk2', 'db_def1', 'db_def2']; + for (var i = 0; i < 4; i++) { + lib.card[list2[i]].image = 'card/' + list2[i] + (list[0] == '全军出击' ? '' : '_' + list[i]); + lib.translate[list2[i]] = list[i]; + } + }, event.namelist); + if (!event.title) event.title = '对策'; + game.log(player, '向', target, '发起了', '#y' + event.title); + if (!event.ai) event.ai = function () { return 1 + Math.random(); }; + if (_status.connectMode) { + player.chooseButtonOL([ + [player, [event.title + ':请选择一种策略', [[['', '', 'db_def2'], ['', '', 'db_def1']], 'vcard']], true], + [target, [event.title + ':请选择一种策略', [[['', '', 'db_atk1'], ['', '', 'db_atk2']], 'vcard']], true] + ], function () { }, event.ai).set('switchToAuto', function () { + _status.event.result = 'ai'; + }).set('processAI', function () { + var buttons = _status.event.dialog.buttons; + return { + bool: true, + links: [buttons.randomGet().link], + }; + }); + } + 'step 1'; + if (_status.connectMode) { + event.mes = result[player.playerid].links[0][2]; + event.tes = result[target.playerid].links[0][2]; + event.goto(4); + } + else { + player.chooseButton([event.title + ':请选择一种策略', [[['', '', 'db_def2'], ['', '', 'db_def1']], 'vcard']], true).ai = event.ai; + } + 'step 2'; + event.mes = result.links[0][2]; + target.chooseButton([event.title + ':请选择一种策略', [[['', '', 'db_atk1'], ['', '', 'db_atk2']], 'vcard']], true).ai = event.ai; + 'step 3'; + event.tes = result.links[0][2]; + 'step 4'; + game.broadcast(function () { + ui.arena.classList.add('thrownhighlight'); + }); + ui.arena.classList.add('thrownhighlight'); + game.addVideo('thrownhighlight1'); + target.$compare(game.createCard(event.tes, '', ''), player, game.createCard(event.mes, '', '')); + game.log(target, '选择的策略为', '#g' + get.translation(event.tes)); + game.log(player, '选择的策略为', '#g' + get.translation(event.mes)); + game.delay(0, 1500); + 'step 5'; + var mes = event.mes.slice(6); + var tes = event.tes.slice(6); + var str; + if (mes == tes) { + str = get.translation(player) + event.title + '成功'; + player.popup('胜', 'wood'); + target.popup('负', 'fire'); + game.log(player, '#g胜'); + event.result = { bool: true }; + } + else { + str = get.translation(player) + event.title + '失败'; + target.popup('胜', 'wood'); + player.popup('负', 'fire'); + game.log(target, '#g胜'); + event.result = { bool: false }; + } + event.result.player = event.mes; + event.result.target = event.tes; + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add('center'); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + game.trySkillAudio(event.getParent().name + '_' + (event.result.bool ? 'true' + mes : 'false'), player); + game.delay(2); + 'step 6'; + game.broadcastAll(function () { + ui.arena.classList.remove('thrownhighlight'); + }); + game.addVideo('thrownhighlight2'); + if (event.clear !== false) { + game.broadcastAll(ui.clear); + } + }, + chooseToPSS: function () { + 'step 0'; + game.log(player, '对', target, '发起了猜拳'); + if (_status.connectMode) { + player.chooseButtonOL([ + [player, ['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true], + [target, ['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true] + ], function () { }, function () { return 1 + Math.random(); }).set('switchToAuto', function () { + _status.event.result = 'ai'; + }).set('processAI', function () { + var buttons = _status.event.dialog.buttons; + return { + bool: true, + links: [buttons.randomGet().link], + }; + }); + } + 'step 1'; + if (_status.connectMode) { + event.mes = result[player.playerid].links[0][2]; + event.tes = result[target.playerid].links[0][2]; + event.goto(4); + } + else { + player.chooseButton(['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true).ai = function () { return 1 + Math.random(); }; + } + 'step 2'; + event.mes = result.links[0][2]; + target.chooseButton(['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true).ai = function () { return 1 + Math.random(); }; + 'step 3'; + event.tes = result.links[0][2]; + 'step 4'; + game.broadcast(function () { + ui.arena.classList.add('thrownhighlight'); + }); + ui.arena.classList.add('thrownhighlight'); + game.addVideo('thrownhighlight1'); + player.$compare(game.createCard(event.mes, '', ''), target, game.createCard(event.tes, '', '')); + game.log(player, '选择的手势为', '#g' + get.translation(event.mes)); + game.log(target, '选择的手势为', '#g' + get.translation(event.tes)); + game.delay(0, 1500); + 'step 5'; + var mes = event.mes.slice(4); + var tes = event.tes.slice(4); + var str; + if (mes == tes) { + str = '二人平局'; + player.popup('平', 'metal'); + target.popup('平', 'metal'); + game.log('猜拳的结果为', '#g平局'); + event.result = { tie: true }; + } + else { + if ({ paper: 'stone', scissor: 'paper', stone: 'scissor' }[mes] == tes) { + str = get.translation(player) + '胜利'; + player.popup('胜', 'wood'); + target.popup('负', 'fire'); + game.log(player, '#g胜'); + event.result = { bool: true }; + } + else { + str = get.translation(target) + '胜利'; + target.popup('胜', 'wood'); + player.popup('负', 'fire'); + game.log(target, '#g胜'); + event.result = { bool: false }; + } + } + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add('center'); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + game.delay(2); + 'step 6'; + game.broadcastAll(function () { + ui.arena.classList.remove('thrownhighlight'); + }); + game.addVideo('thrownhighlight2'); + if (event.clear !== false) { + game.broadcastAll(ui.clear); + } + }, + cardsDiscard: function () { + game.getGlobalHistory().cardMove.push(event); + var withPile = false; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed('discardPile', null, event)) { + cards[i].selfDestroy(event); + continue; + } + if (get.position(cards[i], true) == 'c') withPile = true; + cards[i].discard(); + } + if (withPile) game.updateRoundNumber(); + }, + orderingDiscard: function () { + var cards = event.relatedEvent.orderingCards.slice(0); + for (var i = 0; i < cards.length; i++) { + if (get.position(cards[i], true) != 'o') cards.splice(i--, 1); + } + if (cards.length) game.cardsDiscard(cards); + }, + cardsGotoOrdering: function () { + game.getGlobalHistory().cardMove.push(event); + var withPile = false; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed('ordering', null, event)) { + cards[i].selfDestroy(event); + continue; + } + if (get.position(cards[i], true) == 'c') withPile = true; + cards[i].fix(); + ui.ordering.appendChild(cards[i]); + } + if (withPile) game.updateRoundNumber(); + var evt = event.relatedEvent || event.getParent(); + if (!evt.orderingCards) evt.orderingCards = []; + if (!evt.noOrdering && !evt.cardsOrdered) { + evt.cardsOrdered = true; + var next = game.createEvent('orderingDiscard', false, evt.getParent()); + next.relatedEvent = evt; + next.setContent('orderingDiscard'); + } + if (!evt.noOrdering) evt.orderingCards.addArray(cards); + }, + cardsGotoSpecial: function () { + game.getGlobalHistory().cardMove.push(event); + var withPile = false; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed('special', null, event)) { + cards[i].selfDestroy(event); + continue; + } + if (get.position(cards[i], true) == 'c') withPile = true; + cards[i].fix(); + ui.special.appendChild(cards[i]); + } + if (withPile) game.updateRoundNumber(); + if (event.toRenku) { + _status.renku.addArray(cards); + if (_status.renku.length > 6) { + var cards = _status.renku.splice(0, _status.renku.length - 6); + game.log(cards, '从仁库进入了弃牌堆'); + game.cardsDiscard(cards).set('outRange', true).fromRenku = true; + } + game.updateRenku(); + } + }, + cardsGotoPile: function () { + if (event.washCard) { + event.trigger('washCard'); + for (var i = 0; i < lib.onwash.length; i++) { + if (lib.onwash[i]() == 'remove') { + lib.onwash.splice(i--, 1); + } + } + } + game.getGlobalHistory().cardMove.push(event); + if (!event._triggeronly) game.$cardsGotoPile(event); + }, + chooseToEnable: function () { + 'step 0'; + var list = []; + for (var i = 1; i <= 5; i++) { + if (player.hasDisabledSlot(i)) list.push('equip' + i); + } + if (!list.length) event.finish(); + else if (list.length == 1) { + event.list = list; + event._result = { control: list[0] }; + } + else { + var next = player.chooseControl(list); + next.set('prompt', '请选择恢复一个装备栏'); + if (!event.ai) event.ai = function (event, player, list) { + return list.randomGet(); + }; + event.ai = event.ai(event.getParent(), player, list); + next.ai = function () { + return event.ai; + }; + } + 'step 1'; + event.result = { control: result.control }; + player.enableEquip(result.control); + }, + chooseToDisable: function () { + 'step 0'; + var list = []; + for (var i = 1; i <= 5; i++) { + if (player.hasEnabledSlot(i)) list.push('equip' + i); + } + if (event.horse) { + if (list.includes('equip3') && (get.is.mountCombined() || list.includes('equip4'))) list.push('equip3_4'); + list.remove('equip3'); + list.remove('equip4'); + } + if (!list.length) event.finish(); + else if (list.length == 1) { + event.list = list; + event._result = { control: list[0] }; + } + else { + list.sort(); + event.list = list; + var next = player.chooseControl(list); + next.set('prompt', '请选择废除一个装备栏'); + if (!event.ai) event.ai = function (event, player, list) { + return list.randomGet(); + }; + event.ai = event.ai(event.getParent(), player, list); + next.ai = function () { + return event.ai; + }; + } + 'step 1'; + event.result = { control: result.control }; + if (result.control == 'equip3_4') { + player.disableEquip(3, 4); + } + else player.disableEquip(result.control); + }, + swapEquip: function () { + "step 0"; + game.log(player, '和', target, '交换了装备区中的牌'); + event.cards = [player.getCards('e'), target.getCards('e')]; + game.loseAsync({ + player: player, + target: target, + cards1: event.cards[0], + cards2: event.cards[1], + }).setContent('swapHandcardsx'); + "step 1"; + for (var i = 0; i < event.cards[1].length; i++) { + if (get.position(event.cards[1][i], true) == 'o') player.equip(event.cards[1][i]); + } + for (var i = 0; i < event.cards[0].length; i++) { + if (get.position(event.cards[0][i], true) == 'o') target.equip(event.cards[0][i]); + } + }, + disableJudge: function () { + 'step 0'; + game.log(player, '废除了判定区'); + var js = player.getCards('j'); + if (js.length) player.discard(js); + player.storage._disableJudge = true; + //player.markSkill('_disableJudge'); + 'step 1'; + game.broadcastAll(function (player, card) { + player.$disableJudge(); + }, player); + }, + enableJudge: function () { + if (!player.storage._disableJudge) return; + game.log(player, '恢复了判定区'); + game.broadcastAll(function (player) { + player.$enableJudge(); + }, player); + }, + /*----分界线----*/ + phasing: function () { + 'step 0'; + while (ui.dialogs.length) { + ui.dialogs[0].close(); + } + game.phaseNumber++; + player.phaseNumber++; + game.broadcastAll(function (player, player2, num, popup) { + if (lib.config.glow_phase) { + if (player2) player2.classList.remove('glow_phase'); + player.classList.add('glow_phase'); + } + player.phaseNumber = num; + if (popup && lib.config.show_phase_prompt) player.popup('回合开始', null, false); + }, player, _status.currentPhase, player.phaseNumber, !player.noPhaseDelay); + _status.currentPhase = player; + _status.discarded = []; + game.syncState(); + game.addVideo('phaseChange', player); + if (game.phaseNumber == 1) { + delete player._start_cards; + if (lib.configOL.observe) { + lib.configOL.observeReady = true; + game.send('server', 'config', lib.configOL); + } + } + game.log(); + game.log(player, '的回合开始'); + player._noVibrate = true; + if (get.config('identity_mode') != 'zhong' && get.config('identity_mode') != 'purple' && !_status.connectMode) { + var num; + switch (get.config('auto_identity')) { + case 'one': num = 1; break; + case 'two': num = 2; break; + case 'three': num = 3; break; + case 'always': num = -1; break; + default: num = 0; break; + } + if (num && !_status.identityShown && game.phaseNumber > game.players.length * num && game.showIdentity) { + if (!_status.video) player.popup('显示身份'); + _status.identityShown = true; + game.showIdentity(false); + } + } + player.ai.tempIgnore = []; + if (ui.land && ui.land.player == player) { + game.addVideo('destroyLand'); + ui.land.destroy(); + } + 'step 1'; + event.trigger('phaseBeginStart'); + }, + toggleSubPlayer: function () { + 'step 0'; + var list = event.list || player.storage.subplayer.skills.slice(0); + list.remove(player.storage.subplayer.name2); + event.list = list; + if (!event.directresult) { + if (list.length > 1) { + var dialog = ui.create.dialog('更换一个随从', 'hidden'); + dialog.add([list, 'character']); + player.chooseButton(dialog, true); + } + else if (list.length == 1) { + event.directresult = list[0]; + } + else { + event.finish(); + } + } + else { + if (!list.includes(event.directresult)) { + event.finish(); + } + } + 'step 1'; + if (!event.directresult) { + if (result && result.bool && result.links[0]) { + event.directresult = result.links[0]; + } + else { + event.finish(); + return; + } + } + if (player.storage.subplayer) { + var current = player.storage.subplayer.name2; + if (event.directresult == current) { + event.finish(); + return; + } + player.storage[current].hp = player.hp; + player.storage[current].maxHp = player.maxHp; + player.storage[current].hs = player.getCards('h'); + player.storage[current].es = player.getCards('e'); + player.lose(player.getCards('he'), ui.special)._triggered = null; + + var cfg = player.storage[event.directresult]; + player.storage.subplayer.name2 = event.directresult; + player.reinit(current, event.directresult, [ + cfg.hp, + cfg.maxHp + ]); + if (cfg.hs.length) player.directgain(cfg.hs); + if (cfg.es.length) player.directequip(cfg.es); + } + }, + exitSubPlayer: function () { + 'step 0'; + if (player.storage.subplayer) { + var current = player.storage.subplayer.name2; + if (event.remove) { + player.lose(player.getCards('he'), ui.discardPile)._triggered = null; + } + else { + player.storage[current].hp = player.hp; + player.storage[current].maxHp = player.maxHp; + player.storage[current].hs = player.getCards('h'); + player.storage[current].es = player.getCards('e'); + player.lose(player.getCards('he'), ui.special)._triggered = null; + } + player.reinit(current, player.storage.subplayer.name, [ + player.storage.subplayer.hp, + player.storage.subplayer.maxHp + ]); + player.update(); + if (event.remove) { + if (player.storage[current].onremove) { + player.storage[current].onremove(player); + } + delete player.storage[current]; + player.storage.subplayer.skills.remove(current); + game.log(player, '牺牲了随从', '#g' + current); + } + else { + game.log(player, '收回了随从', '#g' + current); + } + player.addSkill(player.storage.subplayer.skills); + } + 'step 1'; + if (player.storage.subplayer) { + player.directgain(player.storage.subplayer.hs); + player.directequip(player.storage.subplayer.es); + } + player.removeSkill('subplayer'); + 'step 2'; + if (event.remove) { + event.trigger('subPlayerDie'); + } + }, + callSubPlayer: function () { + 'step 0'; + var list = player.getSubPlayers(event.tag); + event.list = list; + if (!event.directresult) { + if (list.length > 1) { + var dialog = ui.create.dialog('调遣一个随从', 'hidden'); + dialog.add([list, 'character']); + player.chooseButton(dialog, true); + } + else if (list.length == 1) { + event.directresult = list[0]; + } + else { + event.finish(); + } + } + else { + if (!list.includes(event.directresult)) { + event.finish(); + } + } + 'step 1'; + if (!event.directresult) { + if (result && result.bool && result.links[0]) { + event.directresult = result.links[0]; + } + else { + event.finish(); + return; + } + } + if (event.directresult) { + var cfg = player.storage[event.directresult]; + var source = cfg.source || player.name; + var name = event.directresult; + game.log(player, '调遣了随从', '#g' + name); + player.storage.subplayer = { + name: source, + name2: event.directresult, + hp: player.hp, + maxHp: player.maxHp, + skills: event.list.slice(0), + hs: player.getCards('h'), + es: player.getCards('e'), + intro2: cfg.intro2 + }; + player.removeSkill(event.list); + player.reinit(source, name, [cfg.hp, cfg.maxHp]); + player.addSkill('subplayer'); + player.lose(player.getCards('he'), ui.special)._triggered = null; + if (cfg.hs.length) player.directgain(cfg.hs); + if (cfg.es.length) player.directequip(cfg.es); + } + 'step 2'; + game.delay(); + }, + addExtraTarget: function () { + "step 0"; + event.num = 0; + "step 1"; + var target = targets[num], info = get.info(card); + if (target == event.target && event.addedTarget) { + event.addedTargets[num] = event.addedTarget; + event._result = { bool: false }; + } + else if (game.hasPlayer(function (current) { + return info.filterAddedTarget(card, player, current, target); + })) { + var next = player.chooseTarget(get.translation(event.card) + ':选择' + get.translation(targets[num]) + '对应的指向目标', function (card, player, target) { + var card = get.card(), info = get.info(card); + return info.filterAddedTarget(card, player, target, _status.event.preTarget); + }, true); + next.set('_get_card', card); + next.set('preTarget', targets[num]); + next.set('ai', target => get.effect(target, get.card(), player, _status.event.player)); + } + else { + event.addedTargets[num] = false; + event._result = { bool: false }; + } + "step 2"; + if (result.bool) { + event.addedTargets[num] = result.targets[0]; + player.line2([targets[num], result.targets[0]]); + } + event.num++; + if (event.num < targets.length) event.goto(1); + }, + reverseOrder: function () { + "step 0"; + game.delay(); + "step 1"; + var choice; + if (get.tag(card, 'multineg')) { + choice = (player.previous.side == player.side) ? '逆时针' : '顺时针'; + } + else { + choice = (player.next.side == player.side) ? '逆时针' : '顺时针'; + } + player.chooseControl('顺时针', '逆时针', function (event, player) { + return _status.event.choice || '逆时针'; + }).set('prompt', '选择' + get.translation(card) + '的结算方向').set('choice', choice).set('forceDie', true); + "step 2"; + if (result && result.control == '顺时针') { + var evt = event.getParent(), sorter = (_status.currentPhase || player); + evt.fixedSeat = true; + evt.targets.sortBySeat(sorter); + evt.targets.reverse(); + if (evt.targets[evt.targets.length - 1] == sorter) { + evt.targets.unshift(evt.targets.pop()); + } + } + }, + addJudgeCard: function () { + if (lib.filter.judge(card, player, target) && cards.length && get.position(cards[0], true) == 'o') target.addJudge(card, cards); + }, + equipCard: function () { + if (cards.length && get.position(cards[0], true) == 'o') target.equip(cards[0]); + }, + gameDraw: function () { + "step 0"; + if (_status.brawl && _status.brawl.noGameDraw) { + event.finish(); + return; + } + var end = player; + var numx = num; + do { + if (typeof num == 'function') { + numx = num(player); + } + if (player.getTopCards) player.directgain(player.getTopCards(numx)); + else player.directgain(get.cards(numx)); + if (player.singleHp === true && get.mode() != 'guozhan' && (lib.config.mode != 'doudizhu' || _status.mode != 'online')) { + player.doubleDraw(); + } + player._start_cards = player.getCards('h'); + player = player.next; + } + while (player != end); + event.changeCard = get.config('change_card'); + if (_status.connectMode || (lib.config.mode == 'doudizhu' && _status.mode == 'online') || lib.config.mode != 'identity' && lib.config.mode != 'guozhan' && lib.config.mode != 'doudizhu') { + event.changeCard = 'disabled'; + } + "step 1"; + if (event.changeCard != 'disabled' && !_status.auto) { + event.dialog = ui.create.dialog('是否使用手气卡?'); + ui.create.confirm('oc'); + event.custom.replace.confirm = function (bool) { + _status.event.bool = bool; + game.resume(); + }; + } + else { + event.finish(); + } + "step 2"; + if (event.changeCard == 'once') { + event.changeCard = 'disabled'; + } + else if (event.changeCard == 'twice') { + event.changeCard = 'once'; + } + else if (event.changeCard == 'disabled') { + event.bool = false; + return; + } + _status.imchoosing = true; + event.switchToAuto = function () { + _status.event.bool = false; + game.resume(); + }; + game.pause(); + "step 3"; + _status.imchoosing = false; + if (event.bool) { + if (game.changeCoin) { + game.changeCoin(-3); + } + var hs = game.me.getCards('h'); + game.addVideo('lose', game.me, [get.cardsInfo(hs), [], [], []]); + for (var i = 0; i < hs.length; i++) { + hs[i].discard(false); + } + game.me.directgain(get.cards(hs.length)); + event.goto(2); + } + else { + if (event.dialog) event.dialog.close(); + if (ui.confirm) ui.confirm.close(); + game.me._start_cards = game.me.getCards('h'); + event.finish(); + } + }, + phaseLoop: function () { + "step 0"; + var num = 1, current = player; + while (current.getSeatNum() == 0) { + current.setSeatNum(num); + current = current.next; + num++; + } + "step 1"; + for (var i = 0; i < lib.onphase.length; i++) { + lib.onphase[i](); + } + player.phase(); + "step 2"; + if (!game.players.includes(event.player.next)) { + event.player = game.findNext(event.player.next); + } + else { + event.player = event.player.next; + } + event.goto(1); + }, + loadPackage: function () { + 'step 0'; + if (event.packages.length) { + window.game = game; + var pack = event.packages.shift().split('/'); + lib.init.js(lib.assetURL + pack[0], pack[1], game.resume); + game.pause(); + } + else { + event.finish(); + } + 'step 1'; + if (!lib.config.dev) delete window.game; + var character = lib.imported.character; + var card = lib.imported.card; + var i, j, k; + for (i in character) { + if (character[i].character) { + var characterPack = lib.characterPack[i]; + if (characterPack) Object.assign(characterPack, character[i].character); + else lib.characterPack[i] = character[i].character; + } + if (character[i].forbid && character[i].forbid.includes(lib.config.mode)) continue; + if (character[i].mode && character[i].mode.includes(lib.config.mode) == false) continue; + + if (Array.isArray(lib[j]) && Array.isArray(character[i][j])) { + lib[j].addArray(character[i][j]); + continue; + } + for (j in character[i]) { + if (j == 'mode' || j == 'forbid' || j == 'characterSort') continue; + for (k in character[i][j]) { + if (j == 'character') { + if (!character[i][j][k][4]) { + character[i][j][k][4] = []; + } + if (character[i][j][k][4].includes('boss') || + character[i][j][k][4].includes('hiddenboss')) { + lib.config.forbidai.add(k); + } + if (lib.config.forbidai_user && lib.config.forbidai_user.includes(k)) { + lib.config.forbidai.add(k); + } + for (var l = 0; l < character[i][j][k][3].length; l++) { + lib.skilllist.add(character[i][j][k][3][l]); + } + } + if (j == 'translate' && k == i) { + lib[j][k + '_character_config'] = character[i][j][k]; + } + else { + if (lib[j][k] == undefined) { + Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(character[i][j], k)); + } + else if (Array.isArray(lib[j][k]) && Array.isArray(character[i][j][k])) { + lib[j][k].addArray(character[i][j][k]); + } + else { + console.log( + `dublicate ${j} in character ${i}:\n${k}:\nlib.${j}.${k}`, + lib[j][k], + `\ncharacter.${i}.${j}.${k}`, + character[i][j][k] + ); + } + } + } + } + } + for (i in card) { + var cardPack = lib.cardPack[i] ? lib.cardPack[i] : lib.cardPack[i] = []; + if (card[i].card) { + for (var j in card[i].card) { + if (!card[i].card[j].hidden && card[i].translate[j + '_info']) { + cardPack.push(j); + } + } + } + for (j in card[i]) { + if (j == 'mode' || j == 'forbid') continue; + if (j == 'list') continue; + for (k in card[i][j]) { + if (j == 'skill' && k[0] == '_' && !lib.config.cards.includes(i)) { + continue; + } + if (j == 'translate' && k == i) { + lib[j][k + '_card_config'] = card[i][j][k]; + } + else { + if (lib[j][k] == undefined) Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(card[i][j], k)); + else { + console.log( + `dublicate ${j} in card ${i}:\n${k}\nlib.${j}.${k}`, + lib[j][k], + `\ncard.${i}.${j}.${k}`, + card[i][j][k] + ); + } + } + } + } + } + event.goto(0); + }, + loadMode: function () { + 'step 0'; + window.game = game; + lib.init.js(lib.assetURL + 'mode', event.mode, game.resume); + game.pause(); + 'step 1'; + if (!lib.config.dev) delete window.game; + event.result = lib.imported.mode[event.mode]; + delete lib.imported.mode[event.mode]; + }, + forceOver: function () { + 'step 0'; + while (ui.controls.length) { + ui.controls[0].close(); + } + while (ui.dialogs.length) { + ui.dialogs[0].close(); + } + 'step 1'; + if (event.bool != 'noover') { + game.over(event.bool); + } + if (event.callback) { + event.callback(); + } + }, + arrangeTrigger: function () { + 'step 0'; + event.doing = event.doingList[0]; + if (event.doing && event.doing.todoList.length) return; + if (event.doingList.length) { + event.doingList.shift(); + return event.redo(); + } + event.finish(); + 'step 1'; + if (trigger.filterStop && trigger.filterStop()) return event.finish(); + event.current = event.doing.todoList.find(info => lib.filter.filterTrigger(trigger, info.player, event.triggername, info.skill)); + if (!event.current) { + event.doing.todoList = []; + return event.goto(0); + } + event.doing.todoList = event.doing.todoList.filter(i => i.priority <= event.current.priority); + + const directUse = info => lib.skill[info.skill].silent || !lib.translate[info.skill];//是否不触发同顺序选择 + if (directUse(event.current)) return event.goto(4); + event.choice = event.doing.todoList.filter(info => { + if (!lib.filter.filterTrigger(trigger, info.player, event.triggername, info.skill)) return false; + if (directUse(info)) return false; + if (event.current.player !== info.player) return false; + return lib.skill.global.includes(info.skill) || event.current.player.hasSkill(info.skill, true); + }); + if (event.choice.length < 2) return event.goto(4); + 'step 2'; + const next = event.choice[0].player.chooseControl(event.choice.map(i => i.skill)); + next.set('prompt', '选择下一个触发的技能'); + next.set('forceDie', true); + next.set('arrangeSkill', true); + next.set('includeOut', true); + 'step 3'; + if (result.control) event.current = event.doing.todoList.find(info => info.skill == result.control && info.player == event.choice[0].player); + 'step 4'; + if (!event.current || !event.doing.todoList.includes(event.current)) return; + event.doing.doneList.push(event.current); + event.doing.todoList.remove(event.current); + game.createTrigger(event.triggername, event.current.skill, event.current.player, trigger); + event.goto(0); + }, + createTrigger: function () { + "step 0"; + // console.log('triggering: ' + player.name+ ' \'s skill: ' + event.skill+' in ' + event.triggername) + if (game.expandSkills(player.getSkills().concat(lib.skill.global)).includes(event.skill)) return; + var info = get.info(event.skill); + let hidden = player.hiddenSkills.slice(0); + let invisible = player.invisibleSkills.slice(0); + game.expandSkills(hidden); + game.expandSkills(invisible); + if (hidden.includes(event.skill)) { + if (!info.silent && player.hasSkillTag('nomingzhi', false, null, true)) event.finish(); + else if (!info.direct) event.trigger('triggerHidden'); + else event.skillHidden = true; + } + else if (invisible.includes(event.skill)) event.trigger('triggerInvisible'); + else if (Object.keys(player.additionalSkills).every(i => { + if (i.startsWith('hidden:')) return true; + return !game.expandSkills(player.additionalSkills[i]).includes(event.skill); + })) event.finish(); + "step 1"; + if (event.cancelled) return event.finish(); + var info = get.info(event.skill); + if (event.revealed || info.forced) return; + const checkFrequent = function (info) { + if (player.hasSkillTag('nofrequent', false, event.skill)) return false; + if (typeof info.frequent == 'boolean') return info.frequent; + if (typeof info.frequent == 'function') return info.frequent(trigger, player); + if (info.frequent == 'check' && typeof info.check == 'function') return info.check(trigger, player); + return false; + }; + if (info.direct) { + if (player.isUnderControl()) game.swapPlayerAuto(player); + if (player.isOnline()) void 0; + event._result = { bool: true }; + event._direct = true; + } + else { + if (checkFrequent(info)) event.frequentSkill = true; + var str; + var check = info.check; + if (info.prompt) str = info.prompt; + else if (typeof info.logTarget == 'string') str = get.prompt(event.skill, trigger[info.logTarget], player); + else if (typeof info.logTarget == 'function') { + const logTarget = info.logTarget(trigger, player); + if (get.itemtype(logTarget).startsWith('player')) str = get.prompt(event.skill, logTarget, player); + } + else str = get.prompt(event.skill, null, player); + if (typeof str == 'function') str = str(trigger, player); + + var next = player.chooseBool(str); + if (event.frequentSkill) next.set('frequentSkill', event.skill); + next.set('forceDie', true); + next.set('includeOut', true); + next.ai = () => !check || check(trigger, player); + + if (typeof info.prompt2 == 'function') next.set('prompt2', info.prompt2(trigger, player)); + else if (typeof info.prompt2 == 'string') next.set('prompt2', info.prompt2); + else if (info.prompt2 != false) { + if (lib.dynamicTranslate[event.skill]) next.set('prompt2', lib.dynamicTranslate[event.skill](player, event.skill)); + else if (lib.translate[event.skill + '_info']) next.set('prompt2', lib.translate[event.skill + '_info']); + } + + if (trigger.skillwarn) { + if (next.prompt2) next.set('prompt2', '' + trigger.skillwarn + '。' + next.prompt2); + else next.set('prompt2', trigger.skillwarn); + } + } + "step 2"; + var info = get.info(event.skill); + if (!result || !result.bool) return; + var autodelay = info.autodelay; + if (typeof autodelay == 'function') autodelay = autodelay(trigger, player); + if (autodelay && (info.forced || !event.isMine())) { + if (typeof autodelay == 'number') game.delayx(autodelay); + else game.delayx(); + } + "step 3"; + var info = get.info(event.skill); + if (result && result.bool == false) { + if (info.oncancel) info.oncancel(trigger, player); + return event.finish(); + } + if (info.popup != false && !info.direct) { + if (info.popup) { + player.popup(info.popup); + game.log(player, '发动了', '【' + get.skillTranslation(event.skill, player) + '】'); + } + else if (!info.logTarget || info.logLine === false) player.logSkill(event.skill, false, info.line); + else if (typeof info.logTarget == 'string') player.logSkill(event.skill, trigger[info.logTarget], info.line); + else if (typeof info.logTarget == 'function') player.logSkill(event.skill, info.logTarget(trigger, player), info.line); + } + var next = game.createEvent(event.skill); + if (typeof info.usable == 'number') { + player.addSkill('counttrigger'); + if (!player.storage.counttrigger) player.storage.counttrigger = {}; + if (!player.storage.counttrigger[event.skill]) player.storage.counttrigger[event.skill] = 1; + else player.storage.counttrigger[event.skill]++; + } + next.player = player; + next._trigger = trigger; + next.triggername = event.triggername; + + if ("contents" in info && Array.isArray(info.contents)) { + next.setContents(info.contents); + } else { + next.setContent(info.content); + } + + next.skillHidden = event.skillHidden; + if (info.forceDie) next.forceDie = true; + if (info.forceOut) next.includeOut = true; + "step 4"; + if (!player._hookTrigger) return; + if (player._hookTrigger.some(i => { + const info = lib.skill[i].hookTrigger; + return info && info.after && info.after(event, player, event.triggername); + })) event.trigger('triggerAfter'); + }, + playVideoContent: function () { + 'step 0'; + game.delay(0, 500); + 'step 1'; + if (!game.chess) { + ui.control.innerHTML = ''; + var nodes = []; + for (var i = 0; i < ui.arena.childNodes.length; i++) { + nodes.push(ui.arena.childNodes[i]); + } + for (var i = 0; i < nodes.length; i++) { + if (nodes[i] == ui.canvas) continue; + if (nodes[i] == ui.control) continue; + if (nodes[i] == ui.mebg) continue; + if (nodes[i] == ui.me) continue; + if (nodes[i] == ui.roundmenu) continue; + nodes[i].remove(); + } + ui.sidebar.innerHTML = ''; + ui.cardPile.innerHTML = ''; + ui.discardPile.innerHTML = ''; + ui.special.innerHTML = ''; + ui.ordering.innerHTML = ''; + } + ui.system.firstChild.innerHTML = ''; + ui.system.lastChild.innerHTML = ''; + ui.system.firstChild.appendChild(ui.config2); + if (ui.updateVideoMenu) { + ui.updateVideoMenu(); + } + _status.videoDuration = 1; + ui.create.system('返回', function () { + var mode = localStorage.getItem(lib.configprefix + 'playbackmode'); + if (mode) { + game.saveConfig('mode', mode); + } + game.reload(); + }); + ui.create.system('重播', function () { + _status.replayvideo = true; + game.playVideo(_status.playback, lib.config.mode); + }); + ui.create.system('暂停', ui.click.pause, true).id = 'pausebutton'; + var slow = ui.create.system('减速', function () { + _status.videoDuration *= 1.5; + updateDuration(); + }, true); + var fast = ui.create.system('加速', function () { + _status.videoDuration /= 1.5; + updateDuration(); + }, true); + var updateDuration = function () { + if (_status.videoDuration > 1) { + slow.classList.add('glow'); + } + else { + slow.classList.remove('glow'); + } + if (_status.videoDuration < 1) { + fast.classList.add('glow'); + } + else { + fast.classList.remove('glow'); + } + }; + ui.system.style.display = ''; + ui.refresh(ui.system); + ui.system.show(); + ui.window.show(); + if (lib.config.mode != 'versus' && lib.config.mode != 'boss') { + ui.arena.style.display = ''; + ui.refresh(ui.arena); + ui.arena.show(); + } + if (!game.chess) { + game.playerMap = {}; + } + game.finishCards(); + 'step 2'; + if (event.video.length) { + var content = event.video.shift(); + // console.log(content); + if (content.type == 'delay') { + game.delay(content.content); + } + else if (content.type == 'play') { + window.play = {}; + if (!event.playtoload) { + event.playtoload = 1; + } + else { + event.playtoload++; + } + var script = lib.init.js(lib.assetURL + 'play', content.name); + script.addEventListener('load', function () { + var play = window.play[content.name]; + if (play && play.video) { + play.video(content.init); + } + event.playtoload--; + if (event.playtoload == 0) { + delete window.play; + } + }); + } + else if (typeof content.player == 'string' && game.playerMap[content.player] && + game.playerMap[content.player].classList && + !game.playerMap[content.player].classList.contains('obstacle')) { + game.videoContent[content.type](game.playerMap[content.player], content.content); + } + else { + game.videoContent[content.type](content.content); + } + if (event.video.length) { + game.delay(0, _status.videoDuration * Math.min(2000, event.video[0].delay)); + } + event.redo(); + } + else { + _status.over = true; + ui.system.lastChild.hide(); + setTimeout(function () { + ui.system.lastChild.innerHTML = ''; + }, 500); + } + }, + waitForPlayer: function () { + 'step 0'; + ui.auto.hide(); + ui.pause.hide(); + + game.createServer(); + if (!lib.translate.zhu) { + lib.translate.zhu = '主'; + } + if (event.func) { + event.func(); + } + if (!lib.configOL.number) { + lib.configOL.number = parseInt(lib.configOL.player_number); + } + if (game.onlineroom) { + game.send('server', 'config', lib.configOL); + } + + ui.create.connectPlayers(game.ip); + if (!window.isNonameServer) { + var me = game.connectPlayers[0]; + me.setIdentity('zhu'); + me.initOL(get.connectNickname(), lib.config.connect_avatar); + me.playerid = '1'; + game.onlinezhu = '1'; + } + _status.waitingForPlayer = true; + if (window.isNonameServer) { + document.querySelector('#server_status').innerHTML = '等待中'; + } + game.pause(); + 'step 1'; + _status.waitingForPlayer = false; + lib.configOL.gameStarted = true; + if (window.isNonameServer) { + document.querySelector('#server_status').innerHTML = '游戏中'; + } + if (game.onlineroom) { + game.send('server', 'config', lib.configOL); + } + for (var i = 0; i < game.connectPlayers.length; i++) { + game.connectPlayers[i].delete(); + } + delete game.connectPlayers; + if (ui.roomInfo) { + ui.roomInfo.remove(); + delete ui.roomInfo; + } + if (ui.exitroom) { + ui.exitroom.remove(); + delete ui.exitroom; + } + game.broadcast('gameStart'); + game.delay(2); + ui.auto.show(); + ui.pause.show(); + if (lib.config.show_cardpile) { + ui.cardPileButton.style.display = ''; + } + }, + replaceHandcards: function () { + 'step 0'; + if (event.players.includes(game.me)) { + game.me.chooseBool('是否置换手牌?'); + } + else { + event.finish(); + } + 'step 1'; + if (result && result.bool) { + var hs = game.me.getCards('h'); + for (var i = 0; i < hs.length; i++) { + hs[i].discard(false); + } + var cards = get.cards(hs.length); + game.me._start_cards = cards; + game.me.directgain(cards); + } + }, + replaceHandcardsOL: function () { + 'step 0'; + var send = function () { + game.me.chooseBool('是否置换手牌?'); + game.resume(); + }; + var sendback = function (result, player) { + if (result && result.bool) { + var hs = player.getCards('h'); + game.broadcastAll(function (player, hs) { + game.addVideo('lose', player, [get.cardsInfo(hs), [], [], []]); + for (var i = 0; i < hs.length; i++) { + hs[i].discard(false); + } + }, player, hs); + var cards = get.cards(hs.length); + player.directgain(cards); + player._start_cards = cards; + } + }; + for (var i = 0; i < event.players.length; i++) { + if (event.players[i].isOnline()) { + event.withol = true; + event.players[i].send(send); + event.players[i].wait(sendback); + } + else if (event.players[i] == game.me) { + event.withme = true; + game.me.chooseBool('是否置换手牌?'); + game.me.wait(sendback); + } + } + 'step 1'; + if (event.withme) { + game.me.unwait(result); + } + 'step 2'; + if (event.withol && !event.resultOL) { + game.pause(); + } + }, + /** + * @deprecated + */ + phase: function () { + 'step 0'; + //初始化阶段列表 + if (!event.phaseList) { + event.phaseList = ['phaseZhunbei', 'phaseJudge', 'phaseDraw', 'phaseUse', 'phaseDiscard', 'phaseJieshu']; + } + if (typeof event.num != 'number') { + event.num = 0; + } + //规则集中的“回合开始后①”,更新游戏轮数,触发“一轮游戏开始时” + var isRound = false; + if (!event.skill) { + isRound = _status.roundSkipped; + if (_status.isRoundFilter) { + isRound = _status.isRoundFilter(event, player); + } + else if (_status.seatNumSettled) { + var seatNum = player.getSeatNum(); + if (seatNum != 0) { + if (get.itemtype(_status.lastPhasedPlayer) != 'player' || seatNum < _status.lastPhasedPlayer.getSeatNum()) isRound = true; + _status.lastPhasedPlayer = player; + } + } + else if (player == _status.roundStart) isRound = true; + if (isRound) { + delete _status.roundSkipped; + game.roundNumber++; + event._roundStart = true; + game.updateRoundNumber(); + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isOut() && game.players[i].outCount > 0) { + game.players[i].outCount--; + if (game.players[i].outCount == 0 && !game.players[i].outSkills) { + game.players[i].in(); + } + } + } + event.trigger('roundStart'); + } + } + _status.globalHistory.push({ + cardMove: [], + custom: [], + useCard: [], + changeHp: [], + everything: [], + }); + var players = game.players.slice(0).concat(game.dead); + for (var i = 0; i < players.length; i++) { + var current = players[i]; + current.actionHistory.push({ useCard: [], respond: [], skipped: [], lose: [], gain: [], sourceDamage: [], damage: [], custom: [], useSkill: [] }); + current.stat.push({ card: {}, skill: {} }); + if (isRound) { + current.getHistory().isRound = true; + current.getStat().isRound = true; + } + } + if (isRound) { + game.getGlobalHistory().isRound = true; + } + 'step 1'; + //规则集中的“回合开始后②(1v1武将登场专用)” + event.trigger('phaseBeforeStart'); + 'step 2'; + //规则集中的“回合开始后③(处理“游戏开始时”的时机)” + event.trigger('phaseBefore'); + 'step 3'; + //规则集中的“回合开始后④(卑弥呼〖纵傀〗的时机)” + event.trigger('phaseBeforeEnd'); + 'step 4'; + //规则集中的“回合开始后⑤”,进行翻面检测 + if (player.isTurnedOver() && !event._noTurnOver) { + event.cancel(); + player.turnOver(); + player.phaseSkipped = true; + } + else { + player.phaseSkipped = false; + player.getHistory().isMe = true; + player.getStat().isMe = true; + } + 'step 5'; + //规则集中的“回合开始后⑥”,更新“当前回合角色” + while (ui.dialogs.length) { + ui.dialogs[0].close(); + } + game.phaseNumber++; + player.phaseNumber++; + game.broadcastAll(function (player, num, popup) { + if (lib.config.glow_phase) { + player.classList.add('glow_phase'); + } + player.phaseNumber = num; + _status.currentPhase = player; + if (popup && lib.config.show_phase_prompt) player.popup('回合开始', null, false); + }, player, player.phaseNumber, !player.noPhaseDelay); + _status.currentPhase = player; + _status.discarded = []; + game.syncState(); + game.addVideo('phaseChange', player); + if (game.phaseNumber == 1) { + delete player._start_cards; + if (lib.configOL.observe) { + lib.configOL.observeReady = true; + game.send('server', 'config', lib.configOL); + } + } + game.log(); + game.log(player, '的回合开始'); + player._noVibrate = true; + if (get.config('identity_mode') != 'zhong' && get.config('identity_mode') != 'purple' && !_status.connectMode) { + var num; + switch (get.config('auto_identity')) { + case 'one': num = 1; break; + case 'two': num = 2; break; + case 'three': num = 3; break; + case 'always': num = -1; break; + default: num = 0; break; + } + if (num && !_status.identityShown && game.phaseNumber > game.players.length * num && game.showIdentity) { + if (!_status.video) player.popup('显示身份'); + _status.identityShown = true; + game.showIdentity(false); + } + } + player.ai.tempIgnore = []; + if (ui.land && ui.land.player == player) { + game.addVideo('destroyLand'); + ui.land.destroy(); + } + 'step 6'; + //规则集中的“回合开始后⑦”,国战武将明置武将牌 + event.trigger('phaseBeginStart'); + 'step 7'; + //规则集中的“回合开始后⑨”,进行当先,化身等操作 + //没有⑧ 因为⑧用不到 + event.trigger('phaseBegin'); + //阶段部分 + 'step 8'; + if (num < event.phaseList.length) { + //规则集中没有的新时机 可以用来插入额外阶段啥的 + if (player.isIn()) event.trigger('phaseChange'); + } + else event.goto(11); + 'step 9'; + if (player.isIn() && num < event.phaseList.length) { + var phase = event.phaseList[num].split('|'); + event.currentPhase = phase[0]; + var next = player[event.currentPhase](); + next.phaseIndex = num; + if (phase.length > 1) { + next._extraPhaseReason = phase[1]; + } + if (event.currentPhase == 'phaseDraw' || event.currentPhase == 'phaseDiscard') { + if (!player.noPhaseDelay) { + if (player == game.me) { + game.delay(); + } + else { + game.delayx(); + } + } + } + } + 'step 10'; + if (event.currentPhase == 'phaseUse') { + game.broadcastAll(function () { + if (ui.tempnowuxie) { + ui.tempnowuxie.close(); + delete ui.tempnowuxie; + } + }); + delete player._noSkill; + } + event.num++; + 'step 11'; + if (event.num < event.phaseList.length) { + event.goto(8); + } + else if (!event._phaseEndTriggered) { + event._phaseEndTriggered = true; + event.trigger('phaseEnd'); + event.redo(); + } + 'step 12'; + event.trigger('phaseAfter'); + 'step 13'; + //删除当前回合角色 此时处于“不属于任何角色的回合”的阶段 + game.broadcastAll(function (player) { + player.classList.remove('glow_phase'); + delete _status.currentPhase; + }, player); + }, + /** + * @deprecated + */ + phase_old: function () { + "step 0"; + player.phaseZhunbei(); + "step 1"; + player.phaseJudge(); + "step 2"; + player.phaseDraw(); + if (!player.noPhaseDelay) { + if (player == game.me) { + game.delay(); + } + else { + game.delayx(); + } + } + "step 3"; + player.phaseUse(); + "step 4"; + game.broadcastAll(function () { + if (ui.tempnowuxie) { + ui.tempnowuxie.close(); + delete ui.tempnowuxie; + } + }); + player.phaseDiscard(); + if (!player.noPhaseDelay) game.delayx(); + //delete player.using; + delete player._noSkill; + "step 5"; + player.phaseJieshu(); + }, + phaseZhunbei: function () { + event.trigger(event.name); + game.log(player, '进入了准备阶段'); + }, + phaseJudge: function () { + "step 0"; + game.log(player, '进入了判定阶段'); + event.cards = player.getCards('j'); + if (!event.cards.length) event.finish(); + "step 1"; + if (cards.length && player.getCards('j').includes(cards[0])) { + event.card = cards.shift(); + if (event.card.classList.contains('removing')) { + event.card.remove(); + delete event.card; + event.redo(); + } + else if (event.card.classList.contains('feichu')) { + event.finish(); + return; + } + else { + player.lose(event.card, 'visible', ui.ordering); + player.$phaseJudge(event.card); + event.cancelled = false; + event.trigger('phaseJudge'); + var name = event.card.viewAs || event.card.name; + player.popup(name, 'thunder'); + if (!lib.card[name].effect) { + game.delay(); + event.redo(); + } + else if (!lib.card[name].judge) { + game.delay(); + event.nojudge = true; + } + } + } + else event.finish(); + "step 2"; + if (!event.cancelled && !event.nojudge) player.judge(event.card).set('type', 'phase'); + "step 3"; + var name = event.card.viewAs || event.card.name; + if (event.excluded) { + delete event.excluded; + } + else if (event.cancelled && !event.direct) { + if (lib.card[name].cancel) { + var next = game.createEvent(name + 'Cancel'); + next.setContent(lib.card[name].cancel); + next.cards = [event.card]; + if (!event.card.viewAs) next.card = get.autoViewAs(event.card); + else next.card = get.autoViewAs({ name: name }, next.cards); + next.player = player; + } + } + else { + var next = game.createEvent(name); + next.setContent(lib.card[name].effect); + next._result = result; + next.cards = [event.card]; + if (!event.card.viewAs) next.card = get.autoViewAs(event.card); + else next.card = get.autoViewAs({ name: name }, next.cards); + next.player = player; + } + ui.clear(); + event.goto(1); + }, + /** + * @deprecated + */ + phaseDraw: function () { + "step 0"; + game.log(player, '进入了摸牌阶段'); + event.trigger("phaseDrawBegin1"); + "step 1"; + event.trigger("phaseDrawBegin2"); + "step 2"; + if (game.modPhaseDraw) { + game.modPhaseDraw(player, event.num); + } + else { + if (event.num > 0) { + var num = event.num; + if (event.attachDraw) { + for (var i = 0; i < event.attachDraw.length; i++) { + ui.cardPile.insertBefore(event.attachDraw[i], ui.cardPile.firstChild); + } + num += event.attachDraw.length; + } + var next = player.draw(num); + if (event.attachDraw) { + next.minnum = event.attachDraw.length; + } + } + } + "step 3"; + if (Array.isArray(result)) { + event.cards = result; + } + }, + phaseUse: function () { + "step 0"; + if (!event.logged) { + game.log(player, '进入了出牌阶段'); + event.logged = true; + } + var next = player.chooseToUse(); + if (!lib.config.show_phaseuse_prompt) { + next.set('prompt', false); + } + next.set('type', 'phase'); + "step 1"; + if (result.bool && !event.skipped) { + event.goto(0); + } + game.broadcastAll(function () { + if (ui.tempnowuxie) { + ui.tempnowuxie.close(); + delete ui.tempnowuxie; + } + }); + "step 2"; + var stat = player.getStat(); + for (var i in stat.skill) { + var bool = false; + var info = lib.skill[i]; + if (!info) continue; + if (info.enable != undefined) { + if (typeof info.enable == 'string' && info.enable == 'phaseUse') bool = true; + else if (typeof info.enable == 'object' && info.enable.includes('phaseUse')) bool = true; + } + if (bool) stat.skill[i] = 0; + } + for (var i in stat.card) { + var bool = false; + var info = lib.card[i]; + if (!info) continue; + if (info.updateUsable == 'phaseUse') stat.card[i] = 0; + } + }, + phaseDiscard: function () { + "step 0"; + game.log(player, '进入了弃牌阶段'); + event.num = player.needsToDiscard(); + if (event.num <= 0) event.finish(); + else { + game.broadcastAll(function (player) { + if (lib.config.show_phase_prompt) { + player.popup('弃牌阶段', null, false); + } + }, player); + } + event.trigger('phaseDiscard'); + "step 1"; + player.chooseToDiscard(num, true) + .set('useCache', true); + "step 2"; + event.cards = result.cards; + }, + phaseJieshu: function () { + event.trigger(event.name); + game.log(player, '进入了结束阶段'); + }, + chooseToUse: function () { + "step 0"; + if (event.responded) return; + if (game.modeSwapPlayer && !_status.auto && player.isUnderControl() && !lib.filter.wuxieSwap(event)) { + game.modeSwapPlayer(player); + } + var skills = player.getSkills('invisible').concat(lib.skill.global); + game.expandSkills(skills); + for (var i = 0; i < skills.length; i++) { + var info = lib.skill[skills[i]]; + if (info && info.onChooseToUse) { + info.onChooseToUse(event); + } + } + if (_status.noclearcountdown !== 'direct') _status.noclearcountdown = true; + if (event.type == 'phase') { + if (event.isMine()) { + event.endButton = ui.create.control('结束回合', 'stayleft', function () { + var evt = _status.event; + if (evt.name != 'chooseToUse' || evt.type != 'phase') return; + if (evt.skill) { + ui.click.cancel(); + } + ui.click.cancel(); + }); + event.fakeforce = true; + } + else { + if (event.endButton) { + event.endButton.close(); + delete event.endButton; + } + event.fakeforce = false; + } + } + if (event.player.isUnderControl() && !_status.auto) { + event.result = { + bool: false + }; + return; + } + else if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + if (event.type == 'wuxie') { + if (ui.tempnowuxie) { + var triggerevent = event.getTrigger(); + if (triggerevent && triggerevent.targets && triggerevent.num == triggerevent.targets.length - 1) { + ui.tempnowuxie.close(); + } + } + if (lib.filter.wuxieSwap(event)) { + event.result = { + bool: false + }; + return; + } + } + var ok = game.check(); + if (!ok || !lib.config.auto_confirm) { + game.pause(); + if (lib.config.enable_vibrate && player._noVibrate) { + delete player._noVibrate; + game.vibrate(); + } + if (typeof event.prompt == 'string') { + if (event.openskilldialog) { + event.skillDialog = ui.create.dialog(event.openskilldialog); + delete event.openskilldialog; + event.dialog = event.prompt; + } + else { + event.dialog = ui.create.dialog(event.prompt); + if (event.prompt2) { + event.dialog.addText(event.prompt2); + } + } + } + else if (typeof event.prompt == 'function') { + event.dialog = ui.create.dialog(event.prompt(event)); + } + else if (event.prompt == undefined) { + var str; + if (typeof event.filterCard == 'object') { + var filter = event.filterCard; + str = '请使用' + get.cnNumber(event.selectCard[0]) + '张'; + if (filter.name) { + str += get.translation(filter.name); + } + else { + str += '牌'; + } + } + else { + str = '请选择要使用的牌'; + } + if (event.openskilldialog) { + event.skillDialog = ui.create.dialog(event.openskilldialog); + delete event.openskilldialog; + event.dialog = str; + } + else if (typeof event.skillDialog != 'string') { + event.dialog = ui.create.dialog(str); + } + else { + event.dialog = str; + } + } + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + "step 1"; + if (event.result == 'ai') { + var ok = game.check(); + if (ok) { + ui.click.ok(); + } + else if (ai.basic.chooseCard(event.ai1) || forced) { + if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + event._aiexcludeclear = true; + } + else { + if (!event.norestore) { + if (event.skill) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + var info = get.info(skill); + if (info.sourceSkill) { + event._aiexclude.add(info.sourceSkill); + } + } + else { + get.card(true).aiexclude(); + game.uncheck(); + } + event.redo(); + game.resume(); + } + else { + ui.click.cancel(); + } + } + } + else if (event.skill && !event.norestore) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + var info = get.info(skill); + if (info.sourceSkill) { + event._aiexclude.add(info.sourceSkill); + } + event.redo(); + game.resume(); + } + else { + ui.click.cancel(); + } + if (event.aidelay && event.result && event.result.bool) { + game.delayx(); + } + } + "step 2"; + if (event.endButton) { + event.endButton.close(); + delete event.endButton; + } + event.resume(); + if (event.result) { + if (event.result._sendskill) { + lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; + } + if (event.result.skill) { + var info = get.info(event.result.skill); + if (info && info.chooseButton) { + if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); + var dialog = info.chooseButton.dialog(event, player); + if (info.chooseButton.chooseControl) { + var next = player.chooseControl(info.chooseButton.chooseControl(event, player)); + if (dialog.direct) next.direct = true; + if (dialog.forceDirect) next.forceDirect = true; + next.dialog = dialog; + next.set('ai', info.chooseButton.check || function () { return 0; }); + if (event.id) next._parent_id = event.id; + next.type = 'chooseToUse_button'; + } + else { + var next = player.chooseButton(dialog); + if (dialog.direct) next.direct = true; + if (dialog.forceDirect) next.forceDirect = true; + next.set('ai', info.chooseButton.check || function () { return 1; }); + next.set('filterButton', info.chooseButton.filter || function () { return true; }); + next.set('selectButton', info.chooseButton.select || 1); + next.set('filterOk', info.chooseButton.filterOk || (() => true)); + if (event.id) next._parent_id = event.id; + next.type = 'chooseToUse_button'; + } + event.buttoned = event.result.skill; + } + else if (info && info.precontent && !game.online && !event.nouse) { + var next = game.createEvent('pre_' + event.result.skill); + next.setContent(info.precontent); + next.set('result', event.result); + next.set('player', player); + } + } + } + "step 3"; + if (event.buttoned) { + if (result.bool || result.control && result.control != 'cancel2') { + var info = get.info(event.buttoned).chooseButton; + lib.skill[event.buttoned + '_backup'] = info.backup(info.chooseControl ? result : result.links, player); + lib.skill[event.buttoned + '_backup'].sourceSkill = event.buttoned; + if (game.online) { + event._sendskill = [event.buttoned + '_backup', lib.skill[event.buttoned + '_backup']]; + } + else { + game.broadcast((skill, audio) => { + if (!lib.skill[skill]) lib.skill[skill] = {}; + lib.skill[skill].audio = audio; + }, event.buttoned + '_backup', lib.skill[event.buttoned + '_backup'].audio); + } + event.backup(event.buttoned + '_backup'); + if (info.prompt) { + event.openskilldialog = info.prompt(info.chooseControl ? result : result.links, player); + } + } + else { + ui.control.addTempClass('nozoom', 100); + event._aiexclude.add(event.buttoned); + } + event.goto(0); + delete event.buttoned; + } + "step 4"; + if (event._aiexcludeclear) { + delete event._aiexcludeclear; + event._aiexclude.length = 0; + } + delete _status.noclearcountdown; + if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { + event.skillDialog.close(); + } + if (event.result && event.result.bool && !game.online && !event.nouse) { + player.useResult(event.result, event); + } + else if (event._sendskill) { + event.result._sendskill = event._sendskill; + } + if ((!event.result || !event.result.bool || event.result._noHidingTimer) && (event.result.skill || event.logSkill)) { + var info = get.info(event.result.skill || event.logSkill); + if (info.direct && !info.clearTime) { + _status.noclearcountdown = 'direct'; + } + } + if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); + if (!_status.noclearcountdown) { + game.stopCountChoose(); + } + "step 5"; + if (event._result && event.result) { + event.result.result = event._result; + } + }, + chooseToRespond: function () { + "step 0"; + if (event.responded) { + delete event.dialog; + return; + } + var skills = player.getSkills('invisible').concat(lib.skill.global); + game.expandSkills(skills); + for (var i = 0; i < skills.length; i++) { + var info = lib.skill[skills[i]]; + if (info && info.onChooseToRespond) { + info.onChooseToRespond(event); + } + } + if (_status.noclearcountdown !== 'direct') _status.noclearcountdown = true; + if (!_status.connectMode && lib.config.skip_shan && event.autochoose && event.autochoose()) { + event.result = { bool: false }; + } + else { + if (game.modeSwapPlayer && !_status.auto && player.isUnderControl()) { + game.modeSwapPlayer(player); + } + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + var ok = game.check(); + if (!ok || !lib.config.auto_confirm) { + game.pause(); + if (event.openskilldialog) { + event.skillDialog = ui.create.dialog(event.openskilldialog); + delete event.openskilldialog; + event.dialog = event.prompt; + } + else { + if (event.prompt) event.dialog = ui.create.dialog(event.prompt); + if (event.prompt2) event.dialog.addText(event.prompt2); + } + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + } + "step 1"; + if (event.result == 'ai') { + var ok = game.check(); + if (ok) { + ui.click.ok(); + } + else if (ai.basic.chooseCard(event.ai1 || event.ai) || forced) { + if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + event._aiexcludeclear = true; + } + else { + if (!event.norestore) { + if (event.skill) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + var info = get.info(skill); + if (info.sourceSkill) { + event._aiexclude.add(info.sourceSkill); + } + } + else { + get.card(true).aiexclude(); + game.uncheck(); + } + event.redo(); + game.resume(); + } + else { + ui.click.cancel(); + } + } + } + else if (event.skill && !event.norestore) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + var info = get.info(skill); + if (info.sourceSkill) { + event._aiexclude.add(info.sourceSkill); + } + event.redo(); + game.resume(); + } + else { + ui.click.cancel(); + } + if (event.aidelay && event.result && event.result.bool) { + game.delayx(); + } + } + "step 2"; + event.resume(); + if (event.result) { + if (event.result._sendskill) { + lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; + } + if (event.result.skill) { + var info = get.info(event.result.skill); + if (info && info.chooseButton) { + if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); + var dialog = info.chooseButton.dialog(event, player); + if (info.chooseButton.chooseControl) { + var next = player.chooseControl(info.chooseButton.chooseControl(event, player)); + if (dialog.direct) next.direct = true; + if (dialog.forceDirect) next.forceDirect = true; + next.dialog = dialog; + next.set('ai', info.chooseButton.check || function () { return 0; }); + } + else { + var next = player.chooseButton(dialog); + if (dialog.direct) next.direct = true; + if (dialog.forceDirect) next.forceDirect = true; + next.set('ai', info.chooseButton.check || function () { return 1; }); + next.set('filterButton', info.chooseButton.filter || function () { return true; }); + next.set('selectButton', info.chooseButton.select || 1); + next.set('filterOk', info.chooseButton.filterOk || (() => true)); + } + event.buttoned = event.result.skill; + } + else if (info && info.precontent && !game.online) { + var next = game.createEvent('pre_' + event.result.skill); + next.setContent(info.precontent); + next.set('result', event.result); + next.set('player', player); + } + } + } + "step 3"; + if (event.buttoned) { + if (result.bool || result.control && result.control != 'cancel2') { + var info = get.info(event.buttoned).chooseButton; + lib.skill[event.buttoned + '_backup'] = info.backup(info.chooseControl ? result : result.links, player); + lib.skill[event.buttoned + '_backup'].sourceSkill = event.buttoned; + if (game.online) { + event._sendskill = [event.buttoned + '_backup', lib.skill[event.buttoned + '_backup']]; + } + else { + game.broadcast((skill, audio) => { + if (!lib.skill[skill]) lib.skill[skill] = {}; + lib.skill[skill].audio = audio; + }, event.buttoned + '_backup', lib.skill[event.buttoned + '_backup'].audio); + } + event.backup(event.buttoned + '_backup'); + if (info.prompt) { + event.openskilldialog = info.prompt(info.chooseControl ? result : result.links, player); + } + } + else { + ui.control.addTempClass('nozoom', 100); + event._aiexclude.add(event.buttoned); + } + event.goto(0); + delete event.buttoned; + } + "step 4"; + delete _status.noclearcountdown; + if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { + event.skillDialog.close(); + } + if (event.result.bool && !game.online) { + if (event.result._sendskill) { + lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; + } + var info = get.info(event.result.skill); + if (event.onresult) { + event.onresult(event.result); + } + if ((!event.result || !event.result.bool || event.result._noHidingTimer) && (event.result.skill || event.logSkill)) { + if (info.direct && !info.clearTime) { + _status.noclearcountdown = 'direct'; + } + } + if (event.logSkill) { + if (typeof event.logSkill == 'string') { + player.logSkill(event.logSkill); + } + else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + if (!event.result.card && event.result.skill) { + event.result.used = event.result.skill; + player.useSkill(event.result.skill, event.result.cards, event.result.targets); + } + else { + if (info && info.prerespond) { + info.prerespond(event.result, player); + } + var next = player.respond(event.result.cards, event.result.card, event.animate, event.result.skill, event.source); + if (event.result.noanimate) next.animate = false; + if (event.parent.card && event.parent.type == 'card') { + next.set('respondTo', [event.parent.player, event.parent.card]); + } + if (event.noOrdering) next.noOrdering = true; + } + } + else if (event._sendskill) { + event.result._sendskill = event._sendskill; + } + if (event.dialog && event.dialog.close) event.dialog.close(); + if (!_status.noclearcountdown) { + game.stopCountChoose(); + } + }, + chooseToGive: function () { + "step 0"; + event.result = { + bool: true, + confirm: 'ok', + buttons: [], + links: [], + cards: [], + targets: [], + }; + event.filterCard = (event => { + const filterCard = event.filterCard; + return function (card, player) { + if (!lib.filter.canBeGained(card, this.target, player)) return false; + return filterCard.call(this, card, player); + }; + })(event); + if (event.directresult) { + event.result.cards = event.directresult.slice(0); + event.goto(2); + return; + } + const directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectCard != 'function' && !event.complexCard); + const cards = directFilter ? player.getCards(event.position).filter(card => !card.classList.contains('uncheck') && lib.filter.cardAiIncluded(card) && event.filterCard(card, player)) : []; + const range = get.select(event.selectCard); + if (directFilter && (range[0] >= cards.length || range[1] <= -1)) { + if (player.isOut()) event.result.cards = []; + else event.result.cards = cards; + } + else if (event.isMine()) { + game.check(); + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + game.pause(); + if (range[1] > 1 && typeof event.selectCard != 'function') { + event.aiChoose = ui.create.control('AI代选', function () { + ai.basic.chooseCard(event.ai); + if (_status.event.custom && _status.event.custom.add.card) { + _status.event.custom.add.card(); + } + ui.selected.cards.forEach(i => i.updateTransform(true)); + }); + } + if (Array.isArray(event.dialog)) { + event.dialog = ui.create.dialog.apply(this, event.dialog); + event.dialog.open(); + event.dialog.classList.add('noselect'); + } + else if (event.prompt != false) { + let prompt; + if (typeof event.prompt == 'string') prompt = event.prompt; + else { + let select; + if (range[0] == range[1]) select = get.cnNumber(range[0]); + else if (range[1] == Infinity) select = '至少' + get.cnNumber(range[0]); + else select = get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); + const position = event.position == 'h' ? '手' : event.position == 'e' ? '装备' : ''; + prompt = `请交给${get.translation(target)}${select}张${position}牌`; + } + event.dialog = ui.create.dialog(prompt); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + if (Array.isArray(event.promptx)) { + event.promptx.forEach(i => event.dialog.add(i)); + } + if (Array.isArray(event.selectCard)) { + event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); + event.custom.add.card = function () { + _status.event.promptbar.innerHTML = + ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); + }; + } + } + else if (get.itemtype(event.dialog) == 'dialog') { + event.dialog.style.display = ''; + event.dialog.open(); + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + "step 1"; + if (event.result == 'ai') { + game.check(); + if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + } + else if (event.skill) { + ui.click.cancel(); + event._aiexclude.add(event.skill); + event.redo(); + game.resume(); + } + else { + ui.click.cancel(); + } + } + "step 2"; + event.resume(); + if (event.aiChoose) event.aiChoose.close(); + if (event.glow_result && event.result.cards && !event.directresult) { + event.result.cards.forEach(i => i.classList.add('glow')); + } + if (event.dialog) event.dialog.close(); + "step 3"; + if (event.result.bool && event.result.cards && !game.online) { + event.cards = event.result.cards.slice(0); + if (event.logSkill) { + if (Array.isArray(event.logSkill)) player.logSkill(...event.logSkill); + else player.logSkill(event.logSkill); + } + if (event.autodelay && !event.isMine()) { + if (typeof event.autodelay == 'number') game.delayx(event.autodelay); + else game.delayx(); + } + } + else event.finish(); + "step 4"; + if (event.boolline) player.line(target, 'green'); + event.done = target.gain(event.cards, player); + event.done.giver = player; + if (event.delay !== false) event.done.animate = event.visibleMove ? 'give' : 'giveAuto'; + else { + target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); + if (event.visibleMove) event.done.visible = true; + } + }, + chooseToDiscard: function () { + "step 0"; + if (event.autochoose()) { + event.result = { + bool: true, + autochoose: true, + cards: player.getCards(event.position), + rawcards: player.getCards(event.position), + }; + for (var i = 0; i < event.result.cards.length; i++) { + if (!lib.filter.cardDiscardable(event.result.cards[i], player, event)) { + event.result.cards.splice(i--, 1); + } + } + } + else { + // &&!lib.filter.wuxieSwap(trigger) + if (game.modeSwapPlayer && !_status.auto && player.isUnderControl()) { + game.modeSwapPlayer(player); + } + event.rangecards = player.getCards(event.position); + for (var i = 0; i < event.rangecards.length; i++) { + if (lib.filter.cardDiscardable(event.rangecards[i], player, event)) { + event.rangecards.splice(i--, 1); + } + else { + event.rangecards[i].uncheck('chooseToDiscard'); + } + } + var range = get.select(event.selectCard); + if (event.isMine()) { + game.check(); + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + game.pause(); + if (range[1] > 1 && typeof event.selectCard != 'function') { + event.promptdiscard = ui.create.control('AI代选', function () { + ai.basic.chooseCard(event.ai); + if (_status.event.custom && _status.event.custom.add.card) { + _status.event.custom.add.card(); + } + for (var i = 0; i < ui.selected.cards.length; i++) { + ui.selected.cards[i].updateTransform(true); + } + }); + } + if (Array.isArray(event.dialog)) { + event.dialog = ui.create.dialog.apply(this, event.dialog); + event.dialog.open(); + event.dialog.classList.add('noselect'); + } + else if (event.prompt != false) { + var str; + if (typeof (event.prompt) == 'string') str = event.prompt; + else { + str = '请弃置'; + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); + str += '张'; + if (event.position == 'h' || event.position == undefined) str += '手'; + if (event.position == 'e') str += '装备'; + str += '牌'; + } + event.dialog = ui.create.dialog(str); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + if (Array.isArray(event.selectCard)) { + event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); + event.custom.add.card = function () { + _status.event.promptbar.innerHTML = + ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); + }; + } + } + else if (get.itemtype(event.dialog) == 'dialog') { + event.dialog.style.display = ''; + event.dialog.open(); + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + } + "step 1"; + if (event.result == 'ai') { + game.check(); + if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + } + else if (event.skill) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + event.redo(); + game.resume(); + } + else { + ui.click.cancel(); + } + } + if (event.rangecards) { + for (var i = 0; i < event.rangecards.length; i++) { + event.rangecards[i].recheck('chooseToDiscard'); + } + } + "step 2"; + event.resume(); + if (event.promptdiscard) { + event.promptdiscard.close(); + } + "step 3"; + if (event.result.bool && event.result.cards && event.result.cards.length && + !game.online && event.autodelay && !event.isMine()) { + if (typeof event.autodelay == 'number') { + game.delayx(event.autodelay); + } + else { + game.delayx(); + } + } + "step 4"; + if (event.logSkill && event.result.bool && !game.online) { + if (typeof event.logSkill == 'string') { + player.logSkill(event.logSkill); + } + else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + if (!game.online) { + if (typeof event.delay == 'boolean') { + event.done = player.discard(event.result.cards).set('delay', event.delay); + } + else { + event.done = player.discard(event.result.cards); + } + event.done.discarder = player; + } + if (event.dialog && event.dialog.close) event.dialog.close(); + }, + gaincardMultiple: function () { + 'step 0'; + event.type = 'gain'; + if (event.animate == 'give' || event.animate == 'gain2') event.visible = true; + if (player && cards) { + event._lose = true; + player.lose(cards, ui.special).set('type', 'gain').set('forceDie', true).set('getlx', false); + } + 'step 1'; + switch (event.animate) { + case 'draw': + game.delay(0, get.delayx(500, 500)); + for (var i of event.gain_list) { + if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; + if (event._lose) { + i[1] = i[1].filter(card => { + return !cards.includes(card) || !player.getCards('hejsx').includes(card); + }); + } + if (i[1].length > 0) i[0].$draw(i[1].length); + } + break; + case 'gain': + game.delay(0, get.delayx(700, 700)); + for (var i of event.gain_list) { + if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; + if (event._lose) { + i[1] = i[1].filter(card => { + return !cards.includes(card) || !player.getCards('hejsx').includes(card); + }); + } + if (i[1].length > 0) i[0].$gain(i[1].length); + } + break; + case 'gain2': case 'draw2': + game.delay(0, get.delayx(500, 500)); + for (var i of event.gain_list) { + if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; + if (event._lose) { + i[1] = i[1].filter(card => { + return !cards.includes(card) || !player.getCards('hejsx').includes(card); + }); + } + if (i[1].length > 0) i[0].$gain2(i[1]); + } + break; + case 'give': case 'giveAuto': + if (!player) break; + var evt = event.getl(player); + game.delay(0, get.delayx(500, 500)); + for (var i of event.gain_list) { + if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; + if (event._lose) { + i[1] = i[1].filter(card => { + return !cards.includes(card) || !player.getCards('hejsx').includes(card); + }); + } + var shown = i[1].slice(0), hidden = []; + if (event.animate == 'giveAuto') { + for (var card of i[1]) { + if (evt.hs.includes(card)) { + shown.remove(card); + hidden.push(card); + } + } + } + if (shown.length > 0) player.$give(shown, i[0]); + if (hidden.length > 0) player.$giveAuto(hidden, i[0]); + } + break; + default: + event.finish(); + } + for (var i of event.gain_list) { + if (i[1].length > 0) { + var next = i[0].gain(i[1]); + next.getlx = false; + if (event.visible) next.visible = true; + if (event.giver) next.giver = event.giver; + if (event.gaintag) next.gaintag.addArray(event.gaintag); + } + } + 'step 2'; + game.delayx(); + }, + discardMultiple: function () { + 'step 0'; + event.type = 'discard'; + event.visible = true; + if (!event.position) event.position = ui.discardPile; + var cards = []; + event.cards = cards; + for (var i = 0; i < event.lose_list.length; i++) { + var next = event.lose_list[i][0].lose(event.lose_list[i][1], event.position); + game.log(event.lose_list[i][0], '弃置了', event.lose_list[i][1]); + next.type = 'discard'; + next.animate = false; + next.delay = false; + cards.addArray(event.lose_list[i][1]); + next.getlx = false; + } + var evt = event; + if (evt.animate != false) { + evt.discardid = lib.status.videoId++; + game.broadcastAll(function (list, id, cards) { + for (var i of list) { + for (var j of i[1]) { + j.classList.remove('glow'); + j.classList.remove('glows'); + } + i[0].$throw(i[1], null, 'nobroadcast'); + } + var cardnodes = []; + cardnodes._discardtime = get.time(); + for (var ix of list) { + var card = ix[1]; + for (var i = 0; i < cards.length; i++) { + if (cards[i].clone) { + cardnodes.push(cards[i].clone); + } + } + } + ui.todiscard[id] = cardnodes; + }, event.lose_list, evt.discardid, cards); + if (lib.config.sync_speed && cards[0] && cards[0].clone) { + if (evt.delay != false) { + var waitingForTransition = get.time(); + evt.waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete evt.waitingForTransition; + }); + } + else if (evt.getParent().discardTransition) { + delete evt.getParent().discardTransition; + var waitingForTransition = get.time(); + evt.getParent().waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete evt.getParent().waitingForTransition; + }); + } + } + } + 'step 1'; + if (event.delay != false) { + if (event.waitingForTransition) { + _status.waitingForTransition = event.waitingForTransition; + game.pause(); + } + else { + game.delayx(); + } + } + }, + chooseToCompareLose: function () { + for (var i = 0; i < event.lose_list.length; i++) { + var next = event.lose_list[i][0].lose(event.lose_list[i][1], ui.ordering); + next.relatedEvent = event.getParent(); + next.getlx = false; + } + }, + chooseToCompareMeanwhile: function () { + 'step 0'; + if (player.countCards('h') == 0) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + for (var i = 0; i < targets.length; i++) { + if (targets[i].countCards('h') == 0) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + } + if (!event.multitarget) { + targets.sort(lib.sort.seat); + } + game.log(player, '对', targets, '发起了共同拼点'); + event.compareMeanwhile = true; + 'step 1'; + event._result = []; + event.list = targets.filter(function (current) { + return !event.fixedResult || !event.fixedResult[current.playerid]; + }); + if (event.list.length || !event.fixedResult || !event.fixedResult[player.playerid]) { + if (!event.fixedResult || !event.fixedResult[player.playerid]) event.list.unshift(player); + player.chooseCardOL(event.list, '请选择拼点牌', true).set('type', 'compare').set('ai', event.ai).set('source', player).aiCard = function (target) { + var hs = target.getCards('h'); + var event = _status.event; + event.player = target; + hs.sort(function (a, b) { + return event.ai(b) - event.ai(a); + }); + delete event.player; + return { bool: true, cards: [hs[0]] }; + }; + } + 'step 2'; + var cards = []; + var lose_list = []; + if (event.fixedResult && event.fixedResult[player.playerid]) { + event.list.unshift(player); + result.unshift({ bool: true, cards: [event.fixedResult[player.playerid]] }); + lose_list.push([player, [event.fixedResult[player.playerid]]]); + } + else { + if (result[0].skill && lib.skill[result[0].skill] && lib.skill[result[0].skill].onCompare) { + player.logSkill(result[0].skill); + result[0].cards = lib.skill[result[0].skill].onCompare(player); + } + else lose_list.push([player, result[0].cards]); + } + for (var j = 0; j < targets.length; j++) { + if (event.list.includes(targets[j])) { + var i = event.list.indexOf(targets[j]); + if (result[i].skill && lib.skill[result[i].skill] && lib.skill[result[i].skill].onCompare) { + event.list[i].logSkill(result[i].skill); + result[i].cards = lib.skill[result[i].skill].onCompare(event.list[i]); + } + else lose_list.push([targets[j], result[i].cards]); + cards.push(result[i].cards[0]); + } + else if (event.fixedResult && event.fixedResult[targets[j].playerid]) { + cards.push(event.fixedResult[targets[j].playerid]); + lose_list.push([targets[j], [event.fixedResult[targets[j].playerid]]]); + } + } + if (lose_list.length) { + game.loseAsync({ + lose_list: lose_list, + }).setContent('chooseToCompareLose'); + } + event.lose_list = lose_list; + event.getNum = function (card) { + for (var i of event.lose_list) { + if (i[1].contains && i[1].includes(card)) return get.number(card, i[0]); + } + return get.number(card, false); + }; + event.cardlist = cards; + event.cards = cards; + event.card1 = result[0].cards[0]; + event.num1 = event.getNum(event.card1); + event.iwhile = 0; + event.winner = null; + event.maxNum = -1; + event.tempplayer = event.player; + event.result = { + winner: null, + player: event.card1, + targets: event.cardlist.slice(0), + num1: [], + num2: [], + }; + 'step 3'; + event.trigger('compareCardShowBefore'); + 'step 4'; + player.$compareMultiple(event.card1, targets, cards); + game.log(player, '的拼点牌为', event.card1); + event.cardlist.forEach((card, index) => { + game.log(targets[index], '的拼点牌为', card); + }); + player.addTempClass('target'); + game.delay(0, 1000); + 'step 5'; + event.target = null; + event.trigger('compare'); + 'step 6'; + if (event.iwhile < targets.length) { + event.target = targets[event.iwhile]; + event.target.addTempClass('target'); + event.card2 = event.cardlist[event.iwhile]; + event.num2 = event.getNum(event.card2); + //event.tempplayer.line(event.target); + delete event.player; + event.trigger('compare'); + } + else { + game.delay(0, 1000); + event.goto(9); + } + 'step 7'; + event.result.num1[event.iwhile] = event.num1; + event.result.num2[event.iwhile] = event.num2; + var list = [[event.tempplayer, event.num1], [event.target, event.num2]]; + for (var i of list) { + if (i[1] > event.maxNum) { + event.maxNum = i[1]; + event.winner = i[0]; + } + else if (event.winner && i[1] == event.maxNum && i[0] != event.winner) { + event.winner = null; + } + } + 'step 8'; + event.iwhile++; + event.goto(6); + 'step 9'; + var player = event.tempplayer; + event.player = player; + delete event.tempplayer; + var str = '无人拼点成功'; + if (event.winner) { + event.result.winner = event.winner; + str = get.translation(event.winner) + '拼点成功'; + game.log(event.winner, '拼点成功'); + event.winner.popup('胜'); + } else game.log('#b无人', '拼点成功'); + var list = [player].addArray(targets); + list.remove(event.winner); + for (var i of list) { + i.popup('负'); + } + if (str) { + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add('center'); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + } + game.delay(3); + 'step 10'; + game.broadcastAll(ui.clear); + 'step 11'; + event.cards.add(event.card1); + }, + chooseToCompareMultiple: function () { + "step 0"; + if (player.countCards('h') == 0) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + for (var i = 0; i < targets.length; i++) { + if (targets[i].countCards('h') == 0) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + } + if (!event.multitarget) { + targets.sort(lib.sort.seat); + } + game.log(player, '对', targets, '发起拼点'); + "step 1"; + event._result = []; + event.list = targets.filter(function (current) { + return !event.fixedResult || !event.fixedResult[current.playerid]; + }); + if (event.list.length || !event.fixedResult || !event.fixedResult[player.playerid]) { + if (!event.fixedResult || !event.fixedResult[player.playerid]) event.list.unshift(player); + player.chooseCardOL(event.list, '请选择拼点牌', true).set('type', 'compare').set('ai', event.ai).set('source', player).aiCard = function (target) { + var hs = target.getCards('h'); + var event = _status.event; + event.player = target; + hs.sort(function (a, b) { + return event.ai(b) - event.ai(a); + }); + delete event.player; + return { bool: true, cards: [hs[0]] }; + }; + } + "step 2"; + var cards = []; + var lose_list = []; + if (event.fixedResult && event.fixedResult[player.playerid]) { + event.list.unshift(player); + result.unshift({ bool: true, cards: [event.fixedResult[player.playerid]] }); + lose_list.push([player, [event.fixedResult[player.playerid]]]); + } + else { + if (result[0].skill && lib.skill[result[0].skill] && lib.skill[result[0].skill].onCompare) { + player.logSkill(result[0].skill); + result[0].cards = lib.skill[result[0].skill].onCompare(player); + } + else lose_list.push([player, result[0].cards]); + } + for (var j = 0; j < targets.length; j++) { + if (event.list.includes(targets[j])) { + var i = event.list.indexOf(targets[j]); + if (result[i].skill && lib.skill[result[i].skill] && lib.skill[result[i].skill].onCompare) { + event.list[i].logSkill(result[i].skill); + result[i].cards = lib.skill[result[i].skill].onCompare(event.list[i]); + } + else lose_list.push([targets[j], result[i].cards]); + cards.push(result[i].cards[0]); + } + else if (event.fixedResult && event.fixedResult[targets[j].playerid]) { + cards.push(event.fixedResult[targets[j].playerid]); + lose_list.push([targets[j], [event.fixedResult[targets[j].playerid]]]); + } + } + if (lose_list.length) { + game.loseAsync({ + lose_list: lose_list, + }).setContent('chooseToCompareLose'); + } + event.lose_list = lose_list; + event.getNum = function (card) { + for (var i of event.lose_list) { + if (i[1].contains && i[1].includes(card)) return get.number(card, i[0]); + } + return get.number(card, false); + }; + event.cardlist = cards; + event.cards = cards; + event.card1 = result[0].cards[0]; + event.num1 = event.getNum(event.card1); + event.iwhile = 0; + event.result = { + player: event.card1, + targets: event.cardlist.slice(0), + num1: [], + num2: [], + }; + "step 3"; + event.trigger('compareCardShowBefore'); + "step 4"; + game.log(player, '的拼点牌为', event.card1); + "step 5"; + if (event.iwhile < targets.length) { + event.target = targets[event.iwhile]; + event.target.addTempClass('target'); + player.addTempClass('target'); + event.card2 = event.cardlist[event.iwhile]; + event.num2 = event.getNum(event.card2); + game.log(event.target, '的拼点牌为', event.card2); + player.line(event.target); + player.$compare(event.card1, event.target, event.card2); + event.trigger('compare'); + game.delay(0, 1500); + } + else { + event.goto(9); + } + "step 6"; + event.result.num1[event.iwhile] = event.num1; + event.result.num2[event.iwhile] = event.num2; + var str; + if (event.num1 > event.num2) { + str = get.translation(player) + '拼点成功'; + player.popup('胜'); + target.popup('负'); + } + else { + str = get.translation(player) + '拼点失败'; + if (event.num1 == event.num2) { + player.popup('平'); + target.popup('平'); + } + else { + player.popup('负'); + target.popup('胜'); + } + } + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add('center'); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + game.delay(2); + "step 7"; + if (event.callback) { + game.broadcastAll(function (card1, card2) { + if (card1.clone) card1.clone.style.opacity = 0.5; + if (card2.clone) card2.clone.style.opacity = 0.5; + }, event.card1, event.card2); + var next = game.createEvent('compareMultiple'); + next.player = player; + next.target = event.target; + next.card1 = event.card1; + next.card2 = event.card2; + next.num1 = event.num1; + next.num2 = event.num2; + next.setContent(event.callback); + event.compareMultiple = true; + } + "step 8"; + game.broadcastAll(ui.clear); + event.iwhile++; + event.goto(5); + "step 9"; + event.cards.add(event.card1); + }, + chooseToCompare: function () { + "step 0"; + if (((!event.fixedResult || !event.fixedResult[player.playerid]) && player.countCards('h') == 0) || ((!event.fixedResult || !event.fixedResult[target.playerid]) && target.countCards('h') == 0)) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + game.log(player, '对', target, '发起拼点'); + event.lose_list = []; + "step 1"; + var sendback = function () { + if (_status.event != event) { + return function () { + event.resultOL = _status.event.resultOL; + }; + } + }; + if (event.fixedResult && event.fixedResult[player.playerid]) { + event.card1 = event.fixedResult[player.playerid]; + event.lose_list.push([player, event.card1]); + } + else if (player.isOnline()) { + player.wait(sendback); + event.ol = true; + player.send(function (ai) { + game.me.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = ai; + game.resume(); + }, event.ai); + } + else { + event.localPlayer = true; + player.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = event.ai; + } + if (event.fixedResult && event.fixedResult[target.playerid]) { + event.card2 = event.fixedResult[target.playerid]; + event.lose_list.push([target, event.card2]); + } + else if (target.isOnline()) { + target.wait(sendback); + event.ol = true; + target.send(function (ai) { + game.me.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = ai; + game.resume(); + }, event.ai); + } + else { + event.localTarget = true; + } + "step 2"; + if (event.localPlayer) { + if (result.skill && lib.skill[result.skill] && lib.skill[result.skill].onCompare) { + result.cards = lib.skill[result.skill].onCompare(player); + player.logSkill(result.skill); + } + else event.lose_list.push([player, result.cards[0]]); + event.card1 = result.cards[0]; + } + if (event.localTarget) { + target.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = event.ai; + } + "step 3"; + if (event.localTarget) { + if (result.skill && lib.skill[result.skill] && lib.skill[result.skill].onCompare) { + target.logSkill(result.skill); + result.cards = lib.skill[result.skill].onCompare(target); + } + else event.lose_list.push([target, result.cards[0]]); + event.card2 = result.cards[0]; + } + if (!event.resultOL && event.ol) { + game.pause(); + } + "step 4"; + try { + if (!event.card1) { + if (event.resultOL[player.playerid].skill && lib.skill[event.resultOL[player.playerid].skill] && lib.skill[event.resultOL[player.playerid].skill].onCompare) { + player.logSkill(event.resultOL[player.playerid].skill); + event.resultOL[player.playerid].cards = lib.skill[event.resultOL[player.playerid].skill].onCompare(player); + } + else event.lose_list.push([player, event.resultOL[player.playerid].cards[0]]); + event.card1 = event.resultOL[player.playerid].cards[0]; + } + if (!event.card2) { + if (event.resultOL[target.playerid].skill && lib.skill[event.resultOL[target.playerid].skill] && lib.skill[event.resultOL[target.playerid].skill].onCompare) { + target.logSkill(event.resultOL[target.playerid].skill); + event.resultOL[target.playerid].cards = lib.skill[event.resultOL[target.playerid].skill].onCompare(player); + } + else event.lose_list.push([target, event.resultOL[target.playerid].cards[0]]); + event.card2 = event.resultOL[target.playerid].cards[0]; + } + if (!event.card1 || !event.card2) { + throw ('err'); + } + } + catch (e) { + console.log(e); + game.print(e); + event.finish(); + return; + } + if (event.card2.number >= 10 || event.card2.number <= 4) { + if (target.countCards('h') > 2) { + event.addToAI = true; + } + } + if (event.lose_list.length) { + game.loseAsync({ + lose_list: event.lose_list, + }).setContent('chooseToCompareLose'); + } + "step 5"; + event.trigger('compareCardShowBefore'); + "step 6"; + game.broadcast(function () { + ui.arena.classList.add('thrownhighlight'); + }); + ui.arena.classList.add('thrownhighlight'); + game.addVideo('thrownhighlight1'); + player.$compare(event.card1, target, event.card2); + game.log(player, '的拼点牌为', event.card1); + game.log(target, '的拼点牌为', event.card2); + var getNum = function (card) { + for (var i of event.lose_list) { + if (i[1] == card) return get.number(card, i[0]); + } + return get.number(card, false); + }; + event.num1 = getNum(event.card1); + event.num2 = getNum(event.card2); + event.trigger('compare'); + game.delay(0, 1500); + "step 7"; + event.result = { + player: event.card1, + target: event.card2, + num1: event.num1, + num2: event.num2 + }; + var str; + if (event.num1 > event.num2) { + event.result.bool = true; + event.result.winner = player; + str = get.translation(player) + '拼点成功'; + player.popup('胜'); + target.popup('负'); + } + else { + event.result.bool = false; + str = get.translation(player) + '拼点失败'; + if (event.num1 == event.num2) { + event.result.tie = true; + player.popup('平'); + target.popup('平'); + } + else { + event.result.winner = target; + player.popup('负'); + target.popup('胜'); + } + } + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add('center'); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + game.delay(2); + "step 8"; + if (typeof event.target.ai.shown == 'number' && event.target.ai.shown <= 0.85 && event.addToAI) { + event.target.ai.shown += 0.1; + } + game.broadcastAll(function () { + ui.arena.classList.remove('thrownhighlight'); + }); + game.addVideo('thrownhighlight2'); + if (event.clear !== false) { + game.broadcastAll(ui.clear); + } + if (typeof event.preserve == 'function') { + event.preserve = event.preserve(event.result); + } + else if (event.preserve == 'win') { + event.preserve = event.result.bool; + } + else if (event.preserve == 'lose') { + event.preserve = !event.result.bool; + } + }, + chooseSkill: function () { + 'step 0'; + var list; + if (typeof event.target == 'string') { + list = get.gainableSkillsName(event.target, event.func); + } + else { + list = event.target.getGainableSkills(event.func); + } + if (!list.length) { + event.finish(); + event.result = { bool: false }; + return; + } + event.skillai = function (list) { + return get.max(list, get.skillRank, 'item'); + }; + if (event.isMine()) { + var dialog = ui.create.dialog('forcebutton'); + dialog.add(event.prompt || '选择获得一项技能'); + _status.event.list = list; + var clickItem = function () { + _status.event._result = this.link; + game.resume(); + }; + for (i = 0; i < list.length; i++) { + if (lib.translate[list[i] + '_info']) { + var translation = get.translation(list[i]); + if (translation[0] == '新' && translation.length == 3) { + translation = translation.slice(1, 3); + } + else { + translation = translation.slice(0, 2); + } + var item = dialog.add(''); + item.firstChild.addEventListener('click', clickItem); + item.firstChild.link = list[i]; + } + } + dialog.add(ui.create.div('.placeholder')); + event.dialog = dialog; + event.switchToAuto = function () { + event._result = event.skillai(event.list); + game.resume(); + }; + _status.imchoosing = true; + game.pause(); + } + else { + event._result = event.skillai(list); + } + 'step 1'; + _status.imchoosing = false; + if (event.dialog) { + event.dialog.close(); + } + event.result = { bool: true, skill: result }; + }, + discoverCard: function () { + 'step 0'; + var num = event.num || 3; + var choice; + if (typeof event.list == 'string' || typeof event.list == 'function') { + choice = get.inpile(event.list).randomGets(num); + } + else if (Array.isArray(event.list)) { + choice = event.list.randomGets(num); + } + else { + choice = Array.from(event.list).randomGets(num); + } + if (choice.length) { + var prompt = event.prompt; + if (!prompt) { + prompt = '选择一张牌'; + if (event.use) { + prompt += '使用之'; + } + else if (!event.nogain) { + prompt += '获得之'; + } + } + if (typeof choice[0] === 'string') { + var next = player.chooseVCardButton(choice, prompt, event.forced); + if (event.ai) { + next.set('ai', event.ai); + } + } + else if (get.itemtype(choice[0]) == 'card') { + var next = player.chooseCardButton(choice, prompt, event.forced); + if (event.ai) { + next.set('ai', event.ai); + } + } + else { + event.finish(); + } + } + else { + event.finish(); + } + 'step 1'; + event.result = { + bool: result.bool, + card: null, + choice: null + }; + if (result.bool && result.links.length) { + var link = result.links[0]; + var togain = null; + if (get.itemtype(link) == 'card') { + event.result.card = link; + togain = link; + } + else if (Array.isArray(link)) { + event.result.choice = link[2]; + togain = game.createCard(link[2]); + } + if (togain) { + if (event.use) { + player.chooseUseTarget(togain); + } + else if (!event.nogain) { + player.gain(togain, 'draw'); + game.log(player, '获得了一张牌'); + } + } + } + }, + chooseButton: function () { + "step 0"; + if (typeof event.dialog == 'number') { + event.dialog = get.idDialog(event.dialog); + } + if (event.createDialog && !event.dialog) { + if (Array.isArray(event.createDialog)) { + event.createDialog.add('hidden'); + event.dialog = ui.create.dialog.apply(this, event.createDialog); + } + event.closeDialog = true; + } + if (event.dialog == undefined) event.dialog = ui.dialog; + if (event.isMine() || event.dialogdisplay) { + event.dialog.style.display = ''; + event.dialog.open(); + } + var filterButton = event.filterButton || function () { return true; }; + var selectButton = get.select(event.selectButton); + var buttons = event.dialog.buttons; + var buttonsx = []; + var num = 0; + for (var i = 0; i < buttons.length; i++) { + var button = buttons[i]; + if (filterButton(button, player)) { + num++; + buttonsx.add(button); + } + } + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + else if (event.direct && num == selectButton[0] || event.forceDirect) { + var buttons = buttonsx.slice(0, num); + event.result = { + bool: true, + button: [buttons], + links: get.links(buttons), + }; + event.dialog.close(); + } + else { + game.check(); + game.pause(); + } + } + else if (event.isOnline()) { + if (event.direct && num == 1 || event.forceDirect) { + var buttons = buttonsx.slice(0, num); + event.result = { + bool: true, + button: [buttons], + links: get.links(buttons), + }; + event.dialog.close(); + } + else { + event.send(); + } + delete event.callback; + } + else { + event.result = 'ai'; + } + if (event.onfree) { + lib.init.onfree(); + } + "step 1"; + if (event.result == 'ai') { + if (event.processAI) { + event.result = event.processAI(); + } + else { + game.check(); + if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); + else ui.click.cancel(); + } + } + if (event.closeDialog) { + event.dialog.close(); + } + if (event.callback) { + event.callback(event.player, event.result); + } + event.resume(); + }, + chooseCardOL: function () { + 'step 0'; + event.targets = event.list.slice(0); + if (!_status.connectMode) { + event.result = []; + event.goto(7); + } + else { + for (var i = 0; i < event.list.length; i++) { + var target = event.list[i]; + target.wait(); + if (target.isOnline()) { + target.send(function (args, set) { + game.me.chooseCard.apply(game.me, args).set(set); + game.resume(); + }, event._args, event._set); + event.list.splice(i--, 1); + } + else if (target == game.me) { + event.withme = true; + event.list.splice(i--, 1); + } + } + } + 'step 1'; + if (event.list.length) { + event.target = event.list.shift(); + event.target.chooseCard.apply(event.target, event._args).set(event._set); + } + else { + event.goto(3); + } + 'step 2'; + event.target.unwait(result); + event.goto(1); + 'step 3'; + if (event.withme) { + game.me.chooseCard.apply(game.me, event._args).set(event._set); + } + else { + event.goto(5); + } + 'step 4'; + game.me.unwait(result); + 'step 5'; + if (!event.resultOL) { + game.pause(); + } + 'step 6'; + event.result = []; + for (var i = 0; i < event.targets.length; i++) { + event.result[i] = event.resultOL[event.targets[i].playerid] || {}; + if (event.result[i] == 'ai' && event.aiCard) { + event.result[i] = event.aiCard(event.targets[i]); + } + } + event.finish(); + 'step 7'; + if (event.list.length) { + event.target = event.list.shift(); + event.target.chooseCard.apply(event.target, event._args).set(event._set); + } + else { + for (var i = 0; i < event.targets.length; i++) { + if (!event.result[i]) { + event.result[i] = {}; + } + } + event.finish(); + } + 'step 8'; + event.result[event.targets.indexOf(event.target)] = result; + event.goto(7); + }, + chooseButtonOL: function () { + 'step 0'; + //ui.arena.classList.add('markhidden'); + for (var i = 0; i < event.list.length; i++) { + var current = event.list[i]; + current[0].wait(); + if (current[0].isOnline()) { + var target = current.shift(); + target.send(function (args, callback, switchToAuto, processAI) { + //ui.arena.classList.add('markhidden'); + var next = game.me.chooseButton.apply(game.me, args); + next.callback = callback; + next.switchToAuto = switchToAuto; + next.processAI = processAI; + next.complexSelect = true; + game.resume(); + }, current, event.callback, event.switchToAuto, event.processAI); + target._choose_button_ol = current; + event.list.splice(i--, 1); + } + else if (current[0] == game.me) { + event.last = current; + event.last.shift(); + event.list.splice(i--, 1); + } + } + 'step 1'; + if (event.list.length) { + var current = event.list.shift(); + event.target = current.shift(); + var next = event.target.chooseButton.apply(event.target, current); + next.callback = event.callback; + next.switchToAuto = event.switchToAuto; + next.processAI = event.processAI; + } + else { + event.goto(3); + } + 'step 2'; + event.target.unwait(result); + event.goto(1); + 'step 3'; + if (event.last) { + var next = game.me.chooseButton.apply(game.me, event.last); + next.callback = event.callback; + next.switchToAuto = event.switchToAuto; + next.processAI = event.processAI; + } + else { + event.goto(5); + } + 'step 4'; + game.me.unwait(result); + 'step 5'; + if (!event.resultOL) { + game.pause(); + } + 'step 6'; + /*game.broadcastAll(function(){ + ui.arena.classList.remove('markhidden'); + });*/ + event.result = event.resultOL; + }, + chooseCard: function () { + "step 0"; + if (event.directresult) { + event.result = { + buttons: [], + cards: event.directresult.slice(0), + targets: [], + confirm: 'ok', + bool: true, + links: [] + }; + } + else { + if (event.isMine()) { + game.check(); + game.pause(); + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + if (event.prompt != false) { + var str; + if (typeof event.prompt == 'string') str = event.prompt; + else { + str = '请选择'; + var range = get.select(event.selectCard); + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); + str += '张'; + if (event.position == 'h' || event.position == undefined) str += '手'; + if (event.position == 'e') str += '装备'; + str += '牌'; + } + event.dialog = ui.create.dialog(str); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + if (Array.isArray(event.promptx)) { + for (var i = 0; i < event.promptx.length; i++) { + event.dialog.add(event.promptx[i]); + } + } + if (Array.isArray(event.selectCard)) { + event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); + event.custom.add.card = function () { + _status.event.promptbar.innerHTML = + ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); + }; + } + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + } + "step 1"; + if (event.result == 'ai') { + game.check(); + if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + } + else if (event.skill) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + event.redo(); + game.resume(); + } + else { + ui.click.cancel(); + } + } + "step 2"; + event.resume(); + if (event.glow_result && event.result.cards && !event.directresult) { + for (var i = 0; i < event.result.cards.length; i++) { + event.result.cards[i].classList.add('glow'); + } + } + if (event.dialog) event.dialog.close(); + }, + chooseTarget: function () { + "step 0"; + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + game.check(); + game.pause(); + if (event.createDialog && !event.dialog && Array.isArray(event.createDialog)) { + event.dialog = ui.create.dialog.apply(this, event.createDialog); + } + else if (event.prompt != false) { + var str; + if (typeof event.prompt == 'string') str = event.prompt; + else { + str = '请选择'; + var range = get.select(event.selectTarget); + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); + str += '个目标'; + } + event.dialog = ui.create.dialog(str); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + if (event.promptbar != 'none') { + event.promptbar = event.dialog.add('0/' + get.numStr(get.select(event.selectTarget)[1], 'target')); + event.custom.add.target = function () { + _status.event.promptbar.innerHTML = + ui.selected.targets.length + '/' + get.numStr(get.select(event.selectTarget)[1], 'target'); + }; + } + } + else if (get.itemtype(event.dialog) == 'dialog') { + event.dialog.open(); + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + "step 1"; + if (event.result == 'ai') { + game.check(); + if ((ai.basic.chooseTarget(event.ai) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + } + else { + ui.click.cancel(); + } + } + if (event.result.bool && event.animate !== false) { + for (var i = 0; i < event.result.targets.length; i++) { + event.result.targets[i].addTempClass('target'); + } + } + if (event.dialog) event.dialog.close(); + event.resume(); + "step 2"; + if (event.onresult) { + event.onresult(event.result); + } + if (event.result.bool && event.autodelay && !event.isMine()) { + if (typeof event.autodelay == 'number') { + game.delayx(event.autodelay); + } + else { + game.delayx(); + } + } + }, + chooseCardTarget: function () { + "step 0"; + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + game.check(); + game.pause(); + if (event.prompt != false) { + event.dialog = ui.create.dialog(event.prompt || '请选择卡牌和目标'); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + "step 1"; + if (event.result == 'ai') { + game.check(); + if (ai.basic.chooseCard(event.ai1) || forced) { + if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + _status.event._aiexclude.length = 0; + } + else { + ui.click.cancel(); + } + } + else { + ui.click.cancel(); + } + } + "step 2"; + event.resume(); + if (event.result.bool && event.animate !== false) { + for (var i = 0; i < event.result.targets.length; i++) { + event.result.targets[i].addTempClass('target'); + } + } + if (event.dialog) event.dialog.close(); + }, + chooseControl: function () { + "step 0"; + if (event.controls.length == 0) { + if (event.sortcard) { + var sortnum = 2; + if (event.sorttop) { + sortnum = 1; + } + for (var i = 0; i < event.sortcard.length + sortnum; i++) { + event.controls.push(get.cnNumber(i, true)); + } + } + else if (event.choiceList) { + for (var i = 0; i < event.choiceList.length; i++) { + event.controls.push('选项' + get.cnNumber(i + 1, true)); + } + } + else { + event.finish(); + return; + } + } + else if (event.choiceList && event.controls.length == 1 && event.controls[0] == 'cancel2') { + event.controls.shift(); + for (var i = 0; i < event.choiceList.length; i++) { + event.controls.push('选项' + get.cnNumber(i + 1, true)); + } + event.controls.push('cancel2'); + } + if (event.isMine()) { + if (event.arrangeSkill) { + var hidden = player.hiddenSkills.slice(0); + game.expandSkills(hidden); + if (hidden.length) { + for (var i of event.controls) { + if (_status.prehidden_skills.includes(i) && hidden.includes(i)) { + event.result = { + bool: true, + control: i, + }; + return; + } + } + } + } + else if (event.hsskill && _status.prehidden_skills.includes(event.hsskill) && event.controls.includes('cancel2')) { + event.result = { + bool: true, + control: 'cancel2', + }; + return; + } + if (event.sortcard) { + var prompt = event.prompt || '选择一个位置'; + if (event.tosort) { + prompt += '放置' + get.translation(event.tosort); + } + event.dialog = ui.create.dialog(prompt, 'hidden'); + if (event.sortcard && event.sortcard.length) { + event.dialog.addSmall(event.sortcard); + } + else { + event.dialog.buttons = []; + event.dialog.add(ui.create.div('.buttons')); + } + var buttons = event.dialog.content.lastChild; + var sortnum = 2; + if (event.sorttop) { + sortnum = 1; + } + for (var i = 0; i < event.dialog.buttons.length + sortnum; i++) { + var item = ui.create.div('.button.card.pointerdiv.mebg'); + item.style.width = '50px'; + buttons.insertBefore(item, event.dialog.buttons[i]); + item.innerHTML = '
第' + get.cnNumber(i + 1, true) + '张
'; + if (i == event.dialog.buttons.length + 1) { + item.firstChild.innerHTML = '牌堆底'; + } + item.link = get.cnNumber(i, true); + item.listen(ui.click.dialogcontrol); + } + + event.dialog.forcebutton = true; + event.dialog.classList.add('forcebutton'); + event.dialog.open(); + } + else if (event.dialogcontrol) { + event.dialog = ui.create.dialog(event.prompt || '选择一项', 'hidden'); + for (var i = 0; i < event.controls.length; i++) { + var item = event.dialog.add(''); + item.firstChild.listen(ui.click.dialogcontrol); + item.firstChild.link = event.controls[i]; + } + event.dialog.forcebutton = true; + event.dialog.classList.add('forcebutton'); + if (event.addDialog) { + for (var i = 0; i < event.addDialog.length; i++) { + if (get.itemtype(event.addDialog[i]) == 'cards') { + event.dialog.addSmall(event.addDialog[i]); + } + else { + event.dialog.add(event.addDialog[i]); + } + } + event.dialog.add(ui.create.div('.placeholder.slim')); + } + event.dialog.open(); + } + else { + if (event.seperate || lib.config.seperate_control) { + var controls = event.controls.slice(0); + var num = 0; + controls.remove('cancel2'); + if (event.direct && controls.length == 1 || event.forceDirect) { + event.result = { + control: event.controls[0].link, + links: get.links([event.controls[0]]), + }; + return; + } + else { + event.controlbars = []; + for (var i = 0; i < event.controls.length; i++) { + event.controlbars.push(ui.create.control([event.controls[i]])); + } + } + } + else { + var controls = event.controls.slice(0); + var num = 0; + controls.remove('cancel2'); + if (event.direct && controls.length == 1 || event.forceDirect) { + event.result = { + control: event.controls[0].link, + links: get.links([event.controls[0]]), + }; + return; + } + event.controlbar = ui.create.control(event.controls); + } + if (event.dialog) { + if (Array.isArray(event.dialog)) { + event.dialog = ui.create.dialog.apply(this, event.dialog); + } + event.dialog.open(); + } + else if (event.choiceList) { + event.dialog = ui.create.dialog(event.prompt || '选择一项', 'hidden'); + event.dialog.forcebutton = true; + event.dialog.open(); + for (var i = 0; i < event.choiceList.length; i++) { + event.dialog.add(''); + } + } + else if (event.prompt) { + event.dialog = ui.create.dialog(event.prompt); + if (event.prompt2) { + event.dialog.addText(event.prompt2, Boolean(event.prompt2.length <= 20 || event.centerprompt2)); + } + } + } + game.pause(); + game.countChoose(); + event.choosing = true; + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + "step 1"; + if (event.result == 'ai') { + event.result = {}; + if (event.ai) { + var result = event.ai(event.getParent(), player); + if (typeof result == 'number') event.result.control = event.controls[result]; + else event.result.control = result; + } + else event.result.control = event.controls[event.choice]; + } + event.result.index = event.controls.indexOf(event.result.control); + event.choosing = false; + _status.imchoosing = false; + if (event.dialog && event.dialog.close) event.dialog.close(); + if (event.controlbar) event.controlbar.close(); + if (event.controlbars) { + for (var i = 0; i < event.controlbars.length; i++) { + event.controlbars[i].close(); + } + } + event.resume(); + }, + chooseBool: function () { + "step 0"; + if (event.isMine()) { + if (event.frequentSkill && !lib.config.autoskilllist.includes(event.frequentSkill)) { + ui.click.ok(); + return; + } + else if (event.hsskill && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + ui.create.confirm('oc'); + if (event.createDialog && !event.dialog) { + if (Array.isArray(event.createDialog)) { + event.dialog = ui.create.dialog.apply(this, event.createDialog); + if (event.dialogselectx) { + for (var i = 0; i < event.dialog.buttons.length; i++) { + event.dialog.buttons[i].classList.add('selectedx'); + } + } + } + } + if (event.dialog) { + event.dialog.open(); + } + else if (event.prompt) { + event.dialog = ui.create.dialog(event.prompt); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + } + game.pause(); + game.countChoose(); + event.choosing = true; + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + "step 1"; + if (event.result == 'ai') { + if (event.ai) { + event.choice = event.ai(event.getParent(), player); + } + event.result = { bool: event.choice }; + } + _status.imchoosing = false; + event.choosing = false; + if (event.dialog) event.dialog.close(); + event.resume(); + }, + chooseDrawRecover: function () { + 'step 0'; + if (player.isHealthy() && event.forced) { + player.draw(event.num1); + event.finish(); + return; + } + var controls = ['draw_card']; + if (player.isDamaged()) { + event.num2 = Math.min(event.num2, player.maxHp - player.hp); + controls.push('recover_hp'); + } + if (!event.forced) { + controls.push('cancel2'); + } + var prompt = event.prompt; + if (!prompt) { + if (player.isHealthy()) { + prompt = '是否摸' + get.cnNumber(event.num1) + '张牌?'; + } + else { + prompt = '摸' + get.cnNumber(event.num1) + '张牌或回复' + get.cnNumber(event.num2) + '点体力'; + } + } + var next = player.chooseControl(controls); + next.set('prompt', prompt); + if (event.hsskill) next.setHiddenSkill(event.hsskill); + if (event.ai) { + next.set('ai', event.ai); + } + else { + var choice; + if (player.isDamaged() && get.recoverEffect(player) > 0 && ( + player.hp == 1 || player.needsToDiscard() || + player.hasSkillTag('maixie_hp') || event.num2 > event.num1 || + (event.num2 == event.num1 && player.needsToDiscard(1)) + )) { + choice = 'recover_hp'; + } + else { + choice = 'draw_card'; + } + next.set('ai', function () { + return _status.event.choice; + }); + next.set('choice', choice); + } + 'step 1'; + if (result.control != 'cancel2') { + if (event.logSkill) { + if (typeof event.logSkill == 'string') { + player.logSkill(event.logSkill); + } + else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + if (result.control == 'draw_card') { + player.draw(event.num1); + } + else { + player.recover(event.num2); + } + } + event.result = result; + }, + choosePlayerCard: function () { + "step 0"; + if (!event.dialog) event.dialog = ui.create.dialog('hidden'); + else if (!event.isMine()) { + event.dialog.style.display = 'none'; + } + if (event.prompt) { + event.dialog.add(event.prompt); + } + else { + event.dialog.add('选择' + get.translation(target) + '的一张牌'); + } + if (event.prompt2) { + event.dialog.addText(event.prompt2); + } + var expand_length = 0; + var directh = (!lib.config.unauto_choose && !event.complexSelect); + for (var i = 0; i < event.position.length; i++) { + if (event.position[i] == 'h') { + var hs = target.getCards('h'); + if (hs.length) { + expand_length += Math.ceil(hs.length / 6); + var title = event.dialog.add('
手牌区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + hs.randomSort(); + if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { + event.dialog.add(hs); + directh = false; + } + else { + var shown = hs.filter(card => get.is.shownCard(card)); + if (shown.length) { + var hidden = hs.filter(card => !shown.includes(card)); + var buttons = ui.create.div('.buttons', event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); + event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove('forcebutton-auto'); + } + else if (!event.dialog.noforcebutton) { + event.dialog.classList.add('forcebutton-auto'); + } + } + else { + event.dialog.add([hs, 'blank']); + } + } + } + } + else if (event.position[i] == 'e') { + var es = target.getCards('e'); + if (es.length) { + expand_length += Math.ceil(es.length / 6); + var title = event.dialog.add('
装备区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + event.dialog.add(es); + directh = false; + } + } + else if (event.position[i] == 'j') { + var js = target.getCards('j'); + if (js.length) { + expand_length += Math.ceil(js.length / 6); + var title = event.dialog.add('
判定区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + event.dialog.add(js); + directh = false; + } + } + } + if (event.dialog.buttons.length == 0) { + event.finish(); + return; + } var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); + var cs = target.getCards(event.position); + var select = get.select(event.selectButton); + if (directFilter && select[0] >= cs.length) { + event.result = { + bool: true, + buttons: event.dialog.buttons, + links: cs + }; + } + else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { + event.result = { + bool: true, + buttons: event.dialog.buttons.randomGets(select[0]), + links: [] + }; + for (var i = 0; i < event.result.buttons.length; i++) { + event.result.links[i] = event.result.buttons[i].link; + } + } + else { + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + event.dialog.open(); + game.check(); + game.pause(); + if (expand_length > 2) { + ui.arena.classList.add('choose-player-card'); + event.dialog.classList.add('fullheight'); + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + } + "step 1"; + if (event.result == 'ai') { + game.check(); + if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); + else ui.click.cancel(); + } + event.dialog.close(); + if (event.result.links) { + event.result.cards = event.result.links.slice(0); + } + event.resume(); + setTimeout(function () { + ui.arena.classList.remove('choose-player-card'); + }, 500); + }, + discardPlayerCard: function () { + "step 0"; + if (event.directresult) { + event.result = { + buttons: [], + cards: event.directresult.slice(0), + links: event.directresult.slice(0), + targets: [], + confirm: 'ok', + bool: true + }; + event.cards = event.directresult.slice(0); + event.goto(2); + return; + } + if (!event.dialog) event.dialog = ui.create.dialog('hidden'); + else if (!event.isMine()) { + event.dialog.style.display = 'none'; + } + if (event.prompt == undefined) { + var str = '弃置' + get.translation(target); + var range = get.select(event.selectButton); + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); + str += '张'; + if (event.position == 'h' || event.position == undefined) str += '手'; + if (event.position == 'e') str += '装备'; + str += '牌'; + event.prompt = str; + } + if (event.prompt) { + event.dialog.add(event.prompt); + } + if (event.prompt2) { + event.dialog.addText(event.prompt2); + } + var directh = (!lib.config.unauto_choose && !event.complexSelect); + var expand_length = 0; + for (var i = 0; i < event.position.length; i++) { + if (event.position[i] == 'h') { + var hs = target.getDiscardableCards(player, 'h'); + expand_length += Math.ceil(hs.length / 6); + if (hs.length) { + var title = event.dialog.add('
手牌区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + hs.randomSort(); + if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { + event.dialog.add(hs); + directh = false; + } + else { + var shown = hs.filter(card => get.is.shownCard(card)); + if (shown.length) { + var hidden = hs.filter(card => !shown.includes(card)); + var buttons = ui.create.div('.buttons', event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); + event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove('forcebutton-auto'); + } + else if (!event.dialog.noforcebutton) { + event.dialog.classList.add('forcebutton-auto'); + } + } + else { + event.dialog.add([hs, 'blank']); + } + } + } + } + else if (event.position[i] == 'e') { + var es = target.getDiscardableCards(player, 'e'); + if (es.length) { + expand_length += Math.ceil(es.length / 6); + var title = event.dialog.add('
装备区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + event.dialog.add(es); + directh = false; + } + } + else if (event.position[i] == 'j') { + var js = target.getDiscardableCards(player, 'j'); + if (js.length) { + expand_length += Math.ceil(js.length / 6); + var title = event.dialog.add('
判定区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + event.dialog.add(js); + directh = false; + } + } + } + if (event.dialog.buttons.length == 0) { + event.finish(); + return; + } + var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); + var cs = target.getCards(event.position); + var select = get.select(event.selectButton); + if (directFilter && select[0] >= cs.length) { + event.result = { + bool: true, + buttons: event.dialog.buttons, + links: cs + }; + } + else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { + event.result = { + bool: true, + buttons: event.dialog.buttons.randomGets(select[0]), + links: [] + }; + for (var i = 0; i < event.result.buttons.length; i++) { + event.result.links[i] = event.result.buttons[i].link; + } + } + else { + if (event.isMine()) { + event.dialog.open(); + game.check(); + game.pause(); + if (expand_length > 2) { + ui.arena.classList.add('discard-player-card'); + event.dialog.classList.add('fullheight'); + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + } + "step 1"; + if (event.result == 'ai') { + game.check(); + if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); + else ui.click.cancel(); + } + event.dialog.close(); + "step 2"; + event.resume(); + setTimeout(function () { + ui.arena.classList.remove('discard-player-card'); + }, 500); + if (event.result.bool && event.result.links && !game.online) { + if (event.logSkill) { + if (typeof event.logSkill == 'string') { + player.logSkill(event.logSkill); + } + else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + var cards = []; + for (var i = 0; i < event.result.links.length; i++) { + cards.push(event.result.links[i]); + } + event.result.cards = event.result.links.slice(0); + event.cards = cards; + event.trigger("rewriteDiscardResult"); + } + "step 3"; + if (event.boolline) { + player.line(target, 'green'); + } + if (!event.chooseonly) { + var next = target.discard(event.cards); + if (player != target) next.notBySelf = true; + next.discarder = player; + event.done = next; + if (event.delay === false) { + next.set('delay', false); + } + } + }, + gainPlayerCard: function () { + "step 0"; + if (event.directresult) { + event.result = { + buttons: [], + cards: event.directresult.slice(0), + links: event.directresult.slice(0), + targets: [], + confirm: 'ok', + bool: true + }; + event.cards = event.directresult.slice(0); + event.goto(2); + return; + } + if (!event.dialog) event.dialog = ui.create.dialog('hidden'); + else if (!event.isMine()) { + event.dialog.style.display = 'none'; + } + if (event.prompt == undefined) { + var str = '获得' + get.translation(target); + var range = get.select(event.selectButton); + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); + str += '张'; + if (event.position == 'h' || event.position == undefined) str += '手'; + if (event.position == 'e') str += '装备'; + str += '牌'; + event.prompt = str; + } + if (event.prompt) { + event.dialog.add(event.prompt); + } + if (event.prompt2) { + event.dialog.addText(event.prompt2); + } + var expand_length = 0; + var directh = (!lib.config.unauto_choose && !event.complexSelect); + for (var i = 0; i < event.position.length; i++) { + if (event.position[i] == 'h') { + var hs = target.getGainableCards(player, 'h'); + if (hs.length) { + expand_length += Math.ceil(hs.length / 6); + var title = event.dialog.add('
手牌区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + hs.randomSort(); + if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { + event.dialog.add(hs); + directh = false; + } + else { + var shown = hs.filter(card => get.is.shownCard(card)); + if (shown.length) { + var hidden = hs.filter(card => !shown.includes(card)); + var buttons = ui.create.div('.buttons', event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); + event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove('forcebutton-auto'); + } + else if (!event.dialog.noforcebutton) { + event.dialog.classList.add('forcebutton-auto'); + } + } + else { + event.dialog.add([hs, 'blank']); + } + } + } + } + else if (event.position[i] == 'e') { + var es = target.getGainableCards(player, 'e'); + if (es.length) { + expand_length += Math.ceil(es.length / 6); + var title = event.dialog.add('
装备区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + event.dialog.add(es); + directh = false; + } + } + else if (event.position[i] == 'j') { + var js = target.getGainableCards(player, 'j'); + if (js.length) { + expand_length += Math.ceil(js.length / 6); + var title = event.dialog.add('
判定区
'); + title.style.margin = '0px'; + title.style.padding = '0px'; + event.dialog.add(js); + directh = false; + } + } + } + if (event.dialog.buttons.length == 0) { + event.dialog.close(); + event.finish(); + return; + } + var cs = target.getCards(event.position); + var select = get.select(event.selectButton); + var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); + if (directFilter && select[0] >= cs.length) { + event.result = { + bool: true, + buttons: event.dialog.buttons, + links: cs + }; + } + else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { + event.result = { + bool: true, + buttons: event.dialog.buttons.randomGets(select[0]), + links: [] + }; + for (var i = 0; i < event.result.buttons.length; i++) { + event.result.links[i] = event.result.buttons[i].link; + } + } + else { + if (event.isMine()) { + event.dialog.open(); + game.check(); + game.pause(); + if (expand_length > 2) { + ui.arena.classList.add('gain-player-card'); + event.dialog.classList.add('fullheight'); + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.result = 'ai'; + } + } + "step 1"; + if (event.result == 'ai') { + game.check(); + if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); + else ui.click.cancel(); + } + event.dialog.close(); + "step 2"; + event.resume(); + setTimeout(function () { + ui.arena.classList.remove('gain-player-card'); + }, 500); + if (game.online || !event.result.bool) { + event.finish(); + } + "step 3"; + if (event.logSkill && event.result.bool && !game.online) { + if (typeof event.logSkill == 'string') { + player.logSkill(event.logSkill); + } + else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + var cards = []; + for (var i = 0; i < event.result.links.length; i++) { + cards.push(event.result.links[i]); + } + event.result.cards = event.result.links.slice(0); + event.cards = cards; + event.trigger("rewriteGainResult"); + "step 4"; + if (event.boolline) { + player.line(target, 'green'); + } + if (!event.chooseonly) { + if (event.delay !== false) { + var next = player.gain(event.cards, target, event.visibleMove ? 'give' : 'giveAuto', 'bySelf'); + event.done = next; + } + else { + var next = player.gain(event.cards, target, 'bySelf'); + event.done = next; + target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); + if (event.visibleMove) next.visible = true; + } + } + else target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); + }, + showHandcards: function () { + "step 0"; + if (player.countCards('h') == 0) { + event.finish(); + return; + } + var cards = player.getCards('h'); + player.showCards(cards).setContent(function () { }); + var str = get.translation(player.name) + '的手牌'; + if (typeof event.prompt == 'string') { + str = event.prompt; + } + event.dialog = ui.create.dialog(str, cards); + event.dialogid = lib.status.videoId++; + event.dialog.videoId = event.dialogid; + game.broadcast(function (str, cards, id) { + ui.create.dialog(str, cards).videoId = id; + }, str, cards, event.dialogid); + game.log(player, '展示了', cards); + game.addVideo('showCards', player, [str, get.cardsInfo(cards)]); + game.delayx(2); + "step 1"; + game.broadcast('closeDialog', event.dialogid); + event.dialog.close(); + }, + showCards: function () { + "step 0"; + if (get.itemtype(cards) != 'cards') { + event.finish(); + return; + } + if (!event.str) { + event.str = get.translation(player.name) + '展示的牌'; + } + event.dialog = ui.create.dialog(event.str, cards); + event.dialogid = lib.status.videoId++; + event.dialog.videoId = event.dialogid; + + if (event.hiddencards) { + for (var i = 0; i < event.dialog.buttons.length; i++) { + if (event.hiddencards.includes(event.dialog.buttons[i].link)) { + event.dialog.buttons[i].className = 'button card'; + event.dialog.buttons[i].innerHTML = ''; + } + } + } + game.broadcast(function (str, cards, cards2, id) { + var dialog = ui.create.dialog(str, cards); + dialog.forcebutton = true; + dialog.videoId = id; + if (cards2) { + for (var i = 0; i < dialog.buttons.length; i++) { + if (cards2.includes(dialog.buttons[i].link)) { + dialog.buttons[i].className = 'button card'; + dialog.buttons[i].innerHTML = ''; + } + } + } + }, event.str, cards, event.hiddencards, event.dialogid); + if (event.hiddencards) { + var cards2 = cards.slice(0); + for (var i = 0; i < event.hiddencards.length; i++) { + cards2.remove(event.hiddencards[i]); + } + game.log(player, '展示了', cards2); + } + else { + game.log(player, '展示了', cards); + } + game.addCardKnower(cards, 'everyone'); + game.delayx(event.delay_time || 2.5); + game.addVideo('showCards', player, [event.str, get.cardsInfo(cards)]); + "step 1"; + game.broadcast('closeDialog', event.dialogid); + event.dialog.close(); + }, + viewCards: function () { + "step 0"; + game.addCardKnower(event.cards, player); + if (player == game.me) { + event.dialog = ui.create.dialog(event.str, event.cards); + if (event.isMine()) { + game.pause(); + ui.create.confirm('o'); + game.countChoose(); + event.choosing = true; + } + else { + event.finish(); + event.result = 'viewed'; + setTimeout(function () { + event.dialog.close(); + }, 2 * lib.config.duration); + game.delayx(2); + } + } + else if (event.isOnline()) { + event.send(); + } + else { + event.finish(); + } + "step 1"; + event.result = 'viewed'; + _status.imchoosing = false; + event.choosing = false; + if (event.dialog) event.dialog.close(); + }, + moveCard: function () { + 'step 0'; + if (!player.canMoveCard(null, event.nojudge, event.sourceTargets, event.aimTargets, event.filter, event.canReplace ? 'canReplace' : 'noReplace')) { + event.finish(); + return; + } + var next = player.chooseTarget(2, function (card, player, target) { + var filterCard = get.event('filter'); + if (ui.selected.targets.length) { + if (!get.event('aimTargets').includes(target)) return false; + var from = ui.selected.targets[0]; + var js = from.getCards('j', filterCard); + for (var i = 0; i < js.length; i++) { + if (_status.event.nojudge) break; + if (target.canAddJudge(js[i])) return true; + } + if (target.isMin()) return false; + var es = from.getCards('e', filterCard); + for (var i = 0; i < es.length; i++) { + if (target.canEquip(es[i], _status.event.canReplace)) return true; + } + return false; + } + else { + if (!get.event('sourceTargets').includes(target)) return false; + var range = 'ej'; + if (_status.event.nojudge) range = 'e'; + return target.countCards(range, filterCard) > 0; + } + }); + next.set('nojudge', event.nojudge || false); + next.set('ai', function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + var sgnatt = get.sgn(att); + var aimTargets = get.event('aimTargets'), filterCard = get.event('filter'); + if (ui.selected.targets.length == 0) { + if (att > 0) { + if (!_status.event.nojudge && target.countCards('j', function (card) { + if (!filterCard(card)) return false; + return game.hasPlayer(function (current) { + if (!aimTargets.includes(current)) return false; + return current != target && current.canAddJudge(card) && get.attitude(player, current) < 0; + }); + })) return 14; + if (target.countCards('e', function (card) { + if (!filterCard(card)) return false; + return get.value(card, target) < 0 && game.hasPlayer(function (current) { + if (!aimTargets.includes(current)) return false; + return current != target && get.attitude(player, current) < 0 && current.canEquip(card, _status.event.canReplace) && get.effect(target, card, player, player) < 0; + }); + }) > 0) return 9; + } + else if (att < 0) { + if (game.hasPlayer(function (current) { + if (current != target && get.attitude(player, current) > 0) { + var es = target.getCards('e', filterCard); + for (var i = 0; i < es.length; i++) { + if (get.value(es[i], target) > 0 && current.canEquip(es[i], _status.event.canReplace) && get.effect(current, es[i], player, player) > (_status.event.canReplace ? get.effect(target, es[i], player, player) : 0)) return true; + } + } + })) { + return -att; + } + } + return 0; + } + var es = ui.selected.targets[0].getCards('e', filterCard); + var i; + var att2 = get.sgn(get.attitude(player, ui.selected.targets[0])); + for (i = 0; i < es.length; i++) { + if (sgnatt != 0 && att2 != 0 && sgnatt != att2 && + get.sgn(get.value(es[i], ui.selected.targets[0])) == -att2 && + get.sgn(get.effect(target, es[i], player, target)) == sgnatt && + target.canEquip(es[i], _status.event.canReplace)) { + return Math.abs(att); + } + } + if (i == es.length && (_status.event.nojudge || !ui.selected.targets[0].countCards('j', function (card) { + if (!filterCard(card)) return false; + return target.canAddJudge(card); + }) || att2 <= 0)) { + return 0; + } + return -att * att2; + }); + next.set('multitarget', true); + next.set('targetprompt', _status.event.targetprompt || ['被移走', '移动目标']); + next.set('prompt', event.prompt || '移动场上的一张牌'); + next.set('filter', event.filter); + next.set('sourceTargets', event.sourceTargets || game.filterPlayer()); + next.set('aimTargets', event.aimTargets || game.filterPlayer()); + next.set('canReplace', event.canReplace); + next.set('custom', get.copy(event.custom)); + if (event.prompt2) next.set('prompt2', event.prompt2); + if (event.forced) next.set('forced', true); + 'step 1'; + event.result = result; + if (result.bool) { + if (event.logSkill) player.logSkill(event.logSkill, result.targets, false); + player.line2(result.targets, 'green'); + event.targets = result.targets; + } + else { + event.finish(); + } + 'step 2'; + game.delay(); + 'step 3'; + if (targets.length == 2) { + player.choosePlayerCard('ej', true, function (button) { + var player = _status.event.player; + var targets0 = _status.event.targets0; + var targets1 = _status.event.targets1; + if (get.attitude(player, targets0) > 0 && get.attitude(player, targets1) < 0) { + if (get.position(button.link) == 'j') return 12; + if (get.value(button.link, targets0) < 0 && get.effect(targets1, button.link, player, targets1) > 0) return 10; + return 0; + } + else { + if (get.position(button.link) == 'j') return -10; + return get.value(button.link) * get.effect(targets1, button.link, player, targets1); + } + }, targets[0]).set('nojudge', event.nojudge || false).set('targets0', targets[0]).set('targets1', targets[1]).set('filterButton', function (button) { + var targets1 = _status.event.targets1; + if (!get.event('filter')(button.link)) return false; + if (get.position(button.link) == 'j') { + if (_status.event.nojudge) return false; + return targets1.canAddJudge(button.link); + } + else { + return targets1.canEquip(button.link, _status.event.canReplace); + } + }).set('filter', event.filter).set('canReplace', event.canReplace).set('custom', get.copy(event.custom)); + } + else { + event.finish(); + } + 'step 4'; + if (result.bool && result.links.length) { + var link = result.links[0]; + if (get.position(link) == 'e') { + event.targets[1].equip(link); + } + else if (link.viewAs) { + event.targets[1].addJudge({ name: link.viewAs }, [link]); + } + else { + event.targets[1].addJudge(link); + } + event.targets[0].$give(link, event.targets[1], false); + game.log(event.targets[0], '的', link, '被移动给了', event.targets[1]); + event.result.card = link; + event.result.position = get.position(link); + game.delay(); + } + }, + useCard: function () { + "step 0"; + if (!card) { + console.log('err: no card', get.translation(event.player)); + event.finish(); + return; + } + if (!get.info(card, false).noForceDie) event.forceDie = true; + if (cards.length) { + var owner = (get.owner(cards[0]) || player); + var next = owner.lose(cards, 'visible', ui.ordering).set('type', 'use'); + var directDiscard = []; + for (var i = 0; i < cards.length; i++) { + if (!next.cards.includes(cards[i])) { + directDiscard.push(cards[i]); + } + } + if (directDiscard.length) game.cardsGotoOrdering(directDiscard); + } + //player.using=cards; + var cardaudio = true; + if (event.skill) { + if (lib.skill[event.skill].audio) { + cardaudio = false; + } + if (lib.skill[event.skill].log != false) { + player.logSkill(event.skill); + } + if (get.info(event.skill).popname) { + player.tryCardAnimate(card, event.card.name, 'metal', true); + } + } + else if (!event.nopopup) { + if (lib.translate[event.card.name + '_pop']) { + player.tryCardAnimate(card, lib.translate[event.card.name + '_pop'], 'metal'); + } + else { + player.tryCardAnimate(card, event.card.name, 'metal'); + } + } + if (event.audio === false) { + cardaudio = false; + } + if (cardaudio) game.broadcastAll((player, card) => { + game.playCardAudio(card, player); + /* + if(!lib.config.background_audio||get.type(card)=='equip'&&!lib.config.equip_audio) return; + const sex=player.sex=='female'?'female':'male'; + var nature=get.natureList(card)[0]; + if(card.name=='sha'&&['fire','thunder','ice','stab'].includes(nature)){ + game.playAudio('card',sex,`${card.name}_${nature}`); + return; + } + const audio=lib.card[card.name].audio; + if(typeof audio=='string'){ + const audioInfo=audio.split(':'); + if(audio.startsWith('db:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,audioInfo[2],`${card.name}_${sex}.${audioInfo[3]||'mp3'}`); + else if(audio.startsWith('ext:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${card.name}_${sex}.${audioInfo[2]||'mp3'}`); + else game.playAudio('card',sex,`${audioInfo[0]}.${audioInfo[1]||'mp3'}`); + } + else game.playAudio('card',sex,card.name);*/ + }, player, card); + if (event.animate != false && event.line != false) { + if (card.name == 'wuxie' && event.getParent()._info_map) { + var evtmap = event.getParent()._info_map; + if (evtmap._source) evtmap = evtmap._source; + var lining = (evtmap.multitarget ? evtmap.targets : evtmap.target) || event.player; + if (Array.isArray(lining) && event.getTrigger().name == 'jiedao') { + player.line(lining[0], 'green'); + } + else { + player.line(lining, 'green'); + } + } + else if (card.name == 'youdishenru' && event.getParent().source) { + var lining = event.getParent().sourcex || event.getParent().source2 || event.getParent().source; + if (lining == player && event.getParent().sourcex2) { + lining = event.getParent().sourcex2; + } + if (Array.isArray(lining) && event.getTrigger().name == 'jiedao') { + player.line(lining[0], 'green'); + } + else { + player.line(lining, 'green'); + } + } + else { + var config = {}; + var nature = get.natureList(card)[0]; + if (nature || card.classList && card.classList.contains(nature)) config.color = nature; + if (event.addedTarget) { + player.line2(targets.concat(event.addedTargets), config); + } + else if (get.info(card, false).multitarget && targets.length > 1 && !get.info(card, false).multiline) { + player.line2(targets, config); + } + else { + player.line(targets, config); + } + } + if (event.throw !== false) player.$throw(cards); + if (lib.config.sync_speed && cards[0] && cards[0].clone) { + var waitingForTransition = get.time(); + event.waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete event.waitingForTransition; + }); + } + } + event.id = get.id(); + if (!Array.isArray(event.excluded)) event.excluded = []; + if (!Array.isArray(event.directHit)) event.directHit = []; + if (typeof event.customArgs != 'object' || typeof event.customArgs.default != 'object') event.customArgs = { default: {} }; + if (typeof event.baseDamage != 'number') event.baseDamage = get.info(card, false).baseDamage || 1; + if (typeof event.effectCount != 'number') event.effectCount = get.info(card, false).effectCount || 1; + event.effectedCount = 0; + if (event.oncard) { + event.oncard(event.card, event.player); + } + player.actionHistory[player.actionHistory.length - 1].useCard.push(event); + game.getGlobalHistory().useCard.push(event); + if (event.addCount !== false) { + if (player.stat[player.stat.length - 1].card[card.name] == undefined) { + player.stat[player.stat.length - 1].card[card.name] = 1; + } + else { + player.stat[player.stat.length - 1].card[card.name]++; + } + } + if (event.skill) { + if (player.stat[player.stat.length - 1].skill[event.skill] == undefined) { + player.stat[player.stat.length - 1].skill[event.skill] = 1; + } + else { + player.stat[player.stat.length - 1].skill[event.skill]++; + } + var sourceSkill = get.info(event.skill).sourceSkill; + if (sourceSkill) { + if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { + player.stat[player.stat.length - 1].skill[sourceSkill] = 1; + } + else { + player.stat[player.stat.length - 1].skill[sourceSkill]++; + } + } + } + if (targets.length) { + var str = (targets.length == 1 && targets[0] == player) ? '#b自己' : targets; + if (cards.length && !card.isCard) { + if (event.addedTarget) { + game.log(player, '对', str, '使用了', card, '(', cards, ',指向', event.addedTargets, ')'); + } + else { + game.log(player, '对', str, '使用了', card, '(', cards, ')'); + } + } + else { + if (event.addedTarget) { + game.log(player, '对', str, '使用了', card, '(指向', event.addedTargets, ')'); + } + else { + game.log(player, '对', str, '使用了', card); + } + } + } + else { + if (cards.length && !card.isCard) { + if (event.addedTarget) { + game.log(player, '使用了', card, '(', cards, ',指向', event.addedTargets, ')'); + } + else { + game.log(player, '使用了', card, '(', cards, ')'); + } + } + else { + if (event.addedTarget) { + game.log(player, '使用了', card, '(指向', event.addedTargets, ')'); + } + else { + game.log(player, '使用了', card); + } + } + } + if (card.name == 'wuxie') { + game.logv(player, [card, cards], [event.getTrigger().card]); + } + else { + game.logv(player, [card, cards], targets); + } + event.trigger('useCard1'); + "step 1"; + event.trigger('yingbian'); + "step 2"; + event.trigger('useCard2'); + "step 3"; + event.trigger('useCard'); + event._oncancel = function () { + game.broadcastAll(function (id) { + if (ui.tempnowuxie && ui.tempnowuxie._origin == id) { + ui.tempnowuxie.close(); + delete ui.tempnowuxie; + } + }, event.id); + }; + "step 4"; + event.sortTarget = function (animate, sort) { + var info = get.info(card, false); + if (num == 0 && targets.length > 1) { + if (!info.multitarget) { + if (!event.fixedSeat && !sort) { + targets.sortBySeat((_status.currentPhase || player)); + } + if (animate) for (var i = 0; i < targets.length; i++) { + targets[i].addTempClass('target'); + } + } + else if (animate) { + for (var i = 0; i < targets.length; i++) { + targets[i].addTempClass('target'); + } + } + } + }; + event.sortTarget(); + event.getTriggerTarget = function (list1, list2) { + var listx = list1.slice(0).sortBySeat((_status.currentPhase || player)); + for (var i = 0; i < listx.length; i++) { + if (get.numOf(list2, listx[i]) < get.numOf(listx, listx[i])) return listx[i]; + } + return null; + }; + "step 5"; + if (event.all_excluded) return; + if (!event.triggeredTargets1) event.triggeredTargets1 = []; + var target = event.getTriggerTarget(targets, event.triggeredTargets1); + if (target) { + event.triggeredTargets1.push(target); + var next = game.createEvent('useCardToPlayer', false); + if (!event.isFirstTarget1) { + event.isFirstTarget1 = true; + next.isFirstTarget = true; + } + next.setContent('emptyEvent'); + next.targets = targets; + next.target = target; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.excluded = event.excluded; + next.directHit = event.directHit; + next.customArgs = event.customArgs; + if (event.forceDie) next.forceDie = true; + event.redo(); + } + "step 6"; + if (event.all_excluded) return; + if (!event.triggeredTargets2) event.triggeredTargets2 = []; + var target = event.getTriggerTarget(targets, event.triggeredTargets2); + if (target) { + event.triggeredTargets2.push(target); + var next = game.createEvent('useCardToTarget', false); + if (!event.isFirstTarget2) { + event.isFirstTarget2 = true; + next.isFirstTarget = true; + } + next.setContent('emptyEvent'); + next.targets = targets; + next.target = target; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.excluded = event.excluded; + next.directHit = event.directHit; + next.customArgs = event.customArgs; + if (event.forceDie) next.forceDie = true; + event.redo(); + } + "step 7"; + var info = get.info(card, false); + if (!info.nodelay && event.animate != false) { + if (event.delayx !== false) { + if (event.waitingForTransition) { + _status.waitingForTransition = event.waitingForTransition; + game.pause(); + } + else { + game.delayx(); + } + } + } + "step 8"; + if (event.all_excluded) return; + if (!event.triggeredTargets3) event.triggeredTargets3 = []; + var target = event.getTriggerTarget(targets, event.triggeredTargets3); + if (target) { + event.triggeredTargets3.push(target); + var next = game.createEvent('useCardToPlayered', false); + if (!event.isFirstTarget3) { + event.isFirstTarget3 = true; + next.isFirstTarget = true; + } + next.setContent('emptyEvent'); + next.targets = targets; + next.target = target; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.excluded = event.excluded; + next.directHit = event.directHit; + next.customArgs = event.customArgs; + if (event.forceDie) next.forceDie = true; + event.redo(); + } + "step 9"; + if (event.all_excluded) return; + if (!event.triggeredTargets4) event.triggeredTargets4 = []; + var target = event.getTriggerTarget(targets, event.triggeredTargets4); + if (target) { + event.triggeredTargets4.push(target); + var next = game.createEvent('useCardToTargeted', false); + if (!event.isFirstTarget4) { + event.isFirstTarget4 = true; + next.isFirstTarget = true; + } + next.setContent('emptyEvent'); + next.targets = targets; + next.target = target; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.excluded = event.excluded; + next.directHit = event.directHit; + next.customArgs = event.customArgs; + if (event.forceDie) next.forceDie = true; + if (targets.length == event.triggeredTargets4.length) { + event.sortTarget(); + } + event.redo(); + } + "step 10"; + if (event.all_excluded) return; + event.effectedCount++; + event.num = 0; + var info = get.info(card, false); + if (info.contentBefore) { + var next = game.createEvent(card.name + 'ContentBefore'); + next.setContent(info.contentBefore); + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.type = 'precard'; + if (event.forceDie) next.forceDie = true; + } + else if (info.reverseOrder && get.is.versus() && targets.length > 1) { + var next = game.createEvent(card.name + 'ContentBefore'); + next.setContent('reverseOrder'); + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.type = 'precard'; + if (event.forceDie) next.forceDie = true; + } + else if (info.singleCard && info.filterAddedTarget && event.addedTargets && event.addedTargets.length < targets.length) { + var next = game.createEvent(card.name + 'ContentBefore'); + next.setContent('addExtraTarget'); + next.target = target; + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.type = 'precard'; + next.addedTarget = event.addedTarget; + next.addedTargets = event.addedTargets; + if (event.forceDie) next.forceDie = true; + } + "step 11"; + if (event.all_excluded) return; + var info = get.info(card, false); + if (num == 0 && targets.length > 1) { + event.sortTarget(true, true); + } + if (targets[num] && targets[num].isDead()) return; + if (targets[num] && targets[num].isOut()) return; + if (targets[num] && targets[num].removed) return; + if (targets[num] && info.ignoreTarget && info.ignoreTarget(card, player, targets[num])) return; + if (targets.length == 0 && !info.notarget) return; + if (targets[num] && event.excluded.includes(targets[num])) { + var next = game.createEvent('useCardToExcluded', false); + next.setContent('emptyEvent'); + next.targets = targets; + next.target = targets[num]; + next.num = num; + next.card = card; + next.cards = cards; + next.player = player; + return; + } + var next = game.createEvent(card.name); + next.setContent(info.content); + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.num = num; + next.type = 'card'; + next.skill = event.skill; + next.multitarget = info.multitarget; + next.preResult = event.preResult; + next.baseDamage = event.baseDamage; + if (event.forceDie) next.forceDie = true; + if (event.addedTargets) { + next.addedTargets = event.addedTargets; + next.addedTarget = event.addedTargets[num]; + next._targets = event._targets; + } + if (info.targetDelay === false) { + event.targetDelay = false; + } + next.target = targets[num]; + for (var i in event.customArgs.default) next[i] = event.customArgs.default[i]; + if (next.target && event.customArgs[next.target.playerid]) { + var customArgs = event.customArgs[next.target.playerid]; + for (var i in customArgs) next[i] = customArgs[i]; + } + if (next.target && event.directHit.includes(next.target)) next.directHit = true; + if (next.target && !info.multitarget) { + if (num == 0 && targets.length > 1) { + // var ttt=next.target; + // setTimeout(function(){ttt.addTempClass('target');},0.5*lib.config.duration); + } + else { + next.target.addTempClass('target'); + } + } + if (!info.nodelay && num > 0) { + if (event.targetDelay !== false) { + game.delayx(0.5); + } + } + "step 12"; + if (event.all_excluded) return; + if (!get.info(event.card, false).multitarget && num < targets.length - 1 && !event.cancelled) { + event.num++; + event.goto(11); + } + "step 13"; + if (event.all_excluded) return; + if (get.info(card, false).contentAfter) { + var next = game.createEvent(card.name + 'ContentAfter'); + next.setContent(get.info(card, false).contentAfter); + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.preResult = event.preResult; + next.type = 'postcard'; + if (event.forceDie) next.forceDie = true; + } + "step 14"; + if (event.all_excluded) return; + if (event.effectedCount < event.effectCount) { + if (document.getElementsByClassName('thrown').length) { + if (event.delayx !== false && get.info(event.card, false).finalDelay !== false) game.delayx(); + } + event.goto(10); + } + "step 15"; + if (event.postAi) { + event.player.logAi(event.targets, event.card); + } + if (event._result) { + event.result = event._result; + } + //delete player.using; + if (document.getElementsByClassName('thrown').length) { + if (event.delayx !== false && get.info(event.card, false).finalDelay !== false) game.delayx(); + } + else { + event.finish(); + } + "step 16"; + event._oncancel(); + }, + useSkill: function () { + "step 0"; + var info = get.info(event.skill); + if (!info.noForceDie) event.forceDie = true; + if (!info.noForceOut) event.includeOut = true; + event._skill = event.skill; + game.trySkillAudio(event.skill, player); + var checkShow = player.checkShow(event.skill); + if (info.discard != false && info.lose != false && !info.viewAs) { + player.discard(cards).delay = false; + if (lib.config.low_performance) { + event.discardTransition = true; + } + } + else { + if (info.lose != false) { + if (info.losetrigger == false) { + var losecard = player.lose(cards, ui.special)._triggered = null; + } + else { + var losecard = player.lose(cards, ui.special); + if (info.visible) losecard.visible = true; + if (info.loseTo) losecard.position = ui[info.loseTo]; + if (info.insert) losecard.insert_card = true; + if (losecard.position == ui.special && info.toStorage) losecard.toStorage = true; + } + } + if (!info.prepare && info.viewAs) { + player.$throw(cards); + if (losecard) losecard.visible = true; + if (lib.config.sync_speed && cards[0] && cards[0].clone) { + var waitingForTransition = get.time(); + event.waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete event.waitingForTransition; + }); + } + } + } + if (info.line != false && targets.length) { + var config = {}; + if (get.is.object(info.line)) config = info.line; + else if (info.line == 'fire') { + config.color = 'fire'; + } + else if (info.line == 'thunder') { + config.color = 'thunder'; + } + else if (info.line === undefined || info.line == 'green') { + config.color = 'green'; + } + if (info.multitarget && !info.multiline && targets.length > 1) { + player.line2(targets, config); + } + else { + player.line(targets, config); + } + } + var str = ''; + if (targets && targets.length && info.log != 'notarget') { + str += '对' + (targets[0] == player ? '自己' : get.translation(targets[0])); + for (var i = 1; i < targets.length; i++) { + str += '、' + (targets[i] == player ? '自己' : get.translation(targets[i])); + } + str += ''; + } + str += '发动了'; + if (!info.direct && info.log !== false) { + game.log(player, str, '【' + get.skillTranslation(skill, player) + '】'); + if (info.logv !== false) game.logv(player, skill, targets); + player.trySkillAnimate(skill, skill, checkShow); + } + if (event.addCount != false) { + if (player.stat[player.stat.length - 1].skill[skill] == undefined) { + player.stat[player.stat.length - 1].skill[skill] = 1; + } + else { + player.stat[player.stat.length - 1].skill[skill]++; + } + var sourceSkill = get.info(skill).sourceSkill; + if (sourceSkill) { + if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { + player.stat[player.stat.length - 1].skill[sourceSkill] = 1; + } + else { + player.stat[player.stat.length - 1].skill[sourceSkill]++; + } + } + } + if (player.stat[player.stat.length - 1].allSkills == undefined) { + player.stat[player.stat.length - 1].allSkills = 1; + } + else { + player.stat[player.stat.length - 1].allSkills++; + } + if (info.prepare) { + switch (info.prepare) { + case 'give': if (losecard) losecard.visible = true; player.$give(cards, targets[0]); break; + case 'give2': player.$give(cards.length, targets[0]); break; + case 'throw': if (losecard) losecard.visible = true; player.$throw(cards); break; + case 'throw2': player.$throw(cards.length); break; + default: info.prepare(cards, player, targets); + } + } + if (info.round) { + var roundname = skill + '_roundcount'; + player.storage[roundname] = game.roundNumber; + player.syncStorage(roundname); + player.markSkill(roundname); + } + var name = event.skill; + var players = player.getSkills(false, false, false); + var equips = player.getSkills('e'); + var global = lib.skill.global.slice(0); + var logInfo = { + skill: name, + targets: targets, + event: _status.event, + }; + if (info.sourceSkill) { + logInfo.sourceSkill = info.sourceSkill; + if (global.includes(info.sourceSkill)) { + logInfo.type = 'global'; + } + else if (players.includes(info.sourceSkill)) { + logInfo.type = 'player'; + } + else if (equips.includes(info.sourceSkill)) { + logInfo.type = 'equip'; + } + } + else { + if (global.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = 'global'; + } + else if (players.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = 'player'; + } + else if (equips.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = 'equip'; + } + else { + var bool = false; + for (var i of players) { + var expand = [i]; + game.expandSkills(expand); + if (expand.includes(name)) { + bool = true; + logInfo.sourceSkill = i; + logInfo.type = 'player'; + break; + } + } + if (!bool) { + for (var i of players) { + var expand = [i]; + game.expandSkills(expand); + if (expand.includes(name)) { + logInfo.sourceSkill = i; + logInfo.type = 'equip'; + break; + } + } + } + } + } + event.sourceSkill = logInfo.sourceSkill; + event.type = logInfo.type; + player.getHistory('useSkill').push(logInfo); + event.trigger('useSkill'); + "step 1"; + var info = get.info(event.skill); + if (info && info.contentBefore) { + var next = game.createEvent(event.skill + 'ContentBefore'); + next.setContent(info.contentBefore); + next.targets = targets; + next.cards = cards; + next.player = player; + if (event.forceDie) next.forceDie = true; + if (event.includeOut) next.includeOut = true; + } + "step 2"; + if (!event.skill) { + console.log('error: no skill', get.translation(event.player), event.player.getSkills()); + if (event._skill) { + event.skill = event._skill; + console.log(event._skill); + } + else { + event.finish(); + return; + } + } + var info = get.info(event.skill); + if (targets[num] && targets[num].isDead() || + targets[num] && targets[num].isOut() || + targets[num] && targets[num].removed) { + if (!info.multitarget && num < targets.length - 1) { + event.num++; + event.redo(); + } + return; + } + var next = game.createEvent(event.skill); + next.setContent(info.content); + next.targets = targets; + next.cards = cards; + next.player = player; + next.num = num; + next.multitarget = info.multitarget; + if (num == 0 && next.targets.length > 1) { + if (!info.multitarget) { + lib.tempSortSeat = player; + targets.sort(lib.sort.seat); + delete lib.tempSortSeat; + } + for (var i = 0; i < targets.length; i++) { + targets[i].addTempClass('target'); + } + } + next.target = targets[num]; + if (event.forceDie) next.forceDie = true; + if (event.includeOut) next.includeOut = true; + if (next.target && !info.multitarget) { + if (num == 0 && targets.length > 1) { + // var ttt=next.target; + // setTimeout(function(){ttt.addTempClass('target');},0.5*lib.config.duration); + } + else { + next.target.addTempClass('target'); + } + } + if (num == 0) { + if (typeof info.delay == 'number') game.delay(info.delay); + else if (info.delay !== false && info.delay !== 0) { + if (event.waitingForTransition) { + _status.waitingForTransition = event.waitingForTransition; + game.pause(); + } + else { + game.delayx(); + } + } + } + else game.delayx(0.5); + if (!info.multitarget && num < targets.length - 1) { + event.num++; + event.redo(); + } + "step 3"; + var info = get.info(event.skill); + if (info && info.contentAfter) { + var next = game.createEvent(event.skill + 'ContentAfter'); + next.setContent(info.contentAfter); + next.targets = targets; + next.cards = cards; + next.player = player; + if (event.forceDie) next.forceDie = true; + if (event.includeOut) next.includeOut = true; + } + "step 4"; + if (player.getStat().allSkills > 200) { + player._noSkill = true; + console.log(player.name, event.skill); + } + if (document.getElementsByClassName('thrown').length) { + if (event.skill && get.info(event.skill).delay !== false && get.info(event.skill).delay !== 0) game.delayx(); + } + else { + event.finish(); + } + "step 5"; + ui.clear(); + }, + draw: function() { + // if(lib.config.background_audio){ + // game.playAudio('effect','draw'); + // } + // game.broadcast(function(){ + // if(lib.config.background_audio){ + // game.playAudio('effect','draw'); + // } + // }); + if (typeof event.minnum == 'number' && num < event.minnum) { + num = event.minnum; + } + if (event.drawDeck) { + if (event.drawDeck > num) { + event.drawDeck = num; + } + num -= event.drawDeck; + } + if (event.log != false) { + if (num > 0) { + if (event.bottom) game.log(player, '从牌堆底摸了' + get.cnNumber(num) + '张牌'); + else game.log(player, '摸了' + get.cnNumber(num) + '张牌'); + } + if (event.drawDeck) { + game.log(player, '从牌库中获得了' + get.cnNumber(event.drawDeck) + '张牌'); + } + } + let cards; + if (num > 0) { + if (event.bottom) cards = get.bottomCards(num); + else if (player.getTopCards) cards = player.getTopCards(num); + else cards = get.cards(num); + } + else { + cards = []; + } + if (event.drawDeck) { + cards = cards.concat(player.getDeckCards(event.drawDeck)); + } + let next; + if (event.animate != false) { + if (event.visible) { + next = player.gain(cards, 'gain2'); + if (event.bottom) game.log(player, '从牌堆底摸了' + get.cnNumber(num) + '张牌(', cards, ')'); + else game.log(player, '摸了' + get.cnNumber(num) + '张牌(', cards, ')'); + } + else { + next = player.gain(cards, 'draw'); + } + } + else { + next = player.gain(cards); + if (event.$draw) { + player.$draw(cards.length); + } + } + if (event.gaintag) next.gaintag.addArray(event.gaintag); + event.result = cards; + }, + discard: function () { + "step 0"; + game.log(player, '弃置了', cards); + event.done = player.lose(cards, event.position, 'visible'); + event.done.type = 'discard'; + if (event.discarder) event.done.discarder = event.discarder; + "step 1"; + event.trigger('discard'); + }, + loseToDiscardpile: function () { + "step 0"; + if (event.log != false) game.log(player, '将', cards, '置入了弃牌堆'); + var next = player.lose(cards, event.position); + if (event.insert_index) next.insert_index = event.insert_index; + if (event.insert_card) next.insert_card = true; + if (!event.blank) next.visible = true; + next.type = 'loseToDiscardpile'; + event.done = next; + "step 1"; + event.trigger('loseToDiscardpile'); + }, + respond: function () { + 'step 0'; + var cardaudio = true; + if (event.skill) { + if (lib.skill[event.skill].audio) { + cardaudio = false; + } + player.logSkill(event.skill); + player.checkShow(event.skill, true); + if (lib.skill[event.skill].onrespond && !game.online) { + lib.skill[event.skill].onrespond(event, player); + } + } + else if (!event.nopopup) player.tryCardAnimate(card, card.name, 'wood'); + if (cardaudio && event.getParent(3).name == 'useCard') game.broadcastAll((player, card) => { + game.playCardAudio(card, player); + /* + if(!lib.config.background_audio) return; + const sex=player.sex=='female'?'female':'male',audio=lib.card[card.name].audio; + if(typeof audio=='string'){ + const audioInfo=audio.split(':'); + if(audio.startsWith('db:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,audioInfo[2],`${card.name}_${sex}.${audioInfo[3]||'mp3'}`); + else if(audio.startsWith('ext:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${card.name}_${sex}.${audioInfo[2]||'mp3'}`); + else game.playAudio('card',sex,`${audioInfo[0]}.${audioInfo[1]||'mp3'}`); + } + else game.playAudio('card',sex,card.name);*/ + }, player, card); + if (event.skill) { + if (player.stat[player.stat.length - 1].skill[event.skill] == undefined) { + player.stat[player.stat.length - 1].skill[event.skill] = 1; + } + else { + player.stat[player.stat.length - 1].skill[event.skill]++; + } + var sourceSkill = get.info(event.skill).sourceSkill; + if (sourceSkill) { + if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { + player.stat[player.stat.length - 1].skill[sourceSkill] = 1; + } + else { + player.stat[player.stat.length - 1].skill[sourceSkill]++; + } + } + } + if (cards.length && (cards.length > 1 || cards[0].name != card.name)) { + game.log(player, '打出了', card, '(', cards, ')'); + } + else { + game.log(player, '打出了', card); + } + player.actionHistory[player.actionHistory.length - 1].respond.push(event); + if (cards.length) { + var owner = (get.owner(cards[0]) || player); + var next = owner.lose(cards, 'visible', ui.ordering).set('type', 'use'); + var directDiscard = []; + for (var i = 0; i < cards.length; i++) { + if (!next.cards.includes(cards[i])) { + directDiscard.push(cards[i]); + } + } + if (directDiscard.length) game.cardsGotoOrdering(directDiscard); + } + if (event.animate != false && event.throw !== false) { + for (var i = 0; i < cards.length; i++) { + player.$throw(cards[i]); + if (event.highlight) { + cards[i].clone.classList.add('thrownhighlight'); + game.addVideo('highlightnode', player, get.cardInfo(cards[i])); + } + } + if (event.highlight) { + game.broadcast(function (cards) { + for (var i = 0; i < cards.length; i++) { + if (cards[i].clone) { + cards[i].clone.classList.add('thrownhighlight'); + } + } + }, cards); + } + } + event.trigger('respond'); + 'step 1'; + game.delayx(0.5); + }, + swapHandcards: function () { + 'step 0'; + event.cards1 = event.cards1 || player.getCards('h'); + event.cards2 = event.cards2 || target.getCards('h'); + game.loseAsync({ + player: player, + target: target, + cards1: event.cards1, + cards2: event.cards2, + }).setContent('swapHandcardsx'); + 'step 1'; + game.loseAsync({ + gain_list: [ + [player, event.cards2.filterInD()], + [target, event.cards1.filterInD()] + ], + }).setContent('gaincardMultiple'); + 'step 2'; + game.delayx(); + }, + swapHandcardsx: function () { + 'step 0'; + player.$giveAuto(event.cards1, target); + target.$giveAuto(event.cards2, player); + 'step 1'; + event.cards = event.cards1; + var next = player.lose(event.cards, ui.ordering); + next.getlx = false; + next.relatedEvent = event.getParent(); + if (player == game.me) { + event.delayed = true; + } + else { + next.delay = false; + } + 'step 2'; + event.cards = event.cards2; + var next = target.lose(event.cards, ui.ordering); + next.getlx = false; + next.relatedEvent = event.getParent(); + if (target == game.me) { + event.delayed = true; + } + else { + next.delay = false; + } + 'step 3'; + if (!event.delayed) game.delay(); + }, + gainMultiple: function () { + 'step 0'; + event.delayed = false; + event.num = 0; + event.cards = []; + 'step 1'; + player.gainPlayerCard(targets[num], event.position, true).set('boolline', false).set('delay', num == targets.length - 1); + 'step 2'; + if (result.bool) { + event.cards.addArray(result.cards); + if (num == targets.length - 1) event.delayed = true; + } + event.num++; + if (event.num < targets.length) { + event.goto(1); + } + 'step 3'; + if (!event.delayed) game.delay(); + }, + gain: function () { + "step 0"; + if (event.animate == 'give') event.visible = true; + if (cards) { + var map = {}; + for (var i of cards) { + var owner = get.owner(i, 'judge'); + if (owner && (owner != player || get.position(i) != 'h')) { + var id = owner.playerid; + if (!map[id]) map[id] = [[], [], []]; + map[id][0].push(i); + var position = get.position(i); + if (position == 'h') map[id][1].push(i); + else map[id][2].push(i); + } + else if (!event.updatePile && get.position(i) == 'c') event.updatePile = true; + } + event.losing_map = map; + for (var i in map) { + var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + var next = owner.lose(map[i][0], ui.special).set('type', 'gain').set('forceDie', true).set('getlx', false); + if (event.visible == true) { + next.visible = true; + } + event.relatedLose = next; + } + } + else { + event.finish(); + } + "step 1"; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed('handcard', player, event)) { + cards[i].selfDestroy(event); + cards.splice(i--, 1); + } + else if (event.losing_map) { + for (var id in event.losing_map) { + if (event.losing_map[id][0].includes(cards[i])) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; + var hs = source.getCards('hejsx'); + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } else { + cards[i].addKnower(event.visible ? 'everyone' : source); + } + } + } + } + } + if (cards.length == 0) { + event.finish(); + return; + } + player.getHistory('gain').push(event); + //if(event.source&&event.delay!==false) game.delayx(); + "step 2"; + if (player.getStat().gain == undefined) { + player.getStat().gain = cards.length; + } + else { + player.getStat().gain += cards.length; + } + "step 3"; + var sort; + var frag1 = document.createDocumentFragment(); + var frag2 = document.createDocumentFragment(); + var hs = player.getCards('hs'); + for (var i = 0; i < cards.length; i++) { + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + for (var num = 0; num < cards.length; num++) { + sort = lib.config.sort_card(cards[num]); + if (lib.config.reverse_sort) sort = -sort; + if (['o', 'd'].includes(get.position(cards[num], true))) { + cards[num].addKnower('everyone'); + } + cards[num].fix(); + cards[num].style.transform = ''; + cards[num].addGaintag(event.gaintag); + if (event.knowers) { + cards[num].addKnower(event.knowers);//添加事件设定的知情者。 + } + if (_status.discarded) { + _status.discarded.remove(cards[num]); + } + // cards[num].vanishtag.length=0; + for (var num2 = 0; num2 < cards[num].vanishtag.length; num2++) { + if (cards[num].vanishtag[num2][0] != '_') { + cards[num].vanishtag.splice(num2--, 1); + } + } + if (player == game.me) { + cards[num].classList.add('drawinghidden'); + } + if (get.is.singleHandcard() || sort > 1) frag1.appendChild(cards[num]); + else frag2.appendChild(cards[num]); + } + var addv = function () { + if (player == game.me) { + game.addVideo('gain12', player, [get.cardsInfo(frag1.childNodes), get.cardsInfo(frag2.childNodes), event.gaintag]); + } + }; + var broadcast = function () { + game.broadcast(function (player, cards, num, gaintag) { + player.directgain(cards, null, gaintag); + _status.cardPileNum = num; + }, player, cards, ui.cardPile.childNodes.length, event.gaintag); + }; + if (event.animate == 'draw') { + player.$draw(cards.length); + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(500, 500)); + } + else if (event.animate == 'gain') { + player.$gain(cards, event.log); + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(700, 700)); + } + else if (event.animate == 'gain2' || event.animate == 'draw2') { + var gain2t = 300; + if (player.$gain2(cards, event.log) && player == game.me) { + gain2t = 500; + } + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(gain2t, gain2t)); + } + else if (event.animate == 'give' || event.animate == 'giveAuto') { + var evtmap = event.losing_map; + if (event.animate == 'give') { + for (var i in evtmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + source.$give(evtmap[i][0], player, event.log); + } + } + else { + for (var i in evtmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + if (evtmap[i][1].length) source.$giveAuto(evtmap[i][1], player, event.log); + if (evtmap[i][2].length) source.$give(evtmap[i][2], player, event.log); + } + } + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(500, 500)); + } + else if (typeof event.animate == 'function') { + var time = event.animate(event); + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(time, time)); + } + else { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + event.finish(); + } + "step 4"; + game.delayx(); + if (event.updatePile) game.updateRoundNumber(); + }, + addToExpansion: function () { + "step 0"; + if (event.animate == 'give') event.visible = true; + if (cards) { + var map = {}; + for (var i of cards) { + var owner = get.owner(i, 'judge'); + if (owner && (owner != player || get.position(i) != 'x')) { + var id = owner.playerid; + if (!map[id]) map[id] = [[], [], []]; + map[id][0].push(i); + var position = get.position(i); + if (position == 'h') map[id][1].push(i); + else map[id][2].push(i); + } + else if (!event.updatePile && get.position(i) == 'c') event.updatePile = true; + } + event.losing_map = map; + for (var i in map) { + var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + var next = owner.lose(map[i][0], ui.special).set('type', 'loseToExpansion').set('forceDie', true).set('getlx', false); + if (event.visible == true) next.visible = true; + event.relatedLose = next; + } + } + else { + event.finish(); + } + "step 1"; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed('expansion', player, event)) { + cards[i].selfDestroy(event); + cards.splice(i--, 1); + } + else if (event.losing_map) { + for (var id in event.losing_map) { + if (event.losing_map[id][0].includes(cards[i])) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; + var hs = source.getCards('hejsx'); + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + } + } + } + if (cards.length == 0) { + event.finish(); + return; + } + "step 2"; + var hs = player.getCards('x'); + for (var i = 0; i < cards.length; i++) { + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + for (var num = 0; num < cards.length; num++) { + if (_status.discarded) { + _status.discarded.remove(cards[num]); + } + for (var num2 = 0; num2 < cards[num].vanishtag.length; num2++) { + if (cards[num].vanishtag[num2][0] != '_') { + cards[num].vanishtag.splice(num2--, 1); + } + } + } + if (event.animate == 'draw') { + player.$draw(cards.length); + if (event.log) game.log(player, '将', get.cnNumber(cards.length), '张牌置于了武将牌上'); + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(500, 500)); + } + else if (event.animate == 'gain') { + player.$gain(cards, false); + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(700, 700)); + } + else if (event.animate == 'gain2' || event.animate == 'draw2') { + var gain2t = 300; + if (player.$gain2(cards) && player == game.me) { + gain2t = 500; + } + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(gain2t, gain2t)); + } + else if (event.animate == 'give' || event.animate == 'giveAuto') { + var evtmap = event.losing_map; + if (event.animate == 'give') { + for (var i in evtmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + source.$give(evtmap[i][0], player, false); + if (event.log) game.log(player, '将', evtmap[i][0], '置于了武将牌上'); + } + } + else { + for (var i in evtmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + if (evtmap[i][1].length) { + source.$giveAuto(evtmap[i][1], player, false); + if (event.log) game.log(player, '将', get.cnNumber(evtmap[i][1].length), '张牌置于了武将牌上'); + } + if (evtmap[i][2].length) { + source.$give(evtmap[i][2], player, false); + if (event.log) game.log(player, '将', evtmap[i][2], '置于了武将牌上'); + } + } + } + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(500, 500)); + } + else if (typeof event.animate == 'function') { + var time = event.animate(event); + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(time, time)); + } + else { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + event.finish(); + } + "step 4"; + game.delayx(); + if (event.updatePile) game.updateRoundNumber(); + }, + lose: function () { + "step 0"; + var evt = event.getParent(); + if ((evt.name != 'discard' || event.type != 'discard') && (evt.name != 'loseToDiscardpile' || event.type != 'loseToDiscardpile')) { + event.delay = false; + return; + } + if (evt.delay === false) event.delay = false; + if (evt.animate != false) { + evt.discardid = lib.status.videoId++; + game.broadcastAll(function (player, cards, id, visible) { + player.$throw(cards, null, 'nobroadcast'); + var cardnodes = []; + cardnodes._discardtime = get.time(); + for (var i = 0; i < cards.length; i++) { + if (cards[i].clone) { + cardnodes.push(cards[i].clone); + if (!visible) { + cards[i].clone.classList.add('infohidden'); + cards[i].clone.classList.add('infoflip'); + } + } + } + ui.todiscard[id] = cardnodes; + }, player, cards, evt.discardid, event.visible); + if (lib.config.sync_speed && cards[0] && cards[0].clone) { + if (evt.delay != false) { + var waitingForTransition = get.time(); + evt.waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete evt.waitingForTransition; + }); + } + else if (evt.getParent().discardTransition) { + delete evt.getParent().discardTransition; + var waitingForTransition = get.time(); + evt.getParent().waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete evt.getParent().waitingForTransition; + }); + } + } + } + "step 1"; + event.gaintag_map = {}; + var hs = [], es = [], js = [], ss = [], xs = []; + var unmarks = []; + if (event.insert_card && event.position == ui.cardPile) event.cards.reverse(); + var hej = player.getCards('hejsx'); + event.stockcards = cards.slice(0); + for (var i = 0; i < cards.length; i++) { + if (!hej.includes(cards[i])) { + cards.splice(i--, 1); + continue; + } + else if (cards[i].parentNode) { + if (cards[i].parentNode.classList.contains('equips')) { + cards[i].original = 'e'; + es.push(cards[i]); + } + else if (cards[i].parentNode.classList.contains('judges')) { + cards[i].original = 'j'; + js.push(cards[i]); + } + else if (cards[i].parentNode.classList.contains('expansions')) { + cards[i].original = 'x'; + xs.push(cards[i]); + if (cards[i].gaintag && cards[i].gaintag.length) unmarks.addArray(cards[i].gaintag); + } + else if (cards[i].parentNode.classList.contains('handcards')) { + if (cards[i].classList.contains('glows')) { + cards[i].original = 's'; + ss.push(cards[i]); + } + else { + cards[i].original = 'h'; + hs.push(cards[i]); + } + } + else { + cards[i].original = null; + } + } + if (cards[i].gaintag && cards[i].gaintag.length) { + event.gaintag_map[cards[i].cardid] = cards[i].gaintag.slice(0); + cards[i].removeGaintag(true); + } + + cards[i].style.transform += ' scale(0.2)'; + cards[i].classList.remove('glow'); + cards[i].classList.remove('glows'); + cards[i].recheck(); + + var info = lib.card[cards[i].name]; + if ('_destroy' in cards[i]) { + if (cards[i]._destroy) { + cards[i].delete(); + cards[i].destroyed = cards[i]._destroy; + continue; + } + } + else if ('destroyed' in cards[i]) { + if (event.getlx !== false && event.position && cards[i].willBeDestroyed(event.position.id, null, event)) { + cards[i].selfDestroy(event); + continue; + } + } + else if (info.destroy) { + cards[i].delete(); + cards[i].destroyed = info.destroy; + continue; + } + if (event.position) { + if (_status.discarded) { + if (event.position == ui.discardPile) { + _status.discarded.add(cards[i]); + } + else { + _status.discarded.remove(cards[i]); + } + } + if (event.insert_index) { + cards[i].fix(); + event.position.insertBefore(cards[i], event.insert_index(event, cards[i])); + } + else if (event.insert_card) { + cards[i].fix(); + event.position.insertBefore(cards[i], event.position.firstChild); + } + else if (event.position == ui.cardPile) { + cards[i].fix(); + event.position.appendChild(cards[i]); + } + else cards[i].goto(event.position); + } + else { + cards[i].remove(); + } + //if(ss.includes(cards[i])) cards.splice(i--,1); + } + if (player == game.me) ui.updatehl(); + ui.updatej(player); + game.broadcast(function (player, cards, num) { + for (var i = 0; i < cards.length; i++) { + cards[i].classList.remove('glow'); + cards[i].classList.remove('glows'); + cards[i].fix(); + cards[i].remove(); + } + if (player == game.me) { + ui.updatehl(); + } + ui.updatej(player); + _status.cardPileNum = num; + }, player, cards, ui.cardPile.childNodes.length); + game.addVideo('lose', player, [get.cardsInfo(hs), get.cardsInfo(es), get.cardsInfo(js), get.cardsInfo(ss)]); + event.cards2 = hs.concat(es); + player.getHistory('lose').push(event); + game.getGlobalHistory().cardMove.push(event); + player.update(); + game.addVideo('loseAfter', player); + event.num = 0; + if (event.position == ui.ordering) { + var evt = event.relatedEvent || event.getParent(); + if (!evt.orderingCards) evt.orderingCards = []; + if (!evt.noOrdering && !evt.cardsOrdered) { + evt.cardsOrdered = true; + var next = game.createEvent('orderingDiscard', false, evt.getParent()); + next.relatedEvent = evt; + next.setContent('orderingDiscard'); + } + if (!evt.noOrdering) { + evt.orderingCards.addArray(cards); + } + } + else if (event.position == ui.cardPile) { + game.updateRoundNumber(); + } + if (unmarks.length) { + for (var i of unmarks) { + player[(lib.skill[i] && lib.skill[i].mark || player.hasCard((card) => card.hasGaintag(i), 'x')) ? 'markSkill' : 'unmarkSkill'](i); + } + } + event.hs = hs; + event.es = es; + event.js = js; + event.ss = ss; + event.xs = xs; + game.clearCardKnowers(hs); + if (hs.length && !event.visible) { + player.getCards('h').forEach(hcard => { hcard.clearKnowers(); }); + } + "step 2"; + if (num < cards.length) { + if (event.es.includes(cards[num])) { + event.loseEquip = true; + player.removeEquipTrigger(cards[num]); + var info = get.info(cards[num]); + if (info.onLose && (!info.filterLose || info.filterLose(cards[num], player))) { + event.goto(3); + return; + } + } + event.num++; + event.redo(); + } + else { + if (event.loseEquip) { + player.addEquipTrigger(); + } + event.goto(4); + } + "step 3"; + var info = get.info(cards[num]); + if (info.loseDelay != false && (player.isAlive() || info.forceDie)) { + player.popup(cards[num].name); + game.delayx(); + } + if (Array.isArray(info.onLose)) { + for (var i = 0; i < info.onLose.length; i++) { + var next = game.createEvent('lose_' + cards[num].name); + next.setContent(info.onLose[i]); + if (info.forceDie) next.forceDie = true; + next.player = player; + next.card = cards[num]; + } + } + else { + var next = game.createEvent('lose_' + cards[num].name); + next.setContent(info.onLose); + next.player = player; + if (info.forceDie) next.forceDie = true; + next.card = cards[num]; + } + event.num++; + event.goto(2); + "step 4"; + if (event.toRenku) { + _status.renku.addArray(cards.filter(function (card) { + return !card.willBeDestroyed('renku', null, event); + })); + if (_status.renku.length > 6) { + var cards = _status.renku.splice(0, _status.renku.length - 6); + game.log(cards, '从仁库进入了弃牌堆'); + game.cardsDiscard(cards).set('outRange', true).fromRenku = true; + } + game.updateRenku(); + } + "step 5"; + var evt = event.getParent(); + if ((evt.name != 'discard' && event.type != 'discard') && (evt.name != 'loseToDiscardpile' && event.type != 'loseToDiscardpile')) return; + if (event.animate === false || event.delay === false) return; + if (evt.delay != false) { + if (evt.waitingForTransition) { + _status.waitingForTransition = evt.waitingForTransition; + game.pause(); + } + else { + game.delayx(); + } + } + }, + damage: function () { + "step 0"; + event.forceDie = true; + if (event.unreal) { event.goto(4); return; } + event.trigger('damageBegin1'); + "step 1"; + event.trigger('damageBegin2'); + "step 2"; + event.trigger('damageBegin3'); + "step 3"; + event.trigger('damageBegin4'); + "step 4"; + //moved changeHujia to changeHp + if (player.hujia > 0 && !player.hasSkillTag('nohujia')) { + var damageAudioInfo = lib.natureAudio.hujia_damage[event.nature]; + if (!damageAudioInfo || damageAudioInfo == 'normal') { + damageAudioInfo = 'effect/hujia_damage' + (num > 1 ? '2' : '') + '.mp3'; + } else if (damageAudioInfo == 'default') { + damageAudioInfo = 'effect/hujia_damage_' + event.nature + (num > 1 ? '2' : '') + '.mp3'; + } else { + damageAudioInfo = damageAudioInfo[num > 1 ? 2 : 1]; + } + game.broadcastAll(function (damageAudioInfo) { + if (lib.config.background_audio) game.playAudio(damageAudioInfo); + }, damageAudioInfo); + } else { + var damageAudioInfo = lib.natureAudio.damage[event.nature]; + if (!damageAudioInfo || damageAudioInfo == 'normal') { + damageAudioInfo = 'effect/damage' + (num > 1 ? '2' : '') + '.mp3'; + } else if (damageAudioInfo == 'default') { + damageAudioInfo = 'effect/damage_' + event.nature + (num > 1 ? '2' : '') + '.mp3'; + } else { + damageAudioInfo = damageAudioInfo[num > 1 ? 2 : 1]; + } + game.broadcastAll(function (damageAudioInfo) { + if (lib.config.background_audio) game.playAudio(damageAudioInfo); + }, damageAudioInfo); + } + var str = event.unreal ? '视为受到了' : '受到了'; + if (source) str += '来自' + (source == player ? '自己' : get.translation(source)) + '的'; + str += get.cnNumber(num) + '点'; + if (event.nature) str += get.translation(event.nature) + '属性'; + str += '伤害'; + game.log(player, str); + if (player.stat[player.stat.length - 1].damaged == undefined) { + player.stat[player.stat.length - 1].damaged = num; + } + else { + player.stat[player.stat.length - 1].damaged += num; + } + if (source) { + source.getHistory('sourceDamage').push(event); + if (source.stat[source.stat.length - 1].damage == undefined) { + source.stat[source.stat.length - 1].damage = num; + } + else { + source.stat[source.stat.length - 1].damage += num; + } + } + player.getHistory('damage').push(event); + if (!event.unreal) { + if (event.notrigger) { + player.changeHp(-num, false)._triggered = null; + } + else { + player.changeHp(-num, false); + } + } + if (event.animate !== false) { + player.$damage(source); + var natures = (event.nature || '').split(lib.natureSeparator); + game.broadcastAll(function (natures, player) { + if (lib.config.animation && !lib.config.low_performance) { + if (natures.includes('fire')) { + player.$fire(); + } + if (natures.includes('thunder')) { + player.$thunder(); + } + } + }, natures, player); + var numx = player.hasSkillTag('nohujia') ? num : Math.max(0, num - player.hujia); + player.$damagepop(-numx, natures[0]); + } + if (event.unreal) event.goto(6); + if (!event.notrigger) { + if (num == 0) { + event.trigger('damageZero'); + event._triggered = null; + } + else { + event.trigger('damage'); + } + } + "step 5"; + if (player.hp <= 0 && player.isAlive() && !event.nodying) { + game.delayx(); + event._dyinged = true; + player.dying(event); + } + if (source && lib.config.border_style == 'auto') { + var dnum = 0; + for (var j = 0; j < source.stat.length; j++) { + if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; + } + if (dnum >= 2) { + if (lib.config.autoborder_start == 'silver') { + dnum += 4; + } + else if (lib.config.autoborder_start == 'gold') { + dnum += 8; + } + } + if (lib.config.autoborder_count == 'damage') { + source.node.framebg.dataset.decoration = ''; + if (dnum >= 10) { + source.node.framebg.dataset.auto = 'gold'; + if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; + } + else if (dnum >= 6) { + source.node.framebg.dataset.auto = 'silver'; + if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; + } + else if (dnum >= 2) { + source.node.framebg.dataset.auto = 'bronze'; + if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; + } + if (dnum >= 2) { + source.classList.add('topcount'); + } + } + else if (lib.config.autoborder_count == 'mix') { + source.node.framebg.dataset.decoration = ''; + switch (source.node.framebg.dataset.auto) { + case 'bronze': if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; break; + case 'silver': if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; break; + case 'gold': if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; break; + } + } + } + "step 6"; + if (!event.notrigger) event.trigger('damageSource'); + }, + recover: function () { + if (lib.config.background_audio) { + game.playAudio('effect', 'recover'); + } + game.broadcast(function () { + if (lib.config.background_audio) { + game.playAudio('effect', 'recover'); + } + }); + if (num > player.maxHp - player.hp) { + num = player.maxHp - player.hp; + event.num = num; + } + if (num > 0) { + player.changeHp(num, false); + game.broadcastAll(function (player) { + if (lib.config.animation && !lib.config.low_performance) { + player.$recover(); + } + }, player); + player.$damagepop(num, 'wood'); + game.log(player, '回复了' + get.cnNumber(num) + '点体力'); + } + }, + loseHp: function () { + "step 0"; + if (lib.config.background_audio) { + game.playAudio('effect', 'loseHp'); + } + game.broadcast(function () { + if (lib.config.background_audio) { + game.playAudio('effect', 'loseHp'); + } + }); + game.log(player, '失去了' + get.cnNumber(num) + '点体力'); + player.changeHp(-num); + "step 1"; + if (player.hp <= 0 && !event.nodying) { + game.delayx(); + event._dyinged = true; + player.dying(event); + } + }, + doubleDraw: function () { + "step 0"; + player.chooseBool('你的主副将体力上限之和是奇数,是否摸一张牌?'); + "step 1"; + if (result.bool) { + player.draw(); + } + }, + loseMaxHp: function () { + "step 0"; + game.log(player, '减少了' + get.cnNumber(num) + '点体力上限'); + player.maxHp -= num; + event.loseHp = Math.max(0, player.hp - player.maxHp); + player.update(); + "step 1"; + if (player.maxHp <= 0) { + player.die(event); + } + }, + gainMaxHp: function () { + "step 0"; + game.log(player, '增加了' + get.cnNumber(num) + '点体力上限'); + player.maxHp += num; + player.update(); + }, + changeHp: function () { + //add to GlobalHistory + game.getGlobalHistory().changeHp.push(event); + //changeHujia moved here + if (num < 0 && player.hujia > 0 && event.getParent().name == 'damage' && !player.hasSkillTag('nohujia')) { + event.hujia = Math.min(-num, player.hujia); + event.getParent().hujia = event.hujia; + event.num += event.hujia; + //log moved to changeHujia + //game.log(player,'的护甲抵挡了'+get.cnNumber(event.hujia)+'点伤害'); + player.changeHujia(-event.hujia).type = 'damage'; + } + //old part + num = event.num; + player.hp += num; + if (isNaN(player.hp)) player.hp = 0; + if (player.hp > player.maxHp) player.hp = player.maxHp; + player.update(); + if (event.popup !== false) { + player.$damagepop(num, 'water'); + } + if (_status.dying.includes(player) && player.hp > 0) { + _status.dying.remove(player); + game.broadcast(function (list) { + _status.dying = list; + }, _status.dying); + var evt = event.getParent('_save'); + if (evt && evt.finish) evt.finish(); + evt = event.getParent('dying'); + if (evt && evt.finish) evt.finish(); + } + event.trigger('changeHp'); + }, + changeHujia: function () { + if (num > 0) { + game.log(player, '获得了' + get.cnNumber(num) + '点护甲'); + } + else if (num < 0) { + if (-num > player.hujia) { + num = -player.hujia; + event.num = num; + } + switch (event.type) { //log moved here + case 'damage': + game.log(player, '的护甲抵挡了' + get.cnNumber(-num) + '点伤害'); + break; + case 'lose': + game.log(player, '失去了' + get.cnNumber(-num) + '点护甲'); + break; + } + } + player.hujia += num; + //if(player.hujia<0){ + // player.hujia=0; + //} + player.update(); + }, + dying: function () { + "step 0"; + event.forceDie = true; + if (player.isDying() || player.hp > 0) { + event.finish(); + return; + } + _status.dying.unshift(player); + game.broadcast(function (list) { + _status.dying = list; + }, _status.dying); + event.trigger('dying'); + game.log(player, '濒死'); + "step 1"; + delete event.filterStop; + if (player.hp > 0 || event.nodying) { + _status.dying.remove(player); + game.broadcast(function (list) { + _status.dying = list; + }, _status.dying); + event.finish(); + } + else if (!event.skipTao) { + var next = game.createEvent('_save'); + var start = false; + var starts = [_status.currentPhase, event.source, event.player, game.me, game.players[0]]; + for (var i = 0; i < starts.length; i++) { + if (get.itemtype(starts[i]) == 'player') { + start = starts[i]; break; + } + } + next.player = start; + next._trigger = event; + next.triggername = '_save'; + next.forceDie = true; + next.setContent(lib.skill._save.content); + } + "step 2"; + _status.dying.remove(player); + game.broadcast(function (list) { + _status.dying = list; + }, _status.dying); + if (player.hp <= 0 && !event.nodying && !player.nodying) player.die(event.reason); + }, + die: function () { + "step 0"; + event.forceDie = true; + if (_status.roundStart == player) { + _status.roundStart = player.next || player.getNext() || game.players[0]; + } + if (ui.land && ui.land.player == player) { + game.addVideo('destroyLand'); + ui.land.destroy(); + } + var unseen = false; + if (player.classList.contains('unseen')) { + player.classList.remove('unseen'); + unseen = true; + } + var logvid = game.logv(player, 'die', source); + event.logvid = logvid; + if (unseen) { + player.classList.add('unseen'); + } + if (source) { + game.log(player, '被', source, '杀害'); + if (source.stat[source.stat.length - 1].kill == undefined) { + source.stat[source.stat.length - 1].kill = 1; + } + else { + source.stat[source.stat.length - 1].kill++; + } + } + else { + game.log(player, '阵亡'); + } + + + // player.removeEquipTrigger(); + + // for(var i in lib.skill.globalmap){ + // if(lib.skill.globalmap[i].includes(player)){ + // lib.skill.globalmap[i].remove(player); + // if(lib.skill.globalmap[i].length==0&&!lib.skill[i].globalFixed){ + // game.removeGlobalSkill(i); + // } + // } + // } + game.broadcastAll(function (player) { + player.classList.add('dead'); + player.removeLink(); + player.classList.remove('turnedover'); + player.classList.remove('out'); + player.node.count.innerHTML = '0'; + player.node.hp.hide(); + player.node.equips.hide(); + player.node.count.hide(); + player.previous.next = player.next; + player.next.previous = player.previous; + game.players.remove(player); + game.dead.push(player); + _status.dying.remove(player); + + if (lib.config.background_speak) { + if (lib.character[player.name] && lib.character[player.name][4].some(tag => /^die:.+$/.test(tag))) { + var tag = lib.character[player.name][4].find(tag => /^die:.+$/.test(tag)); + var reg = new RegExp("^ext:(.+)?/"); + var match = tag.match(/^die:(.+)$/); + if (match) { + var path = match[1]; + if (reg.test(path)) path = path.replace(reg, (_o, p) => `../extension/${p}/`); + game.playAudio(path); + } + } + else if (lib.character[player.name] && lib.character[player.name][4].some(tag => tag.startsWith('die_audio'))) { + var tag = lib.character[player.name][4].find(tag => tag.startsWith('die_audio')); + var list = tag.split(':').slice(1); + game.playAudio('die', list.length ? list[0] : player.name); + } + else { + game.playAudio('die', player.name, function () { + game.playAudio('die', player.name.slice(player.name.indexOf('_') + 1)); + }); + } + } + }, player); + + game.addVideo('diex', player); + if (event.animate !== false) { + player.$die(source); + } + if (player.hp != 0) { + player.changeHp(0 - player.hp, false).forceDie = true; + } + "step 1"; + if (player.dieAfter) player.dieAfter(source); + "step 2"; + event.trigger('die'); + "step 3"; + if (player.isDead()) { + if (!game.reserveDead) { + for (var mark in player.marks) { + player.unmarkSkill(mark); + } + while (player.node.marks.childNodes.length > 1) { + player.node.marks.lastChild.remove(); + } + game.broadcast(function (player) { + while (player.node.marks.childNodes.length > 1) { + player.node.marks.lastChild.remove(); + } + }, player); + } + for (var i in player.tempSkills) { + player.removeSkill(i); + } + var skills = player.getSkills(); + for (var i = 0; i < skills.length; i++) { + if (lib.skill[skills[i]].temp) { + player.removeSkill(skills[i]); + } + } + if (_status.characterlist) { + if (lib.character[player.name] && !player.name.startsWith('gz_shibing') && !player.name.startsWith('gz_jun_')) _status.characterlist.add(player.name); + if (lib.character[player.name1] && !player.name1.startsWith('gz_shibing') && !player.name1.startsWith('gz_jun_')) _status.characterlist.add(player.name1); + if (lib.character[player.name2] && !player.name2.startsWith('gz_shibing') && !player.name2.startsWith('gz_jun_')) _status.characterlist.add(player.name2); + } + event.cards = player.getCards('hejsx'); + if (event.cards.length) { + player.discard(event.cards).forceDie = true; + //player.$throw(event.cards,1000); + } + } + "step 4"; + if (player.dieAfter2) player.dieAfter2(source); + "step 5"; + game.broadcastAll(function (player) { + if (game.online && player == game.me && !_status.over && !game.controlOver && !ui.exit) { + if (lib.mode[lib.configOL.mode].config.dierestart) { + ui.create.exit(); + } + } + }, player); + if (!_status.connectMode && player == game.me && !_status.over && !game.controlOver) { + ui.control.show(); + if (get.config('revive') && lib.mode[lib.config.mode].config.revive && !ui.revive) { + ui.revive = ui.create.control('revive', ui.click.dierevive); + } + if (get.config('continue_game') && !ui.continue_game && lib.mode[lib.config.mode].config.continue_game && !_status.brawl && !game.no_continue_game) { + ui.continue_game = ui.create.control('再战', game.reloadCurrent); + } + if (get.config('dierestart') && lib.mode[lib.config.mode].config.dierestart && !ui.restart) { + ui.restart = ui.create.control('restart', game.reload); + } + } + + if (!_status.connectMode && player == game.me && !game.modeSwapPlayer) { + // _status.auto=false; + if (ui.auto) { + // ui.auto.classList.remove('glow'); + ui.auto.hide(); + } + if (ui.wuxie) ui.wuxie.hide(); + } + + if (typeof _status.coin == 'number' && source && !_status.auto) { + if (source == game.me || source.isUnderControl()) { + _status.coin += 10; + } + } + if (source && lib.config.border_style == 'auto' && (lib.config.autoborder_count == 'kill' || lib.config.autoborder_count == 'mix')) { + switch (source.node.framebg.dataset.auto) { + case 'gold': case 'silver': source.node.framebg.dataset.auto = 'gold'; break; + case 'bronze': source.node.framebg.dataset.auto = 'silver'; break; + default: source.node.framebg.dataset.auto = lib.config.autoborder_start || 'bronze'; + } + if (lib.config.autoborder_count == 'kill') { + source.node.framebg.dataset.decoration = source.node.framebg.dataset.auto; + } + else { + var dnum = 0; + for (var j = 0; j < source.stat.length; j++) { + if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; + } + source.node.framebg.dataset.decoration = ''; + switch (source.node.framebg.dataset.auto) { + case 'bronze': if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; break; + case 'silver': if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; break; + case 'gold': if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; break; + } + } + source.classList.add('topcount'); + } + }, + addJudge: function () { + "step 0"; + if (cards) { + var owner = get.owner(cards[0]); + if (owner) { + event.relatedLose = owner.lose(cards, 'visible', ui.special).set('getlx', false); + } + else if (get.position(cards[0]) == 'c') event.updatePile = true; + } + "step 1"; + if (cards[0].willBeDestroyed('judge', player, event)) { + cards[0].selfDestroy(event); + event.finish(); + return; + } + else if (event.relatedLose) { + var owner = event.relatedLose.player; + if (owner.getCards('hejsx').includes(card)) { + event.finish(); + return; + } + } + cards[0].fix(); + cards[0].style.transform = ''; + cards[0].classList.remove('drawinghidden'); + delete cards[0]._transform; + var viewAs = typeof card == 'string' ? card : card.name; + if (!lib.card[viewAs] || !lib.card[viewAs].effect) { + game.cardsDiscard(cards[0]); + } + else { + cards[0].style.transform = ''; + cards[0].classList.add('drawinghidden'); + player.node.judges.insertBefore(cards[0], player.node.judges.firstChild); + if (_status.discarded) { + _status.discarded.remove(cards[0]); + } + ui.updatej(player); + game.broadcast(function (player, card, viewAs) { + card.fix(); + card.style.transform = ''; + card.classList.add('drawinghidden'); + card.viewAs = viewAs; + if (viewAs && viewAs != card.name && (card.classList.contains('fullskin') || card.classList.contains('fullborder'))) { + card.classList.add('fakejudge'); + card.node.background.innerHTML = lib.translate[viewAs + '_bg'] || get.translation(viewAs)[0]; + } + else { + card.classList.remove('fakejudge'); + } + player.node.judges.insertBefore(card, player.node.judges.firstChild); + ui.updatej(player); + if (card.clone && (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena)) { + card.clone.moveDelete(player); + game.addVideo('gain2', player, get.cardsInfo([card])); + } + }, player, cards[0], viewAs); + if (cards[0].clone && (cards[0].clone.parentNode == player.parentNode || cards[0].clone.parentNode == ui.arena)) { + cards[0].clone.moveDelete(player); + game.addVideo('gain2', player, get.cardsInfo(cards)); + } + // player.$gain2(cards); + if (get.itemtype(card) != 'card') { + if (typeof card == 'string') cards[0].viewAs = card; + else cards[0].viewAs = card.name; + } + else { + delete cards[0].viewAs; + } + if (cards[0].viewAs && cards[0].viewAs != cards[0].name) { + if (cards[0].classList.contains('fullskin') || cards[0].classList.contains('fullborder')) { + cards[0].classList.add('fakejudge'); + cards[0].node.background.innerHTML = lib.translate[cards[0].viewAs + '_bg'] || get.translation(cards[0].viewAs)[0]; + } + game.log(player, '被贴上了' + get.translation(cards[0].viewAs) + '(', cards, ')'); + } + else { + cards[0].classList.remove('fakejudge'); + game.log(player, '被贴上了', cards); + } + game.addVideo('addJudge', player, [get.cardInfo(cards[0]), cards[0].viewAs]); + } + if (event.updatePile) game.updateRoundNumber(); + }, + judge: function () { + "step 0"; + var judgestr = get.translation(player) + '的' + event.judgestr + '判定'; + event.videoId = lib.status.videoId++; + var cardj = event.directresult; + if (!cardj) { + if (player.getTopCards) cardj = player.getTopCards()[0]; + else cardj = get.cards()[0]; + } + var owner = get.owner(cardj); + if (owner) { + owner.lose(cardj, 'visible', ui.ordering); + } + else { + var nextj = game.cardsGotoOrdering(cardj); + if (event.position != ui.discardPile) nextj.noOrdering = true; + } + player.judging.unshift(cardj); + game.addVideo('judge1', player, [get.cardInfo(player.judging[0]), judgestr, event.videoId]); + game.broadcastAll(function (player, card, str, id, cardid) { + var event; + if (game.online) { + event = {}; + } + else { + event = _status.event; + } + if (game.chess) { + event.node = card.copy('thrown', 'center', ui.arena).addTempClass('start'); + } + else { + event.node = player.$throwordered(card.copy(), true); + } + if (lib.cardOL) lib.cardOL[cardid] = event.node; + event.node.cardid = cardid; + event.node.classList.add('thrownhighlight'); + ui.arena.classList.add('thrownhighlight'); + event.dialog = ui.create.dialog(str); + event.dialog.classList.add('center'); + event.dialog.videoId = id; + }, player, player.judging[0], judgestr, event.videoId, get.id()); + + game.log(player, '进行' + event.judgestr + '判定,亮出的判定牌为', player.judging[0]); + game.delay(2); + if (!event.noJudgeTrigger) event.trigger('judge'); + "step 1"; + event.result = { + card: player.judging[0], + name: player.judging[0].name, + number: get.number(player.judging[0]), + suit: get.suit(player.judging[0]), + color: get.color(player.judging[0]), + node: event.node, + }; + if (event.fixedResult) { + for (var i in event.fixedResult) { + event.result[i] = event.fixedResult[i]; + } + } + event.result.judge = event.judge(event.result); + if (event.result.judge > 0) event.result.bool = true; + else if (event.result.judge < 0) event.result.bool = false; + else event.result.bool = null; + player.judging.shift(); + game.checkMod(player, event.result, 'judge', player); + if (event.judge2) { + var judge2 = event.judge2(event.result); + if (typeof judge2 == 'boolean') player.tryJudgeAnimate(judge2); + } + if (event.clearArena != false) { + game.broadcastAll(ui.clear); + } + game.broadcast(function (id) { + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + ui.arena.classList.remove('thrownhighlight'); + }, event.videoId); + event.dialog.close(); + game.addVideo('judge2', null, event.videoId); + ui.arena.classList.remove('thrownhighlight'); + game.log(player, '的判定结果为', event.result.card); + event.trigger('judgeFixing'); + if (event.callback) { + var next = game.createEvent('judgeCallback', false); + next.player = player; + next.card = event.result.card; + next.judgeResult = get.copy(event.result); + next.setContent(event.callback); + } + else { + if (!get.owner(event.result.card)) { + if (event.position != ui.discardPile) event.position.appendChild(event.result.card); + } + } + }, + turnOver: function () { + game.log(player, '翻面'); + player.classList.toggle('turnedover'); + game.broadcast(function (player) { + player.classList.toggle('turnedover'); + }, player); + game.addVideo('turnOver', player, player.classList.contains('turnedover')); + }, + link: function () { + if (player.isLinked()) { + game.log(player, '解除连环'); + } + else { + game.log(player, '被连环'); + } + if (lib.config.background_audio) { + game.playAudio('effect', 'link'); + } + game.broadcast(function () { + if (lib.config.background_audio) { + game.playAudio('effect', 'link'); + } + }); + player.classList.remove('target'); + if (get.is.linked2(player)) { + player.classList.toggle('linked2'); + } + else { + player.classList.toggle('linked'); + } + ui.updatej(player); + ui.updatem(player); + game.broadcast(function (player, linked) { + player.classList.remove('target'); + if (get.is.linked2(player)) { + if (linked) { + player.classList.add('linked2'); + } + else { + player.classList.remove('linked2'); + } + } + else { + if (linked) { + player.classList.add('linked'); + } + else { + player.classList.remove('linked'); + } + } + ui.updatej(player); + ui.updatem(player); + }, player, player.isLinked()); + game.addVideo('link', player, player.isLinked()); + }, + /** + * @deprecated + */ + chooseToGuanxing: function () { + "step 0"; + var cards = get.cards(num); + game.cardsGotoOrdering(cards); + var next = player.chooseToMove(); + next.set('list', [ + ['牌堆顶', cards], + ['牌堆底'], + ]); + next.set('prompt', '点击将牌移动到牌堆顶或牌堆底'); + next.processAI = event.processAI || function (list) { + var cards = list[0][1], player = _status.event.player; + var top = []; + var bottom; + cards.sort(function (a, b) { + return get.value(b, player) - get.value(a, player); + }); + while (cards.length) { + if (get.value(cards[0], player) <= 5) break; + top.unshift(cards.shift()); + } + bottom = cards; + return [top, bottom]; + }; + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; + top.reverse(); + for (var i = 0; i < top.length; i++) { + ui.cardPile.insertBefore(top[i], ui.cardPile.firstChild); + } + for (i = 0; i < bottom.length; i++) { + ui.cardPile.appendChild(bottom[i]); + } + game.addCardKnower(top, player); + game.addCardKnower(bottom, player); + player.popup(get.cnNumber(top.length) + '上' + get.cnNumber(bottom.length) + '下'); + game.log(player, '将' + get.cnNumber(top.length) + '张牌置于牌堆顶'); + game.updateRoundNumber(); + game.delayx(); + } +} diff --git a/noname/library/experimental/index.js b/noname/library/experimental/index.js index a83285f23..b68624008 100644 --- a/noname/library/experimental/index.js +++ b/noname/library/experimental/index.js @@ -1,5 +1,8 @@ -import { Uninstantable } from "../../util/index.js"; - -export class Experimental extends Uninstantable { - -} +import { Uninstantable } from "../../util/index.js"; + +import { ExperimentalSymbol } from "./symbol.js"; + +export class Experimental extends Uninstantable { + static symbol = ExperimentalSymbol + static symbols = ExperimentalSymbol +} diff --git a/noname/library/experimental/symbol.js b/noname/library/experimental/symbol.js new file mode 100644 index 000000000..d73532822 --- /dev/null +++ b/noname/library/experimental/symbol.js @@ -0,0 +1,5 @@ +import { Uninstantable } from "../../util/index.js"; + +export class ExperimentalSymbol extends Uninstantable { + static itemType = Symbol('noname.experimental.itemType') +} diff --git a/noname/ui/index.js b/noname/ui/index.js index 09d8173d6..16d72c58b 100644 --- a/noname/ui/index.js +++ b/noname/ui/index.js @@ -1,14655 +1,14655 @@ -import { Uninstantable } from "../util/index.js"; -import { Library as lib } from '../library/index.js'; -import { Game as game } from "../game/index.js"; -import { Get as get } from "../get/index.js"; -import { _status } from "../status/index.js"; -import { GNC as gnc } from '../gnc/index.js'; -import { AI as ai } from "../ai/index.js"; - -class Create extends Uninstantable { - /** - * 创建身份牌实例 - */ - static identityCard(identity, position, noclick) { - const card = ui.create.card(position, 'noclick', noclick); - card.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.card); - card.classList.add('button'); - card._customintro = uiintro => uiintro.add(`${get.translation(`${identity}${2}`)}的身份牌`); - const fileName = `image/card/identity_${identity}.jpg`; - new Promise((resolve, reject) => { - const image = new Image(); - image.onload = resolve; - image.onerror = reject; - image.src = `${lib.assetURL}${fileName}`; - }).then(() => { - card.classList.add('fullskin'); - card.node.image.setBackgroundImage(fileName); - }, () => card.node.background.innerHTML = get.translation(identity)[0]); - return card; - } - /** - * 让卡牌旋转 - */ - static cardSpinning(card) { - if (lib.config.cardback_style != 'default') { - card.style.transitionProperty = 'none'; - ui.refresh(card); - card.classList.add('infohidden'); - ui.refresh(card); - card.style.transitionProperty = ''; - } - else { - card.classList.add('infohidden'); - } - card.style.transition = 'all 0s'; - card.style.transform = 'perspective(600px) rotateY(180deg) translateX(0)'; - const onEnd01 = function () { - setTimeout(function () { - card.style.transition = 'all ease-in 0.3s'; - card.style.transform = 'perspective(600px) rotateY(270deg) translateX(52px)'; - var onEnd = function () { - card.classList.remove('infohidden'); - card.style.transition = 'all 0s'; - ui.refresh(card); - card.style.transform = 'perspective(600px) rotateY(-90deg) translateX(52px)'; - ui.refresh(card); - card.style.transition = ''; - ui.refresh(card); - card.style.transform = ''; - } - card.listenTransition(onEnd); - }, 300); - }; - onEnd01(); - } - /** - * 旋转的身份牌! - */ - static spinningIdentityCard(identity, dialog) { - const card = ui.create.identityCard(identity); - const buttons = ui.create.div('.buttons', dialog.content); - setTimeout(() => { - buttons.appendChild(card); - dialog.open(); - ui.create.cardSpinning(card); - }, 50); - } - /** - * 创建codemirror编辑器 - * @param {HTMLDivElement} container - * @param {Function} saveInput - */ - static editor(container, saveInput) { - const createList = []; - const containerDelete = container.delete; - const editorpage = ui.create.div(container); - //删除container的时候,删除创建的ul列表 - container.delete = function () { - for (let i = createList.length - 1; i >= 0; i--) { - createList[i].parentNode && createList[i].parentNode.removeChild(createList[i]); - } - Array.from(editorpage.children).forEach(v => { v.style.background = '' }); - containerDelete.apply(this, arguments); - } - //创建ul列表 - const createMenu = function (pos, self, List, click) { - if (!self || self == window) return; - const parent = self.parentNode; - if (parent) { - for (let i = 0; i < parent.childElementCount; i++) { - const node = parent.childNodes[i]; - if (node != self && node.ul) closeMenu.call(node); - } - } - if (self.ul) { - self.style.background = '#08f'; - createList.add(self.ul); - ui.window.appendChild(self.ul); - return self.ul; - } - const editor = container.editor; - if (!editor) return false; - self.style.background = '#08f'; - const ul = document.createElement('ul'); - container.css.call(ul, { - position: 'absolute', - top: pos.bottom / game.documentZoom + 'px', - left: pos.left / game.documentZoom + 'px', - height: '20em', - width: pos.width * 4 / game.documentZoom + 'px', - //'font-family':'shousha', - 'font-size': (lib.config.codeMirror_fontSize ? lib.config.codeMirror_fontSize.slice(0, -2) : 16) / game.documentZoom + 'px', - - }); - const theme = editor.options.theme; - lib.setScroll(ul); - lib.setMousewheel(ul); - ul.className = "CodeMirror-hints " + theme; - const getActive = () => { - let i = 0; - while (i < ul.childElementCount) { - if (ul.childNodes[i].classList.contains('CodeMirror-hint-active')) break; - else i++; - } - return i; - }; - const setActive = i => { - ul.childNodes[getActive()].classList.remove('CodeMirror-hint-active'); - ul.childNodes[i].classList.add('CodeMirror-hint-active'); - return i; - }; - if (List && List.length && click) { - for (let i = 0; i < List.length; ++i) { - const elt = ul.appendChild(document.createElement("li")); - elt.style.color = 'black'; - elt.style.boxShadow = 'none'; - const cur = List[i]; - if (cur instanceof HTMLElement) { - elt.appendChild(cur); - } else { - elt.innerHTML = cur; - } - let className = "CodeMirror-hint" + (i != 0 ? "" : " " + "CodeMirror-hint-active"); - if (cur.className != null) className = cur.className + " " + className; - elt.className = className; - elt.hintId = i; - ui.window.listen.call(elt, function () { - setActive(this.hintId); - this.focus(); - click.call(this); - }); - elt.onmousemove = elt.ontouchstart = () => { - setActive(i); - }; - } - } - createList.add(ul); - ui.window.appendChild(ul); - return ul; - }; - //关闭ul列表 - const closeMenu = function () { - const ul = this.ul; - if (!ul) return false; - if (ul.parentNode) ul.parentNode.removeChild(ul); - this.style.background = ''; - //创建后不用删除了,除非以后要动态加载。 - //delete this.ul; - createList.remove(ul); - return ul; - }; - const discardConfig = ui.create.div('.editbutton', '取消', editorpage, function () { - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); - container.delete(null); - delete window.saveNonameInput; - }); - const saveConfig = ui.create.div('.editbutton', '保存', editorpage, saveInput); - const theme = ui.create.div('.editbutton', '主题', editorpage, function () { - if (!this || this == window) return; - if (this.ul && this.ul.parentNode) { - return closeMenu.call(this); - } - //this - const self = this; - if (!this.ul) { - //主题列表 - const list = ['mdn-like', 'mbo']; - //正在使用的主题 - const active = container.editor.options.theme; - //排个序 - list.remove(active).splice(0, 0, active); - //元素位置 - const pos = self.getBoundingClientRect(); - //点击事件 - const click = function (e) { - const theme = this.innerHTML; - container.editor.setOption("theme", theme); - setTimeout(() => container.editor.refresh(), 0); - game.saveConfig('codeMirror_theme', theme); - closeMenu.call(self); - }; - const ul = createMenu(pos, self, list, click); - self.ul = ul; - } else { - createMenu(null, self); - } - }); - const edit = ui.create.div('.editbutton', '编辑', editorpage, function () { - if (!this || this == window) return; - if (this.ul && this.ul.parentNode) { - return closeMenu.call(this); - } - const self = this; - if (!this.ul) { - const pos = this.getBoundingClientRect(); - const list = ['撤销 Ctrl+Z', '恢复撤销 Ctrl+Y']; - const click = function (e) { - const num = this.innerHTML.indexOf("Ctrl"); - const inner = this.innerHTML.slice(num).replace("+", "-"); - container.editor.execCommand(container.editor.options.extraKeys[inner]); - setTimeout(() => container.editor.refresh(), 0); - closeMenu.call(self); - }; - const ul = createMenu(pos, self, list, click); - this.ul = ul; - } else { - createMenu(null, self); - } - }); - const fontSize = ui.create.div('.editbutton', '字号', editorpage, function () { - if (!this || this == window) return; - if (this.ul && this.ul.parentNode) { - return closeMenu.call(this); - } - const self = this; - if (!this.ul) { - const pos = this.getBoundingClientRect(); - const list = ['16px', '18px', '20px', '22px', '24px', '26px']; - const click = function (e) { - const size = this.innerHTML; - container.style.fontSize = size.slice(0, -2) / game.documentZoom + 'px'; - Array.from(self.parentElement.children).map(v => v.ul).filter(Boolean).forEach(v => { v.style.fontSize = size.slice(0, -2) / game.documentZoom + 'px' }); - setTimeout(() => container.editor.refresh(), 0); - game.saveConfig('codeMirror_fontSize', size); - closeMenu.call(self); - }; - const ul = createMenu(pos, self, list, click); - this.ul = ul; - } else { - createMenu(null, self); - } - }); - const editor = ui.create.div(editorpage); - return editor; - } - static cardTempName(card, applyNode) { - let getApplyNode = applyNode || card; - let cardName = get.name(card); - let cardNature = get.nature(card); - let tempname = get.translation(cardName); - let cardTempNameConfig = lib.config.cardtempname; - let node = getApplyNode._tempName || ui.create.div('.tempname', getApplyNode); - let datasetNature = ''; - getApplyNode._tempName = node; - if (cardTempNameConfig != 'image') { - //清空,避免和下面的image部分有冲突 - node.innerHTML = ''; - datasetNature = 'fire'; - if (get.position(card) == 'j' && card.viewAs && card.viewAs != card.name) { - datasetNature = 'wood'; - tempname = get.translation(card.viewAs); - } else { - if (cardName == 'sha') { - if (cardNature) tempname = get.translation(cardNature) + tempname; - if (cardNature == 'thunder') datasetNature = 'thunder'; - if (cardNature == 'kami') datasetNature = 'kami'; - if (cardNature == 'ice') datasetNature = 'ice'; - } - } - if (cardTempNameConfig == 'default') getApplyNode._tempName.classList.add('vertical'); - if (datasetNature.length > 0) { - node.dataset.nature = datasetNature; - } else { - delete node.dataset.nature; - node.classList.add(datasetNature); - } - } else { - if (get.position(card) == 'j' && card.viewAs && card.viewAs != card.name) { - cardName = card.viewAs; - tempname = get.translation(card.viewAs); - } - if (cardName == 'sha') { - if (cardNature) tempname = get.translation(cardNature) + tempname; - if (cardNature == 'fire') datasetNature = 'fire'; - if (cardNature == 'thunder') datasetNature = 'thunder'; - if (cardNature == 'kami') datasetNature = 'kami'; - if (cardNature == 'ice') datasetNature = 'ice'; - } - let bg = node.querySelector('div'); - if (bg) { - Array.from(node.childNodes).filter(v => v != bg).forEach(v => node.removeChild(v)); - } - else bg = ui.create.div(node); - node.classList.add('tempimage'); - let img = lib.card[cardName].image; - if (img) { - if (img.startsWith('db:')) { - img = img.slice(3); - } - else if (!img.startsWith('ext:')) { - img = null; - } - } - if (lib.card[cardName].fullskin) { - if (img) { - if (img.startsWith('ext:')) { - bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - } - else { - bg.setBackgroundDB(img); - } - } - else { - if (lib.card[cardName].modeimage) { - bg.setBackgroundImage('image/mode/' + lib.card[cardName].modeimage + '/card/' + cardName + '.png'); - } - else { - if (cardName == 'sha' && cardNature == 'stab') bg.setBackgroundImage('image/card/cisha.png'); - else bg.setBackgroundImage('image/card/' + cardName + '.png'); - } - } - } - else if (lib.card[cardName].image == 'background') { - if (cardNature) bg.setBackground(cardName + '_' + cardNature, 'card'); - else bg.setBackground(cardName, 'card'); - } - else if (lib.card[cardName].fullimage) { - if (img) { - if (img.startsWith('ext:')) { - bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - bg.style.backgroundSize = 'cover'; - } - else { - bg.setBackgroundDB(img); - } - } - else if (lib.card[cardName].image) { - if (lib.card[cardName].image.startsWith('character:')) { - bg.setBackground(lib.card[cardName].image.slice(10), 'character'); - } - else { - bg.setBackground(lib.card[cardName].image); - } - } - else { - let cardPack = lib.cardPack['mode_' + get.mode()]; - if (Array.isArray(cardPack) && cardPack.includes(cardName)) { - bg.setBackground('mode/' + get.mode() + '/card/' + cardName); - } - else { - bg.setBackground('card/' + cardName); - } - } - } - else if (lib.card[cardName].image == 'card') { - if (cardNature) bg.setBackground(cardName + '_' + cardNature, 'card'); - else bg.setBackground(cardName, 'card'); - } - else if (typeof lib.card[cardName].image == 'string' && !lib.card[cardName].fullskin) { - if (img) { - if (img.startsWith('ext:')) { - bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - bg.style.backgroundSize = 'cover'; - } - else { - bg.setBackgroundDB(img); - } - } - else { - bg.setBackground(lib.card[cardName].image); - } - } - else { - console.warn('卡牌图片解析失败'); - } - if (datasetNature.length > 0) { - node.classList.add(datasetNature); - } - delete node.dataset.nature; - } - node.innerHTML += `${cardTempNameConfig == 'default' ? get.verticalStr(tempname) : tempname}`; - node.tempname = tempname; - return node; - } - static connectRooms(list) { - ui.rooms = []; - ui.roombase = ui.create.dialog(); - ui.roombase.classList.add('fullwidth'); - ui.roombase.classList.add('fullheight'); - ui.roombase.classList.add('fixed'); - ui.roombase.classList.add('scroll1'); - ui.roombase.classList.add('scroll2'); - ui.roombase.classList.add('noupdate'); - for (var i = 0; i < list.length; i++) { - var player = ui.roombase.add(''); - player.roomindex = i; - player.initRoom = lib.element.Player.prototype.initRoom; - player.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.connectroom); - player.initRoom(list[i]); - ui.rooms.push(player); - } - } - static rarity(button) { - var rarity = game.getRarity(button.link); - if (rarity != 'common' && lib.config.show_rarity) { - var intro = button.node.intro; - intro.classList.add('showintro'); - intro.style.fontFamily = 'yuanli'; - intro.style.fontSize = '16px'; - intro.style.bottom = '6px'; - intro.style.left = '6px'; - switch (rarity) { - case 'rare': intro.dataset.nature = 'thunderm'; break; - case 'epic': intro.dataset.nature = 'metalm'; break; - case 'legend': intro.dataset.nature = 'orangem'; break; - case 'junk': intro.dataset.nature = 'woodm'; break; - } - intro.innerHTML = get.translation(rarity); - } - /*if((button.link=='xushu'||button.link=='xin_xushu'||button.link=='jsrg_guanyu')&&button.node&&button.node.name&&button.node.group){ - if(button.classList.contains('newstyle')){ - button.node.name.dataset.nature='watermm'; - button.node.group.dataset.nature='water'; - } - else button.node.group.style.backgroundColor=get.translation('weiColor'); - }*/ - } - static div() { - var str, innerHTML, position, position2, style, divposition, listen; - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') { - if (typeof str == 'string') { - innerHTML = arguments[i]; - } - else { - str = arguments[i]; - } - } - else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; - else if (typeof arguments[i] == 'number') position2 = arguments[i]; - else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; - else if (typeof arguments[i] == 'object') style = arguments[i]; - else if (typeof arguments[i] == 'function') listen = arguments[i]; - } - if (str == undefined) str = ''; - var node = document.createElement('div'); - for (var i = 0; i < str.length; i++) { - if (str[i] == '.') { - if (node.className.length != 0) { - node.className += ' '; - } - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { - node.className += str[i + 1]; - i++; - } - } - else if (str[i] == '#') { - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { - node.id += str[i + 1]; - i++; - } - } - } - if (position) { - if (typeof position2 == 'number' && position.childNodes.length > position2) { - position.insertBefore(node, position.childNodes[position2]); - } - else { - position.appendChild(node); - } - } - if (style) node.css(style); - if (divposition) node.setPosition(divposition); - if (innerHTML) node.innerHTML = innerHTML; - if (listen) node.listen(listen); - return node; - } - static filediv() { - var args = Array.from(arguments); - var func = null; - for (var i = 0; i < args.length; i++) { - if (typeof args[i] == 'function') { - func = args[i]; - args.splice(i, 1); - break; - } - } - var div = ui.create.div.apply(this, args); - var input = ui.create.node('input.fileinput'); - input.type = 'file'; - input.onchange = function (e) { - func.call(this, this.files[0], e); - }; - div.appendChild(input); - div.inputNode = input; - return div; - } - static node() { - var tagName, str, innerHTML, position, position2, style, divposition, listen; - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') { - if (typeof tagName == 'string') { - innerHTML = arguments[i]; - } - else { - tagName = arguments[i]; - } - } - else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; - else if (typeof arguments[i] == 'number') position2 = arguments[i]; - else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; - else if (typeof arguments[i] == 'object') style = arguments[i]; - else if (typeof arguments[i] == 'function') listen = arguments[i]; - } - if (tagName == undefined) { - tagName = 'div'; - } - else { - var i1 = tagName.indexOf('.'); - var i2 = tagName.indexOf('#'); - if (i1 != -1 || i2 != -1) { - if (i2 != -1 && i2 < i1) { - i1 = i2; - } - str = tagName.slice(i1); - tagName = tagName.slice(0, i1); - } - } - var node = document.createElement(tagName); - if (str) { - for (var i = 0; i < str.length; i++) { - if (str[i] == '.') { - if (node.className.length != 0) { - node.className += ' '; - } - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { - node.className += str[i + 1]; - i++; - } - } - else if (str[i] == '#') { - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { - node.id += str[i + 1]; - i++; - } - } - } - } - if (position) { - if (typeof position2 == 'number' && position.childNodes.length > position2) { - position.insertBefore(node, position.childNodes[position2]); - } - else { - position.appendChild(node); - } - } - if (style) HTMLDivElement.prototype.css.call(node, style); - if (divposition) HTMLDivElement.prototype.setPosition.call(node, divposition); - if (innerHTML) node.innerHTML = innerHTML; - if (listen) node.onclick = listen; - return node; - } - static iframe(src) { - var layer = document.createElement('div'); - layer.classList.add('poplayer'); - layer.style.zIndex = '100'; - layer.listen(function () { - this.remove(); - }); - layer.style.background = 'white'; - - var webview = document.createElement('iframe'); - webview.src = src; - webview.style.width = '100%'; - webview.style.height = '100%'; - webview.style.left = '0px'; - webview.style.top = '0px'; - webview.style.position = 'absolute'; - webview.style.border = 'none'; - layer.appendChild(webview); - - var backbutton = ui.create.div('.menubutton.round', '返', layer, function () { - layer.remove(); - }); - backbutton.style.bottom = '10px'; - backbutton.style.right = '10px'; - backbutton.style.background = 'rgba(0,0,0,0.4)'; - backbutton.style.color = 'white'; - backbutton.style.textShadow = 'rgba(0,0,0,0.5) 0px 0px 2px'; - backbutton.style.boxShadow = 'rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 3px 10px'; - backbutton.style.position = 'fixed'; - - ui.window.appendChild(layer); - } - static identitycircle(list, target) { - var container = ui.create.div('.identitycircle.menubg', target); - var circle = ui.create.div(container); - container.dataset.num = list.length; - for (var i = 0; i < list.length; i++) { - var sec1 = ui.create.div(circle); - sec1.dataset.color = list[i]; - var sec2 = ui.create.div(circle); - sec2.dataset.color = list[i]; - var deg1 = 360 / list.length * i; - var deg2 = 0; - if (list.length == 2) { - deg2 = 90; - } - else if (list.length == 3) { - deg2 = 30; - } - sec1.style.transform = 'rotate(' + deg1 + 'deg)'; - sec2.style.transform = 'rotate(' + (deg1 + deg2) + 'deg)'; - } - } - static chat() { - var chat = ui.create.system('聊天', null, true); - ui.chatButton = chat; - lib.setPopped(chat, ui.click.chat, 220); - } - static exit() { - if (!ui.exit) { - ui.exit = ui.create.control('退出房间', ui.click.exit); - } - } - static connecting(bool) { - if (bool) { - ui.window.classList.remove('connecting'); - if (ui.connecting) { - ui.connecting.delete(); - delete ui.connecting; - } - } - else { - ui.window.classList.add('connecting'); - ui.connecting = ui.create.div('.fullsize.connectlayer'); - document.body.appendChild(ui.connecting); - ui.create.div('', '正在重连...', ui.connecting); - ui.connecting.splashtimeout = setTimeout(function () { - if (ui.connecting) { - delete ui.connecting.splashtimeout; - } - }, 300); - // setTimeout(function(){ - // if(ui.connecting){ - // ui.connecting.firstChild.show(); - // } - // },1000); - } - } - static roomInfo() { - var chat = ui.create.system(game.online ? '房间信息' : '房间设置', function () { - if (!game.online || game.onlinezhu) { - ui.click.connectMenu(); - } - }, true); - ui.roomInfo = chat; - lib.setPopped(chat, function () { - if (game.getRoomInfo) { - var uiintro = ui.create.dialog('hidden'); - game.getRoomInfo(uiintro); - return uiintro; - } - }, 180); - } - static templayer(time) { - if (typeof time != 'number' || isNaN(time) || time == Infinity) { - time = 500; - } - var templayer = ui.create.div('.popup-container', ui.window); - setTimeout(function () { - templayer.remove(); - }, time); - } - static selectlist(list, init, position, onchange) { - var select = document.createElement('select'); - for (var i = 0; i < list.length; i++) { - var option = document.createElement('option'); - if (Array.isArray(list[i])) { - option.value = list[i][0]; - option.innerHTML = list[i][1]; - } - else { - option.value = list[i]; - option.innerHTML = list[i]; - } - if (init == option.value) { - option.selected = 'selected'; - } - select.appendChild(option); - } - if (position) { - position.appendChild(select); - } - if (onchange) { - select.onchange = onchange; - } - return select; - } - static menu(connectMenu) { - var menuTimeout = null; - if (!connectMenu && !game.syncMenu) { - menuTimeout = setTimeout(lib.init.reset, 1000); - } - var menu, menuContainer; - var startButton; - var popupContainer; - var closeMenu = function () { - if (popupContainer.noclose) { - popupContainer.noclose = false; - return; - } - popupContainer.classList.add('hidden'); - if (popupContainer.onclose) { - popupContainer.onclose(); - } - }; - popupContainer = ui.create.div('.popup-container.hidden', ui.window, closeMenu); - - var openMenu = function (node, e, onclose) { - popupContainer.innerHTML = ''; - var left = Math.round(e.clientX / game.documentZoom); - var zoom = get.is.phoneLayout() ? 1.3 : 1; - popupContainer.appendChild(node); - // var rect=node.getBoundingClientRect(); - if (node.classList.contains('visual')) { - // var num=node.querySelectorAll('.menu.visual>div').length; - // node.style.top=(e.y-node.offsetHeight/2+30)+'px'; - for (var i = 0; i < node.childElementCount; i++) { - if (node.childNodes[i].update) { - node.childNodes[i].update(); - } - } - // if(node.offsetTop<10){ - // node.style.top='10px'; - // } - } - // else if(get.is.phoneLayout()&&rect.top*1.3+rect.height*1.3+20>ui.window.offsetHeight){ - // node.style.top=(ui.winheightdow.offsetHeight-20-rect.height*1.3)/1.3+'px'; - // } - // if(e){ - var height = node.offsetHeight; - var idealtop = e.clientY / game.documentZoom; - if (idealtop < 10) { - idealtop = 10; - } - else if ((idealtop + height) * zoom + 10 > ui.window.offsetHeight) { - idealtop = (ui.window.offsetHeight - 10) / zoom - height; - } - node.style.top = idealtop + 'px'; - node.style.left = left + 'px'; - // } - - popupContainer.classList.remove('hidden'); - popupContainer.onclose = onclose; - }; - var clickToggle = function () { - if (this.classList.contains('disabled')) return; - this.classList.toggle('on'); - var config = this._link.config; - if (config.onclick) { - if (config.onclick.call(this, this.classList.contains('on')) === false) { - this.classList.toggle('on'); - } - } - if (config.update) { - config.update(); - } - }; - var clickSwitcher = function () { - if (this.classList.contains('disabled')) return; - var node = this; - this.classList.add('on'); - if (this._link.menu) { - var pos1 = this.lastChild.getBoundingClientRect(); - var pos2 = ui.window.getBoundingClientRect(); - if (this._link.menu.classList.contains('visual')) { - openMenu(this._link.menu, { - clientX: pos1.left + pos1.width + 5 - pos2.left, - clientY: pos1.top - pos2.top - }, function () { - node.classList.remove('on'); - }); - } - else if (this._link.menu.childElementCount > 10) { - openMenu(this._link.menu, { - clientX: pos1.left + pos1.width + 5 - pos2.left, - clientY: Math.min((ui.window.offsetHeight - 400) / 2, pos1.top - pos2.top) - }, function () { - node.classList.remove('on'); - }); - lib.setScroll(this._link.menu); - } - else { - openMenu(this._link.menu, { - clientX: pos1.left + pos1.width + 5 - pos2.left, - clientY: pos1.top - pos2.top - }, function () { - node.classList.remove('on'); - }); - } - } - }; - var clickContainer = function () { - menuContainer.classList.add('hidden'); - if (connectMenu) { - if (_status.enteringroom) { - _status.enteringroom = false; - } - if (_status.creatingroom) { - _status.creatingroom = false; - } - ui.window.classList.remove('shortcutpaused'); - } - else { - game.resume2(); - if (game.onresume2) { - game.onresume2(); - } - ui.arena.classList.remove('menupaused'); - ui.historybar.classList.remove('menupaused'); - ui.window.classList.remove('touchinfohidden'); - ui.config2.classList.remove('pressdown2'); - } - }; - var clickMenuItem = function () { - var node = this.parentNode._link; - var config = node._link.config; - node._link.current = this.link; - var tmpName = node.lastChild.innerHTML; - node.lastChild.innerHTML = config.item[this._link]; - if (config.onclick) { - if (config.onclick.call(node, this._link, this) === false) { - node.lastChild.innerHTML = tmpName; - } - } - if (config.update) { - config.update(); - } - }; - var createMenu = function (tabs, config) { - var createPage = function (position) { - var node = ui.create.div(position); - lib.setScroll(ui.create.div('.left.pane', node)); - lib.setScroll(ui.create.div('.right.pane', node)); - return node; - }; - var menu = ui.create.div('.main.menu.dialog.popped.static', config.position, function (e) { - e.stopPropagation(); - }); - if (connectMenu) { - menu.classList.add('center'); - menuContainer.classList.add('centermenu'); - } - var menuTab = ui.create.div('.menu-tab', menu); - var menuTabBar = ui.create.div('.menu-tab-bar', menu); - menuTabBar.style.left = (config.bar || 0) + 'px'; - if (Math.round(2 * game.documentZoom) < 2) { - menuTabBar.style.height = '3px'; - } - var menuContent = ui.create.div('.menu-content', menu); - var clickTab = function () { - if (this.classList.contains('disabled')) return; - var active = this.parentNode.querySelector('.active'); - if (active) { - active.classList.remove('active'); - active._link.remove(); - } - this.classList.add('active'); - menuTabBar.style.transform = 'translateX(' + (this.getBoundingClientRect().left - this.parentNode.firstChild.getBoundingClientRect().left) / game.documentZoom + 'px)'; - menuContent.appendChild(this._link); - }; - ui.click.menuTab = function (tab) { - for (var i = 0; i < menuTab.childNodes.length; i++) { - if (menuTab.childNodes[i].innerHTML == tab) { - clickTab.call(menuTab.childNodes[i]); - return; - } - } - }; - var pages = []; - for (var i = 0; i < tabs.length; i++) { - var active = (i === (config.init || 0)); - pages[i] = createPage(active ? menuContent : null); - ui.create.div(active ? '.active' : '', tabs[i], menuTab, clickTab)._link = pages[i]; - } - return { - menu: menu, - pages: pages - }; - }; - var createConfig = function (config, position) { - var node = ui.create.div('.config', config.name); - node._link = { config: config }; - if (!config.clear) { - if (config.name != '开启') { - if (config.name == '屏蔽弱将') { - config.intro = '强度过低的武将(孙策除外)不会出现在选将框,也不会被AI选择' - } - else if (config.name == '屏蔽强将') { - config.intro = '强度过高的武将不会出现在选将框,也不会被AI选择' - } - else if (!config.intro) { - config.intro = '设置' + config.name; - } - lib.setIntro(node, function (uiintro) { - if (lib.config.touchscreen) _status.dragged = true; - uiintro.style.width = '170px'; - var str = config.intro; - if (typeof str == 'function') { - str = str(); - } - uiintro._place_text = uiintro.add('
' + str + '
'); - }); - } - } - else { - node.innerHTML = '' + config.name + ''; - if (!config.nopointer) { - node.classList.add('pointerspan'); - } - } - if (config.item) { - if (typeof config.item == 'function') { - config.item = config.item(); - } - if (Array.isArray(config.init)) { - void 0; - } - else { - node.classList.add('switcher'); - node.listen(clickSwitcher); - node._link.choosing = ui.create.div('', config.item[config.init], node); - node._link.menu = ui.create.div('.menu'); - if (config.visualMenu) { - node._link.menu.classList.add('visual'); - var updateVisual = function () { - config.visualMenu(this, this._link, config.item[this._link], config); - }; - var createNode = function (i, before) { - var visualMenu = ui.create.div(); - if (config.visualBar) { - if (before) { - node._link.menu.insertBefore(visualMenu, before); - } - else { - node._link.menu.insertBefore(visualMenu, node._link.menu.lastChild); - } - } - else { - node._link.menu.appendChild(visualMenu); - } - ui.create.div('.name', get.verticalStr(config.item[i]), visualMenu); - visualMenu._link = i; - if (config.visualMenu(visualMenu, i, config.item[i], config) !== false) { - visualMenu.listen(clickMenuItem); - } - visualMenu.update = updateVisual; - }; - if (config.visualBar) { - var visualBar = ui.create.div(node._link.menu, function () { - this.parentNode.parentNode.noclose = true; - }); - node._link.menu.classList.add('withbar'); - config.visualBar(visualBar, config.item, createNode, node); - visualBar.update = function () { - config.visualBar(visualBar, config.item, createNode, node); - } - } - for (var i in config.item) { - createNode(i); - } - lib.setScroll(node._link.menu); - node._link.menu.updateBr = function () { - var br = Array.from(this.querySelectorAll('.menu.visual>br')); - while (br.length) { - br.shift().remove(); - } - var split = []; - for (var i = 1; i < this.childElementCount; i++) { - if (i % 3 == 0) { - split.push(this.childNodes[i]); - } - } - for (var i = 0; i < split.length; i++) { - this.insertBefore(ui.create.node('br'), split[i]); - } - } - node._link.menu.updateBr(); - } - else { - for (var i in config.item) { - var textMenu = ui.create.div('', config.item[i], node._link.menu, clickMenuItem); - textMenu._link = i; - if (config.textMenu) { - config.textMenu(textMenu, i, config.item[i], config) - } - lib.setScroll(node._link.menu); - } - } - node._link.menu._link = node; - node._link.current = config.init; - } - } - else if (config.range) { - void 0; - } - else if (config.clear) { - if (node.innerHTML.length >= 15) node.style.height = 'auto'; - node.listen(clickToggle); - } - else if (config.input) { - node.classList.add('switcher'); - var input = ui.create.div(node); - if (!config.fixed) { - input.contentEditable = true; - input.style.webkitUserSelect = 'text'; - } - input.style.minWidth = '10px'; - input.style.maxWidth = '60%'; - input.style.overflow = 'hidden'; - input.style.whiteSpace = 'nowrap'; - input.onkeydown = function (e) { - if (e.keyCode == 13) { - e.preventDefault(); - e.stopPropagation(); - input.blur(); - } - }; - if (config.name == '联机昵称') { - input.innerHTML = config.init || '无名玩家'; - input.onblur = function () { - input.innerHTML = input.innerHTML.replace(/
/g, ''); - if (!input.innerHTML || get.is.banWords(input.innerHTML)) { - input.innerHTML = '无名玩家'; - } - input.innerHTML = input.innerHTML.slice(0, 12); - game.saveConfig('connect_nickname', input.innerHTML); - game.saveConfig('connect_nickname', input.innerHTML, 'connect'); - } - } - else if (config.name == '联机大厅') { - input.innerHTML = config.init || lib.hallURL; - input.onblur = function () { - if (!input.innerHTML) { - input.innerHTML = lib.hallURL; - } - input.innerHTML = input.innerHTML.replace(/
/g, ''); - game.saveConfig('hall_ip', input.innerHTML, 'connect'); - } - } - else { - input.innerHTML = config.init; - input.onblur = config.onblur; - } - } - else { - node.classList.add('toggle'); - node.listen(clickToggle); - ui.create.div(ui.create.div(node)); - if (config.init == true) { - node.classList.add('on'); - } - } - if (position) { - position.appendChild(node); - } - return node; - }; - var updateActive, updateActiveCard; - var menuUpdates = []; - menuContainer = ui.create.div('.menu-container.hidden', ui.window, clickContainer); - var menux; - if (!connectMenu) { - ui.menuContainer = menuContainer; - ui.click.configMenu = function () { - ui.click.shortcut(false) - if (menuContainer.classList.contains('hidden')) { - ui.config2.classList.add('pressdown2'); - ui.arena.classList.add('menupaused'); - ui.historybar.classList.add('menupaused'); - ui.window.classList.add('touchinfohidden'); - menuContainer.classList.remove('hidden'); - for (var i = 0; i < menuUpdates.length; i++) { - menuUpdates[i](); - } - } - else { - clickContainer.call(menuContainer); - } - } - menux = createMenu(['开始', '选项', '武将', '卡牌', '扩展', '其它'], { - position: menuContainer, bar: 40 - }); - } - else { - ui.connectMenuContainer = menuContainer; - ui.click.connectMenu = function () { - if (menuContainer.classList.contains('hidden')) { - if (_status.waitingForPlayer) { - startButton.innerHTML = '设'; - var start = menux.pages[0].firstChild; - for (var i = 0; i < start.childNodes.length; i++) { - if (start.childNodes[i].mode != lib.configOL.mode) { - start.childNodes[i].classList.add('unselectable'); - start.childNodes[i].classList.remove('active'); - if (start.childNodes[i].link) start.childNodes[i].link.remove(); - } - else { - start.childNodes[i].classList.add('active'); - if (start.childNodes[i].link) start.nextSibling.appendChild(start.childNodes[i].link); - else console.log(start.nextSibling, start.childNodes[i]); - } - } - } - ui.window.classList.add('shortcutpaused'); - menuContainer.classList.remove('hidden'); - for (var i = 0; i < menuUpdates.length; i++) { - menuUpdates[i](); - } - } - else { - clickContainer.call(menuContainer); - } - } - - menux = createMenu(['模式', '武将', '卡牌'], { - position: menuContainer, bar: 123 - }); - menu = menux.menu; - } - var menuxpages = menux.pages.slice(0); - - var copyObj = get.copy; - - (function () { - var start = menuxpages.shift(); - var rightPane = start.lastChild; - - startButton = ui.create.div('.menubutton.round.highlight', '启', start, function () { - if (this.animating || this.classList.contains('dim')) { - return; - } - var active = this.parentNode.querySelector('.active'); - if (active) { - if (connectMenu) { - if (_status.waitingForPlayer) { - var config = {}; - for (var i in lib.mode[lib.configOL.mode].connect) { - if (i == 'update') continue; - config[i.slice(8)] = get.config(i, lib.configOL.mode); - } - config.zhinang_tricks = lib.config.connect_zhinang_tricks; - if (game.online) { - if (game.onlinezhu) { - game.send('changeRoomConfig', config); - } - } - else { - game.broadcastAll(function (config) { - for (var i in config) { - lib.configOL[i] = config[i]; - } - }, config); - if (lib.configOL.mode == 'identity' && lib.configOL.identity_mode == 'zhong' && game.connectPlayers) { - for (var i = 0; i < game.connectPlayers.length; i++) { - game.connectPlayers[i].classList.remove('unselectable2'); - } - lib.configOL.number = 8; - game.updateWaiting(); - } - if (game.onlineroom) { - game.send('server', 'config', lib.configOL); - } - game.connectPlayers[0].chat('房间设置已更改'); - } - } - else if (_status.enteringroom || _status.creatingroom) { - lib.configOL.mode = active.mode; - if (_status.enteringroomserver) { - game.saveConfig('connect_mode', lib.configOL.mode); - - var config = {}; - for (var i in lib.mode[lib.configOL.mode].connect) { - if (i == 'update') continue; - config[i.slice(8)] = get.config(i, lib.configOL.mode); - } - config.zhinang_tricks = lib.config.connect_zhinang_tricks; - - config.characterPack = lib.connectCharacterPack.slice(0); - config.cardPack = lib.connectCardPack.slice(0); - for (var i = 0; i < lib.config.connect_characters.length; i++) { - config.characterPack.remove(lib.config.connect_characters[i]); - } - for (var i = 0; i < lib.config.connect_cards.length; i++) { - config.cardPack.remove(lib.config.connect_cards[i]); - } - config.banned = lib.config['connect_' + active.mode + '_banned']; - config.bannedcards = lib.config['connect_' + active.mode + '_bannedcards']; - game.send('server', 'create', game.onlineKey, get.connectNickname(), lib.config.connect_avatar, config, active.mode); - } - else { - game.send('server', 'create', game.onlineKey, get.connectNickname(), lib.config.connect_avatar); - } - } - else { - localStorage.setItem(lib.configprefix + 'directstart', true); - game.saveConfig('directstartmode', active.mode); - game.saveConfig('mode', 'connect'); - ui.exitroom = ui.create.system('退出房间', function () { - game.saveConfig('directstartmode'); - game.reload(); - }, true); - game.switchMode(active.mode); - } - clickContainer.call(menuContainer); - } - else { - game.saveConfig('mode', active.mode); - localStorage.setItem(lib.configprefix + 'directstart', true); - game.reload(); - } - } - }); - - var clickMode = function () { - if (this.classList.contains('unselectable')) return; - var active = this.parentNode.querySelector('.active'); - if (active === this) { - return; - } - active.classList.remove('active'); - active.link.remove(); - active = this; - this.classList.add('active'); - if (this.link) rightPane.appendChild(this.link); - else { - this._initLink(); - rightPane.appendChild(this.link); - } - if (connectMenu) { - if (updateActive) updateActive(); - if (updateActiveCard) updateActiveCard(); - } - }; - - var createModeConfig = function (mode, position) { - var info = lib.mode[mode]; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', info.name, position, clickMode); - node.mode = mode; - var connectDisplayMap = { - connect_player_number: null, - connect_versus_mode: null, - } - var updateConnectDisplayMap = function () { - if (_status.waitingForPlayer) { - if (connectDisplayMap.connect_player_number) { - connectDisplayMap.connect_player_number.style.display = 'none'; - } - if (connectDisplayMap.connect_versus_mode) { - connectDisplayMap.connect_versus_mode.style.display = 'none'; - } - } - }; - if (connectMenu) { - menuUpdates.push(updateConnectDisplayMap); - if (mode == lib.config.connect_mode) { - node.classList.add('active'); - } - } - else { - if (mode == lib.config.mode) { - node.classList.add('active'); - } - } - node._initLink = function () { - node.link = page; - //“更多”下的内容 - var map = {}; - var infoconfig = connectMenu ? info.connect : info.config; - if (infoconfig) { - var hiddenNodes = []; - var config = lib.config.mode_config[mode] || {}; - if (connectMenu) { - infoconfig.connect_choose_timeout = { - name: '出牌时限', - init: '30', - item: { - '10': '10秒', - '15': '15秒', - '30': '30秒', - '60': '60秒', - '90': '90秒', - }, - connect: true, - frequent: true - }; - infoconfig.connect_observe = { - name: '允许旁观', - init: true, - connect: true - }; - infoconfig.connect_observe_handcard = { - name: '允许观看手牌', - init: false, - connect: true - }; - infoconfig.connect_mount_combine = { - name: '合并坐骑栏', - init: false, - connect: true - }; - } - for (var j in infoconfig) { - if (j === 'update') { - continue; - } - var cfg = copyObj(infoconfig[j]); - cfg._name = j; - cfg.mode = mode; - if (j in config) { - cfg.init = config[j]; - } - else { - game.saveConfig(j, cfg.init, mode); - } - if (!cfg.onclick) { - cfg.onclick = function (result) { - var cfg = this._link.config; - game.saveConfig(cfg._name, result, mode); - if (cfg.onsave) { - cfg.onsave.call(this, result); - } - if (!_status.connectMode || game.online) { - if (typeof cfg.restart == 'function') { - if (cfg.restart()) { - startButton.classList.add('glowing'); - } - } - else if (cfg.restart) { - startButton.classList.add('glowing'); - } - } - }; - } - if (infoconfig.update) { - cfg.update = function () { - infoconfig.update(config, map); - }; - } - var cfgnode = createConfig(cfg); - map[j] = cfgnode; - if (cfg.frequent) { - page.appendChild(cfgnode); - } - else { - cfgnode.classList.add('auto-hide'); - hiddenNodes.push(cfgnode); - } - } - if (!connectMenu) { - var move = ui.create.div('.auto-hide.config', '
上移↑
下移↓
'); - move.firstChild.listen(function () { - if (node.previousSibling) { - node.parentNode.insertBefore(node, node.previousSibling); - var order = []; - for (var i = 0; i < node.parentNode.childNodes.length; i++) { - order.push(node.parentNode.childNodes[i].mode); - } - game.saveConfig('modeorder', order); - } - }); - move.lastChild.listen(function () { - if (node.nextSibling) { - if (node.nextSibling.nextSibling) { - node.parentNode.insertBefore(node, node.nextSibling.nextSibling); - } - else { - node.parentNode.insertBefore(node.nextSibling, node); - } - var order = []; - for (var i = 0; i < node.parentNode.childNodes.length; i++) { - order.push(node.parentNode.childNodes[i].mode); - } - game.saveConfig('modeorder', order); - } - }); - hiddenNodes.push(move); - } - var expanded = false; - var hasexpand = true; - if (hiddenNodes.length) { - if (lib.config.fold_mode) { - var clickmore = function (type) { - if (type === 'expand' && expanded) return; - if (type === 'unexpand' && !expanded) return; - if (expanded) { - this.classList.remove('on'); - this.parentNode.classList.remove('expanded'); - } - else { - this.classList.add('on'); - this.parentNode.classList.add('expanded'); - } - expanded = !expanded; - }; - var morenodes = ui.create.div('.config.more', '更多
>
', page); - morenodes.listen(clickmore); - morenodes._onclick = clickmore; - page.morenodes = morenodes; - } - else { - page.classList.add('expanded'); - if (!connectMenu) { - page.classList.add('expanded2'); - } - } - for (var k = 0; k < hiddenNodes.length; k++) { - page.appendChild(hiddenNodes[k]); - } - } - else { - hasexpand = false; - } - if (!connectMenu) { - var hidemode = ui.create.div('.config.pointerspan', '隐藏此模式', page, function () { - if (this.firstChild.innerHTML == '隐藏此模式') { - this.firstChild.innerHTML = '此模式将在重启后隐藏'; - lib.config.hiddenModePack.add(mode); - if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); - } - } - else { - this.firstChild.innerHTML = '隐藏此模式'; - lib.config.hiddenModePack.remove(mode); - } - game.saveConfig('hiddenModePack', lib.config.hiddenModePack); - }); - if (hasexpand) { - hidemode.classList.add('auto-hide'); - } - } - if (infoconfig.update) { - infoconfig.update(config, map); - node.update = function () { - infoconfig.update(config, map); - } - } - } - if (connectMenu) { - connectDisplayMap.connect_player_number = map.connect_player_number; - connectDisplayMap.connect_versus_mode = map.connect_versus_mode; - updateConnectDisplayMap(); - } - }; - if (!get.config('menu_loadondemand')) node._initLink(); - return node; - }; - var modeorder = lib.config.modeorder || []; - for (var i in lib.mode) { - modeorder.add(i); - } - for (var i = 0; i < modeorder.length; i++) { - if (connectMenu) { - if (!lib.mode[modeorder[i]].connect) continue; - if (!lib.config['connect_' + modeorder[i] + '_banned']) { - lib.config['connect_' + modeorder[i] + '_banned'] = []; - } - if (!lib.config['connect_' + modeorder[i] + '_bannedcards']) { - lib.config['connect_' + modeorder[i] + '_bannedcards'] = []; - } - } - if (lib.config.all.mode.includes(modeorder[i])) { - createModeConfig(modeorder[i], start.firstChild); - } - } - var active = start.firstChild.querySelector('.active'); - if (!active) { - active = start.firstChild.firstChild; - active.classList.add('active'); - } - if (!active.link) active._initLink(); - rightPane.appendChild(active.link); - if (lib.config.fold_mode) { - rightPane.addEventListener('mousewheel', function (e) { - var morenodes = this.firstChild.morenodes; - if (morenodes) { - if (e.wheelDelta < 0) { - morenodes._onclick.call(morenodes, 'expand'); - } - else if (this.scrollTop == 0) { - morenodes._onclick.call(morenodes, 'unexpand'); - } - } - }, { passive: true }); - } - }()); - - (function () { - if (connectMenu) return; - var start = menuxpages.shift(); - var rightPane = start.lastChild; - - var clickMode = function () { - var active = this.parentNode.querySelector('.active'); - if (active === this) { - return; - } - active.classList.remove('active'); - active.link.remove(); - active = this; - active.classList.add('active'); - if (this.link) rightPane.appendChild(this.link); - else { - this._initLink(); - rightPane.appendChild(this.link); - } - }; - - var clickAutoSkill = function (bool) { - var name = this._link.config._name; - var list = lib.config.autoskilllist; - if (bool) { - list.remove(name); - } - else { - list.add(name); - } - game.saveConfig('autoskilllist', list); - }; - var skilllistexpanded = game.expandSkills(lib.skilllist); - for (var i in lib.skill) { - if (!skilllistexpanded.includes(i)) continue; - if (lib.skill[i].frequent && lib.translate[i]) { - lib.configMenu.skill.config[i] = { - name: lib.translate[i + '_noconf'] || lib.translate[i], - init: true, - type: 'autoskill', - onclick: clickAutoSkill, - intro: lib.translate[i + '_info'] - } - } - } - var clickBanSkill = function (bool) { - var name = this._link.config._name; - var list = lib.config.forbidlist; - if (bool) { - list.remove(name); - } - else { - list.add(name); - } - game.saveConfig('forbidlist', list); - }; - var forbid = lib.config.forbid; - if (!lib.config.forbidlist) { - game.saveConfig('forbidlist', []); - } - for (var i = 0; i < forbid.length; i++) { - var skip = false; - var str = ''; - var str2 = ''; - var str3 = ''; - for (var j = 0; j < forbid[i].length; j++) { - if (!lib.skilllist.includes(forbid[i][j])) { - skip = true; - break; - } - str += get.translation(forbid[i][j]) + '+'; - str2 += forbid[i][j] + '+'; - str3 += get.translation(forbid[i][j]) + ':' + lib.translate[forbid[i][j] + '_info']; - if (j < forbid[i].length - 1) { - str3 += '
'; - } - } - if (skip) continue; - str = str.slice(0, str.length - 1); - str2 = str2.slice(0, str2.length - 1); - - lib.configMenu.skill.config[str2] = { - name: str, - init: true, - type: 'banskill', - onclick: clickBanSkill, - intro: str3 - } - } - - var updateView = null; - var updateAppearence = null; - var createModeConfig = function (mode, position) { - var info = lib.configMenu[mode]; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', info.name, position, clickMode); - node.mode = mode; - // node._initLink=function(){ - node.link = page; - var map = {}; - if (info.config) { - var hiddenNodes = []; - var autoskillNodes = []; - var banskillNodes = []; - var custombanskillNodes = []; - var banskill; - - if (mode == 'skill') { - var autoskillexpanded = false; - var banskillexpanded = false; - ui.create.div('.config.more', '自动发动
>
', page, function () { - if (autoskillexpanded) { - this.classList.remove('on'); - for (var k = 0; k < autoskillNodes.length; k++) { - autoskillNodes[k].style.display = 'none'; - } - } - else { - this.classList.add('on'); - for (var k = 0; k < autoskillNodes.length; k++) { - autoskillNodes[k].style.display = ''; - } - } - autoskillexpanded = !autoskillexpanded; - }); - banskill = ui.create.div('.config.more', '双将禁配
>
', page, function () { - if (banskillexpanded) { - this.classList.remove('on'); - for (var k = 0; k < banskillNodes.length; k++) { - banskillNodes[k].style.display = 'none'; - } - } - else { - this.classList.add('on'); - for (var k = 0; k < banskillNodes.length; k++) { - banskillNodes[k].style.display = ''; - } - } - banskillexpanded = !banskillexpanded; - }); - - var banskilladd = ui.create.div('.config.indent', '添加...', page, function () { - this.nextSibling.classList.toggle('hidden'); - }); - banskilladd.style.display = 'none'; - banskillNodes.push(banskilladd); - - var banskilladdNode = ui.create.div('.config.indent.hidden.banskilladd', page); - banskilladdNode.style.display = 'none'; - banskillNodes.push(banskilladdNode); - - var matchBanSkill = function (skills1, skills2) { - if (skills1.length != skills2.length) return false; - for (var i = 0; i < skills1.length; i++) { - if (!skills2.includes(skills1[i])) return false; - } - return true; - } - var deleteCustomBanSkill = function () { - for (var i = 0; i < lib.config.customforbid.length; i++) { - if (matchBanSkill(lib.config.customforbid[i], this.parentNode.link)) { - lib.config.customforbid.splice(i--, 1); - break; - } - } - game.saveConfig('customforbid', lib.config.customforbid); - this.parentNode.remove(); - } - var createCustomBanSkill = function (skills) { - var node = ui.create.div('.config.indent.toggle'); - node.style.display = 'none'; - node.link = skills; - banskillNodes.push(node); - custombanskillNodes.push(node); - var str = get.translation(skills[0]); - for (var i = 1; i < skills.length; i++) { - str += '+' + get.translation(skills[i]); - } - node.innerHTML = str; - var span = document.createElement('span'); - span.classList.add('cardpiledelete'); - span.innerHTML = '删除'; - span.onclick = deleteCustomBanSkill; - node.appendChild(span); - page.insertBefore(node, banskilladdNode.nextSibling); - return node; - }; - for (var i = 0; i < lib.config.customforbid.length; i++) { - createCustomBanSkill(lib.config.customforbid[i]); - } - (function () { - var list = []; - for (var i in lib.character) { - if (lib.character[i][3].length) - list.push([i, lib.translate[i]]); - } - - list.sort(function (a, b) { - a = a[0]; b = b[0]; - var aa = a, bb = b; - if (aa.includes('_')) { - aa = aa.slice(aa.indexOf('_') + 1); - } - if (bb.includes('_')) { - bb = bb.slice(bb.indexOf('_') + 1); - } - if (aa != bb) { - return aa > bb ? 1 : -1; - } - return a > b ? 1 : -1; - }); - - var list2 = []; - var skills = lib.character[list[0][0]][3]; - for (var i = 0; i < skills.length; i++) { - list2.push([skills[i], lib.translate[skills[i]]]); - } - - var selectname = ui.create.selectlist(list, list[0], banskilladdNode); - selectname.onchange = function () { - var skills = lib.character[this.value][3]; - skillopt.innerHTML = ''; - for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); - option.value = skills[i]; - option.innerHTML = lib.translate[skills[i]]; - skillopt.appendChild(option); - } - }; - selectname.style.maxWidth = '85px'; - var skillopt = ui.create.selectlist(list2, list2[0], banskilladdNode); - - var span = document.createElement('span'); - span.innerHTML = '+'; - banskilladdNode.appendChild(span); - var br = document.createElement('br'); - banskilladdNode.appendChild(br); - - var selectname2 = ui.create.selectlist(list, list[0], banskilladdNode); - selectname2.onchange = function () { - var skills = lib.character[this.value][3]; - skillopt2.innerHTML = ''; - for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); - option.value = skills[i]; - option.innerHTML = lib.translate[skills[i]]; - skillopt2.appendChild(option); - } - }; - selectname2.style.maxWidth = '85px'; - var skillopt2 = ui.create.selectlist(list2, list2[0], banskilladdNode); - var confirmbutton = document.createElement('button'); - confirmbutton.innerHTML = '确定'; - banskilladdNode.appendChild(confirmbutton); - - confirmbutton.onclick = function () { - var skills = [skillopt.value, skillopt2.value]; - if (skills[0] == skills[1]) { - skills.shift(); - } - if (!lib.config.customforbid) return; - for (var i = 0; i < lib.config.customforbid.length; i++) { - if (matchBanSkill(lib.config.customforbid[i], skills)) return; - } - lib.config.customforbid.push(skills); - game.saveConfig('customforbid', lib.config.customforbid); - createCustomBanSkill(skills).style.display = ''; - } - }()); - page.style.paddingBottom = '10px'; - } - var config = lib.config; - if (mode == 'appearence') { - updateAppearence = function () { - info.config.update(config, map); - }; - } - else if (mode == 'view') { - updateView = function () { - info.config.update(config, map); - }; - } - for (var j in info.config) { - if (j === 'update') { - continue; - } - var cfg = copyObj(info.config[j]); - cfg._name = j; - if (j in config) { - cfg.init = config[j]; - } - else if (cfg.type != 'autoskill' && cfg.type != 'banskill') { - game.saveConfig(j, cfg.init); - } - if (!cfg.onclick) { - cfg.onclick = function (result) { - var cfg = this._link.config; - game.saveConfig(cfg._name, result); - if (cfg.onsave) { - cfg.onsave.call(this, result); - } - }; - } - if (info.config.update) { - if (mode == 'appearence' || mode == 'view') { - cfg.update = function () { - if (updateAppearence) { - updateAppearence(); - } - if (updateView) { - updateView(); - } - }; - } - else { - cfg.update = function () { - info.config.update(config, map); - }; - } - } - var cfgnode = createConfig(cfg); - if (cfg.type == 'autoskill') { - autoskillNodes.push(cfgnode); - // cfgnode.style.transition='all 0s'; - cfgnode.classList.add('indent'); - // cfgnode.hide(); - cfgnode.style.display = 'none'; - } - else if (cfg.type == 'banskill') { - banskillNodes.push(cfgnode); - // cfgnode.style.transition='all 0s'; - cfgnode.classList.add('indent'); - // cfgnode.hide(); - cfgnode.style.display = 'none'; - } - if (j == 'import_data_button') { - ui.import_data_button = cfgnode; - cfgnode.hide(); - cfgnode.querySelector('button').onclick = function () { - var fileToLoad = this.previousSibling.files[0]; - if (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { - var data = fileLoadedEvent.target.result; - if (!data) return; - try { - data = JSON.parse(lib.init.decode(data)); - if (!data || typeof data != 'object') { - throw ('err'); - } - if (lib.db && (!data.config || !data.data)) { - throw ('err'); - } - } - catch (e) { - console.log(e); - alert('导入失败'); - return; - } - alert('导入成功'); - if (!lib.db) { - var noname_inited = localStorage.getItem('noname_inited'); - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); - localStorage.clear(); - if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); - } - if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); - } - for (var i in data) { - localStorage.setItem(i, data[i]); - } - } - else { - for (var i in data.config) { - game.putDB('config', i, data.config[i]); - lib.config[i] = data.config[i]; - } - for (var i in data.data) { - game.putDB('data', i, data.data[i]); - } - } - lib.init.background(); - game.reload(); - }; - fileReader.readAsText(fileToLoad, "UTF-8"); - } - } - } - else if (j == 'import_music') { - cfgnode.querySelector('button').onclick = function () { - if (_status.music_importing) return; - _status.music_importing = true; - var fileToLoad = this.previousSibling.files[0]; - if (fileToLoad) { - if (!lib.config.customBackgroundMusic) lib.config.customBackgroundMusic = {}; - var name = fileToLoad.name; - if (name.includes('.')) { - name = name.slice(0, name.indexOf('.')); - } - var link = (game.writeFile ? 'cdv_' : 'custom_') + name; - if (lib.config.customBackgroundMusic[link]) { - if (!confirm('已经存在文件名称相同的背景音乐,是否仍然要继续导入?')) { _status.music_importing = false; return } - for (var i = 1; i < 1000; i++) { - if (!lib.config.customBackgroundMusic[link + '_' + i]) { - link = link + '_' + i; break; - } - } - } - var callback = function () { - var nodexx = ui.background_music_setting; - var nodeyy = nodexx._link.menu; - var nodezz = nodexx._link.config; - var musicname = link.slice(link.indexOf('_') + 1); - game.prompt('###请输入音乐的名称###' + musicname, true, function (str) { - if (str) musicname = str; - lib.config.customBackgroundMusic[link] = musicname; - lib.config.background_music = link; - lib.config.all.background_music.add(link); - game.saveConfig('background_music', link); - game.saveConfig('customBackgroundMusic', lib.config.customBackgroundMusic); - nodezz.item[link] = lib.config.customBackgroundMusic[link]; - var textMenu = ui.create.div('', lib.config.customBackgroundMusic[link], nodeyy, clickMenuItem, nodeyy.childElementCount - 2); - textMenu._link = link; - nodezz.updatex.call(nodexx, []); - _status.music_importing = false; - if (!_status._aozhan) game.playBackgroundMusic(); - }); - }; - if (game.writeFile) { - game.writeFile(fileToLoad, 'audio/background', link + '.mp3', callback); - } - else { - game.putDB('audio', link, fileToLoad, callback); - } - } - } - } - else if (j == 'extension_source') { - ui.extension_source = cfgnode; - cfgnode.updateInner = function () { - this._link.choosing.innerHTML = lib.config.extension_source; - } - } - map[j] = cfgnode; - if (!cfg.unfrequent) { - if (cfg.type == 'autoskill') { - page.insertBefore(cfgnode, banskill); - } - else { - page.appendChild(cfgnode); - } - } - else { - // cfgnode.classList.add('auto-hide'); - hiddenNodes.push(cfgnode); - } - } - var expanded = false; - if (hiddenNodes.length) { - // ui.create.div('.config.more','更多
>
',page,function(){ - // if(expanded){ - // this.classList.remove('on'); - // this.parentNode.classList.remove('expanded'); - // } - // else{ - // this.classList.add('on'); - // this.parentNode.classList.add('expanded'); - // } - // expanded=!expanded; - // }); - page.classList.add('morenodes'); - for (var k = 0; k < hiddenNodes.length; k++) { - page.appendChild(hiddenNodes[k]); - } - } - if (info.config.update) { - info.config.update(config, map); - } - } - // }; - // if(!get.config('menu_loadondemand')) node._initLink(); - return node; - }; - - for (var i in lib.configMenu) { - if (i != 'others') createModeConfig(i, start.firstChild); - } - (function () { - if (!game.download && !lib.device) return; - var page = ui.create.div('#create-extension'); - var node = ui.create.div('.menubutton.large', '文件', start.firstChild, clickMode); - node.mode = 'create'; - node._initLink = function () { - node.link = page; - var pageboard = ui.create.div(page); - - var importextensionexpanded = false; - var importExtension; - var extensionnode = ui.create.div('.config.more', '导入素材包
>
', pageboard, function () { - if (importextensionexpanded) { - this.classList.remove('on'); - importExtension.style.display = 'none'; - } - else { - this.classList.add('on'); - importExtension.style.display = ''; - } - importextensionexpanded = !importextensionexpanded; - }); - extensionnode.style.padding = '13px 33px 4px'; - extensionnode.style.left = '0px'; - importExtension = ui.create.div('.new_character.export.import', pageboard); - importExtension.style.padding = '0px 33px 10px'; - importExtension.style.display = 'none'; - importExtension.style.width = '100%'; - importExtension.style.textAlign = 'left'; - ui.create.div('', '', importExtension); - var promptnode = ui.create.div('', '
', importExtension); - promptnode.style.display = 'none'; - importExtension.firstChild.lastChild.onclick = function () { - if (promptnode.style.display != 'none') return; - var fileToLoad = this.previousSibling.files[0]; - if (fileToLoad) { - promptnode.style.display = ''; - promptnode.firstChild.innerHTML = '正在解压...'; - var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { - var data = fileLoadedEvent.target.result; - var loadData = function () { - var zip = new JSZip(); - zip.load(data); - var images = [], audios = [], fonts = [], directories = {}, directoryList = []; - Object.keys(zip.files).forEach(file => { - const parsedPath = lib.path.parse(file), directory = parsedPath.dir, fileExtension = parsedPath.ext.toLowerCase(); - if (directory.startsWith('audio') && (fileExtension == '.mp3' || fileExtension == '.ogg')) audios.push(file); - else if (directory.startsWith('font') && fileExtension == '.woff2') fonts.push(file); - else if (directory.startsWith('image') && (fileExtension == '.jpg' || fileExtension == '.png')) images.push(file); - else return; - if (!directories[directory]) { - directories[directory] = []; - directoryList.push(directory); - } - directories[directory].push(parsedPath.base); - }); - if (audios.length || fonts.length || images.length) { - var str = ''; - if (audios.length) { - str += audios.length + '个音频文件'; - } - if (fonts.length) { - if (str.length) str += '、' - str += fonts.length + '个字体文件'; - } - if (images.length) { - if (str.length) str += '、' - str += images.length + '个图片文件'; - } - var filelist = audios.concat(fonts).concat(images); - if (filelist.length > 200) { - str += ',导入时间可能较长'; - } - var assetLoaded = function () { - promptnode.firstChild.innerHTML = '导入成功。重新启动×'; - promptnode.firstChild.querySelectorAll('span')[0].onclick = game.reload; - promptnode.firstChild.querySelectorAll('span')[1].onclick = function () { - promptnode.style.display = 'none'; - } - }; - if (confirm('本次将导入' + str + ',是否继续?')) { - promptnode.firstChild.innerHTML = '正在导入... 详细信息'; - promptnode.firstChild.querySelector('span.hrefnode').onclick = ui.click.consoleMenu; - if (lib.node && lib.node.fs) { - var writeFile = function () { - if (filelist.length) { - var str = filelist.shift(); - game.print(str.slice(str.lastIndexOf('/') + 1)); - lib.node.fs.writeFile(__dirname + '/' + str, zip.files[str].asNodeBuffer(), null, writeFile); - } - else { - assetLoaded(); - } - }; - game.ensureDirectory(directoryList, writeFile); - - } - else { - var getDirectory = function () { - if (directoryList.length) { - var dir = directoryList.shift(); - var filelist = directories[dir]; - window.resolveLocalFileSystemURL(lib.assetURL + dir, function (entry) { - var writeFile = function () { - if (filelist.length) { - var filename = filelist.shift(); - game.print(filename); - entry.getFile(filename, { create: true }, function (fileEntry) { - fileEntry.createWriter(function (fileWriter) { - fileWriter.onwriteend = writeFile; - fileWriter.onerror = function (e) { - game.print('Write failed: ' + e.toString()); - }; - fileWriter.write(zip.files[dir + '/' + filename].asArrayBuffer()); - }); - }); - } - else { - getDirectory(); - } - }; - writeFile(); - }); - } - else { - assetLoaded(); - } - }; - game.ensureDirectory(directoryList, getDirectory); - } - } - else { - promptnode.style.display = 'none'; - } - } - else { - alert('没有检测到素材'); - } - } - if (!window.JSZip) { - lib.init.js(lib.assetURL + 'game', 'jszip', loadData); - } - else { - loadData(); - } - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - } - } - - var dashboard = ui.create.div(pageboard); - var clickDash = function () { - ui.create.templayer(); - pageboard.hide(); - this.link.show(); - if (this.link.init) { - this.link.init(); - } - }; - var createDash = function (str1, str2, node) { - var dash = ui.create.div('.menubutton.large.dashboard'); - dashboard.appendChild(dash); - page.appendChild(node); - dash.link = node; - node.link = dash; - dash.listen(clickDash); - lib.setScroll(node); - ui.create.div('', str1, dash); - ui.create.div('', str2, dash); - }; - var createDash2 = function (str1, str2, path, page) { - var dash = ui.create.div('.menubutton.large.dashboard.dashboard2'); - page.appendChild(dash); - dash.listen(function () { - page.path = path; - enterDirectory(page, path); - }); - ui.create.div('', str1, dash); - ui.create.div('', str2, dash); - }; - var removeFile = function (selected, page) { - if (lib.node && lib.node.fs) { - var unlink = function () { - if (selected.length) { - lib.node.fs.unlink(__dirname + '/' + selected.shift().path, unlink); - } - else { - enterDirectory(page, page.currentpath); - } - } - unlink(); - } - else { - window.resolveLocalFileSystemURL(lib.assetURL + page.currentpath, function (entry) { - var unlink = function () { - if (selected.length) { - entry.getFile(selected.shift().filename, { create: false }, function (fileEntry) { - fileEntry.remove(unlink); - }); - } - else { - enterDirectory(page, page.currentpath); - } - } - unlink(); - }); - } - }; - var clickDirectory = function () { - if (_status.dragged) return; - var page = this.parentNode.parentNode.parentNode; - if (page.deletebutton.classList.contains('active')) { - if (confirm('确认删除' + this.innerHTML + '文件夹?(此操作不可撤销)')) { - if (lib.node && lib.node.fs) { - try { - var removeDirectory = function (path, callback) { - lib.node.fs.readdir(__dirname + '/' + path, function (err, list) { - if (err) { - console.log(err); - return; - } - var removeFile = function () { - if (list.length) { - var filename = list.shift(); - var url = __dirname + '/' + path + '/' + filename; - if (lib.node.fs.statSync(url).isDirectory()) { - removeDirectory(path + '/' + filename, removeFile); - } - else { - lib.node.fs.unlink(url, removeFile); - } - } - else { - lib.node.fs.rmdir(__dirname + '/' + path, callback); - } - } - removeFile(); - }); - }; - removeDirectory(this.path, function () { - enterDirectory(page, page.currentpath); - }); - } - catch (e) { - console.log(e); - } - } - else { - window.resolveLocalFileSystemURL(lib.assetURL + this.path, function (entry) { - entry.removeRecursively(function () { - enterDirectory(page, page.currentpath); - }); - }); - } - } - return; - } - enterDirectory(page, this.path); - }; - var clickFile = function () { - if (_status.dragged) return; - var page = this.parentNode.parentNode.parentNode; - if (page.deletebutton.classList.contains('active')) { - if (confirm('确认删除' + this.innerHTML + '?(此操作不可撤销)')) { - removeFile([this], page); - } - return; - } - this.classList.toggle('thundertext'); - page.clicked = true; - if (this.ext == 'jpg' || this.ext == 'png') { - if (this.classList.contains('thundertext')) { - if (!this.previewnode) { - this.previewnode = document.createElement('img'); - this.previewnode.src = lib.assetURL + this.path; - this.previewnode.width = '60'; - this.previewnode.style.maxHeight = '120px'; - this.parentNode.appendChild(this.previewnode); - } - } - else { - if (this.previewnode) { - this.previewnode.remove(); - delete this.previewnode; - } - } - } - else if (this.ext == 'mp3' || this.ext == 'ogg') { - if (this.classList.contains('thundertext')) { - if (!this.previewnode) { - this.previewnode = game.playAudio(this.path.slice(6)); - } - } - else { - if (this.previewnode) { - this.previewnode.remove(); - delete this.previewnode; - } - } - } - }; - var clickFileList = function () { - if (!this.parentNode) return; - if (this.parentNode.clicked) { - this.parentNode.clicked = false; - } - else { - var selected = Array.from(this.querySelectorAll('span.thundertext')); - for (var i = 0; i < selected.length; i++) { - selected[i].classList.remove('thundertext'); - if (selected[i].previewnode) { - selected[i].previewnode.remove(); - delete selected[i].previewnode; - } - } - } - }; - var enterDirectory = function (page, path) { - page.innerHTML = ''; - page.currentpath = path; - var backbutton = ui.create.div('.menubutton.round', '返', page, function () { - page.clicked = false; - clickFileList.call(filelist); - if (page.path == path) { - page.reset(); - } - else { - if (path.indexOf('/') == -1) { - enterDirectory(page, ''); - } - else { - enterDirectory(page, path.slice(0, path.lastIndexOf('/'))); - } - } - }); - backbutton.style.zIndex = 1; - backbutton.style.right = '10px'; - backbutton.style.bottom = '15px'; - - - var refresh = function () { - enterDirectory(page, path); - }; - var addbutton = ui.create.div('.menubutton.round', '添', page, function () { - var pos1 = this.getBoundingClientRect(); - var pos2 = ui.window.getBoundingClientRect(); - openMenu(this.menu, { - clientX: pos1.left + pos1.width + 5 - pos2.left, - clientY: pos1.top - pos2.top - }); - }); - addbutton.menu = ui.create.div('.menu'); - ui.create.div('', '添加文件', addbutton.menu, function () { - popupContainer.noclose = true; - }); - var createDir = function (str) { - if (lib.node && lib.node.fs) { - lib.node.fs.mkdir(__dirname + '/' + path + '/' + str, refresh); - } - else { - window.resolveLocalFileSystemURL(lib.assetURL + path, function (entry) { - entry.getDirectory(str, { create: true }, refresh); - }); - } - }; - ui.create.div('', '添加目录', addbutton.menu, function () { - ui.create.templayer(); - game.prompt('输入目录名称', function (str) { - if (str) { - createDir(str); - } - }); - }); - var input = document.createElement('input'); - input.className = 'fileinput'; - input.type = 'file'; - input.onchange = function () { - var fileToLoad = input.files[0]; - game.print(fileToLoad.name); - if (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - game.writeFile(e.target.result, path, fileToLoad.name, refresh); - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - } - }; - addbutton.menu.firstChild.appendChild(input); - addbutton.style.zIndex = 1; - addbutton.style.right = '10px'; - addbutton.style.bottom = '80px'; - - var deletebutton = ui.create.div('.menubutton.round', '删', page, function () { - if (!this.parentNode) return; - if (!this.classList.contains('active')) { - var selected = Array.from(filelist.querySelectorAll('span.thundertext')); - if (selected.length) { - if (confirm('一共要删除' + selected.length + '个文件,此操作不可撤销,是否确定?')) { - removeFile(selected, page); - } - } - else { - this.classList.add('active'); - } - } - else { - this.classList.remove('active'); - } - }); - deletebutton.style.zIndex = 1; - deletebutton.style.right = '10px'; - deletebutton.style.bottom = '145px'; - - page.backbutton = backbutton; - page.addbutton = addbutton; - page.deletebutton = deletebutton; - var filelist = ui.create.div(page); - filelist.classList.add('file-container'); - filelist.listen(clickFileList); - lib.setScroll(filelist); - game.getFileList(path, function (folders, files) { - var sort = function (a, b) { - if (a > b) return 1; - if (a < b) return -1; - return 0; - } - folders.sort(sort); - files.sort(sort); - var parent = path; - if (parent) { - parent += '/'; - } - for (var i = 0; i < folders.length; i++) { - if (!page.path && folders[i] == 'app') continue; - var entry = ui.create.div('', '' + folders[i], filelist); - entry.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickDirectory); - entry.firstChild.path = parent + folders[i] - } - for (var i = 0; i < files.length; i++) { - if (!page.path) { - if (files[i] == 'app.html') continue; - if (files[i] == 'main.js') continue; - if (files[i] == 'package.json') continue; - } - var entry = ui.create.div('', '' + files[i], filelist); - entry.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickFile); - entry.firstChild.ext = files[i].slice(files[i].lastIndexOf('.') + 1); - entry.firstChild.path = parent + files[i]; - entry.firstChild.filename = files[i]; - } - }); - }; - var dash1 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - page.reset = function () { - page.innerHTML = ''; - var backbutton = ui.create.div('.menubutton.round', '返', page, function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }); - backbutton.style.zIndex = 1; - backbutton.style.right = '10px'; - backbutton.style.bottom = '15px'; - var placeholder = ui.create.div('.placeholder', page); - placeholder.style.position = 'relative'; - placeholder.style.display = 'block'; - placeholder.style.width = '100%'; - placeholder.style.height = '14px'; - createDash2('将', '武将图片', 'image/character', page); - createDash2('肤', '皮肤图片', 'image/skin', page); - createDash2('卡', '卡牌图片', 'image/card', page); - createDash2('模', '模式图片', 'image/mode', page); - createDash2('始', '开始图片', 'image/splash', page); - createDash2('景', '背景图片', 'image/background', page); - }; - page.reset(); - return page; - }()); - var dash2 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - page.reset = function () { - page.innerHTML = ''; - var backbutton = ui.create.div('.menubutton.round', '返', page, function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }); - backbutton.style.zIndex = 1; - backbutton.style.right = '10px'; - backbutton.style.bottom = '15px'; - var placeholder = ui.create.div('.placeholder', page); - placeholder.style.position = 'relative'; - placeholder.style.display = 'block'; - placeholder.style.width = '100%'; - placeholder.style.height = '14px'; - createDash2('技', '技能配音', 'audio/skill', page); - createDash2('卡', '男性卡牌', 'audio/card/male', page); - createDash2('牌', '女性卡牌', 'audio/card/female', page); - createDash2('亡', '阵亡配音', 'audio/die', page); - createDash2('效', '游戏音效', 'audio/effect', page); - createDash2('景', '背景音乐', 'audio/background', page); - }; - page.reset(); - return page; - }()); - var dash3 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - page.path = 'font'; - page.reset = function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }; - page.init = function () { - enterDirectory(page, 'font'); - }; - return page; - }()); - var dash4 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - page.path = ''; - page.reset = function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }; - page.init = function () { - enterDirectory(page, ''); - }; - return page; - }()); - createDash('图', '图片文件', dash1); - createDash('音', '音频文件', dash2); - createDash('字', '字体文件', dash3); - createDash('全', '全部文件', dash4); - }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - createModeConfig('others', start.firstChild); - - var active = start.firstChild.querySelector('.active'); - if (!active) { - active = start.firstChild.firstChild; - active.classList.add('active'); - } - if (!active.link) active._initLink(); - rightPane.appendChild(active.link); - }()); - - (function () { - var start = menuxpages.shift(); - var rightPane = start.lastChild; - - var clickMode = function () { - var active = this.parentNode.querySelector('.active'); - if (active) { - if (active === this) { - return; - } - active.classList.remove('active'); - active.link.remove(); - } - this.classList.add('active'); - updateActive(this); - if (this.link) rightPane.appendChild(this.link); - else { - this._initLink(); - rightPane.appendChild(this.link); - } - }; - updateActive = function (node) { - if (!node) { - node = start.firstChild.querySelector('.active'); - if (!node) { - return; - } - } - if (!node.link) { - node._initLink(); - } - for (var i = 0; i < node.link.childElementCount; i++) { - if (node.link.childNodes[i].updateBanned) { - node.link.childNodes[i].updateBanned(); - } - } - }; - var updateNodes = function () { - for (var i = 0; i < start.firstChild.childNodes.length; i++) { - var node = start.firstChild.childNodes[i]; - if (node.mode) { - if (node.mode.startsWith('mode_')) continue; - if (node.mode == 'custom') continue; - if (connectMenu) { - if (!lib.config.connect_characters.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - else { - if (lib.config.characters.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - } - } - } - var togglePack = function (bool) { - var name = this._link.config._name; - if (connectMenu) { - if (!bool) { - lib.config.connect_characters.add(name); - } - else { - lib.config.connect_characters.remove(name); - } - game.saveConfig('connect_characters', lib.config.connect_characters); - } - else { - if (bool) { - lib.config.characters.add(name); - } - else { - lib.config.characters.remove(name); - } - game.saveConfig('characters', lib.config.characters); - } - updateNodes(); - }; - - var createModeConfig = function (mode, position, position2) { - var _info = lib.characterPack[mode]; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', lib.translate[mode + '_character_config'], position, clickMode); - if (node.innerHTML.length >= 5) { - node.classList.add('smallfont'); - } - if (position2) { - position.insertBefore(node, position2); - } - node.mode = mode; - node._initLink = function () { - node.link = page; - page.node = node; - var list = []; - var boolAI = true; - var alterableSkills = []; - var alterableCharacters = []; - var charactersToAlter = []; - for (var i in _info) { - if (_info[i][4] && _info[i][4].includes('unseen')) continue; - if (connectMenu && lib.connectBanned.includes(i)) continue; - list.push(i); - if (boolAI && !lib.config.forbidai_user.includes(i)) boolAI = false; - for (var j = 0; j < _info[i][3].length; j++) { - if (!lib.skill[_info[i][3][j]]) { - continue; - } - if (lib.skill[_info[i][3][j]].alter) { - alterableSkills.add(_info[i][3][j]); - alterableCharacters.add(i); - if (lib.config.vintageSkills.includes(_info[i][3][j])) { - charactersToAlter.add(i); - } - } - } - } - alterableCharacters.sort(); - list.sort(lib.sort.character); - var list2 = list.slice(0); - var cfgnode = createConfig({ - name: '开启', - _name: mode, - init: connectMenu ? (!lib.config.connect_characters.includes(mode)) : (lib.config.characters.includes(mode)), - onclick: togglePack - }); - var cfgnodeAI = createConfig({ - name: '仅点将可用', - _name: mode, - init: boolAI, - intro: '将该武将包内的武将全部设置为仅点将可用', - onclick(bool) { - if (bool) { - for (var i = 0; i < list.length; i++) { - lib.config.forbidai_user.add(list[i]); - } - } - else { - for (var i = 0; i < list.length; i++) { - lib.config.forbidai_user.remove(list[i]); - } - } - game.saveConfig('forbidai_user', lib.config.forbidai_user); - }, - }); - if (!mode.startsWith('mode_')) { - cfgnodeAI.style.marginTop = '0px'; - page.appendChild(cfgnode); - page.appendChild(cfgnodeAI); - if (alterableCharacters.length) { - var cfgnode2 = createConfig({ - name: '新版替换', - _name: mode, - init: charactersToAlter.length == 0, - intro: '以下武将将被修改:' + get.translation(alterableCharacters), - onclick(bool) { - if (bool) { - for (var i = 0; i < alterableSkills.length; i++) { - lib.config.vintageSkills.remove(alterableSkills[i]); - lib.translate[alterableSkills[i] + '_info'] = lib.translate[alterableSkills[i] + '_info_alter']; - } - } - else { - for (var i = 0; i < alterableSkills.length; i++) { - lib.config.vintageSkills.add(alterableSkills[i]); - lib.translate[alterableSkills[i] + '_info'] = lib.translate[alterableSkills[i] + '_info_origin']; - } - } - game.saveConfig('vintageSkills', lib.config.vintageSkills); - } - }); - cfgnode2.style.marginTop = '0px'; - page.appendChild(cfgnode2); - } - } - else if (mode.startsWith('mode_extension')) { - page.appendChild(cfgnodeAI); - } - else { - page.style.paddingTop = '8px'; - } - var banCharacter = function (e) { - if (_status.clicked) { - _status.clicked = false; - return; - } - if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && - mode != 'mode_favourite' && mode != 'mode_banned') { - if (!connectMenu && lib.config.show_charactercard) { - ui.click.charactercard(this.link, this, mode == 'mode_guozhan' ? 'guozhan' : true); - } - return; - } - ui.click.touchpop(); - this._banning = connectMenu ? 'online' : 'offline'; - if (!connectMenu && lib.config.show_charactercard) { - ui.click.charactercard(this.link, this); - } - else { - ui.click.intro.call(this, e); - } - _status.clicked = false; - delete this._banning; - }; - var updateBanned = function () { - var _list; - if (connectMenu) { - var mode = menux.pages[0].firstChild.querySelector('.active'); - if (mode && mode.mode) { - _list = lib.config['connect_' + mode.mode + '_banned']; - } - } - else { - _list = lib.config[get.mode() + '_banned']; - } - if (_list && _list.includes(this.link)) { - this.classList.add('banned'); - } - else { - this.classList.remove('banned'); - } - }; - if (lib.characterSort[mode]) { - var listb = []; - if (!connectMenu) { - listb = lib.config[get.mode() + '_banned'] || []; - } - else { - var modex = menux.pages[0].firstChild.querySelector('.active'); - if (modex && modex.mode) { - listb = lib.config['connect_' + modex.mode + '_banned']; - } - } - for (var pak in lib.characterSort[mode]) { - var info = lib.characterSort[mode][pak]; - var listx = []; - var boolx = false; - for (var ii = 0; ii < list2.length; ii++) { - if (info.includes(list2[ii])) { - listx.add(list2[ii]); - if (!listb.includes(list2[ii])) boolx = true; - list2.splice(ii--, 1); - } - } - if (listx.length) { - var cfgnodeY = { - name: lib.translate[pak], - _name: pak, - init: boolx, - onclick(bool) { - var banned = []; - if (connectMenu) { - var modex = menux.pages[0].firstChild.querySelector('.active'); - if (modex && modex.mode) { - banned = lib.config['connect_' + modex.mode + '_banned']; - } - } - else if (_status.connectMode) return; - else banned = lib.config[get.mode() + '_banned'] || []; - var listx = lib.characterSort[mode][this._link.config._name]; - if (bool) { - for (var i = 0; i < listx.length; i++) { - banned.remove(listx[i]); - } - } - else { - for (var i = 0; i < listx.length; i++) { - banned.add(listx[i]); - } - } - game.saveConfig(connectMenu ? ('connect_' + modex.mode + '_banned') : (get.mode() + '_banned'), banned); - updateActive(); - }, - }; - if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && !mode.startsWith('mode_guozhan')) { - cfgnodeY.clear = true; - delete cfgnodeY.onclick; - } - var cfgnodeX = createConfig(cfgnodeY); - page.appendChild(cfgnodeX); - var buttons = ui.create.buttons(listx, 'character', page); - for (var i = 0; i < buttons.length; i++) { - buttons[i].classList.add('noclick'); - buttons[i].listen(banCharacter); - ui.create.rarity(buttons[i]); - buttons[i].node.hp.style.transition = 'all 0s'; - buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; - if (mode != 'mode_banned') { - buttons[i].updateBanned = updateBanned; - } - } - } - } - if (list2.length) { - var cfgnodeX = createConfig({ - name: '其他', - _name: 'others', - clear: true, - }); - page.appendChild(cfgnodeX); - var buttons = ui.create.buttons(list2, 'character', page); - for (var i = 0; i < buttons.length; i++) { - buttons[i].classList.add('noclick'); - buttons[i].listen(banCharacter); - ui.create.rarity(buttons[i]); - buttons[i].node.hp.style.transition = 'all 0s'; - buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; - if (mode != 'mode_banned') { - buttons[i].updateBanned = updateBanned; - } - } - } - } - else { - var buttons = ui.create.buttons(list, 'character', page); - for (var i = 0; i < buttons.length; i++) { - buttons[i].classList.add('noclick'); - ui.create.rarity(buttons[i]); - buttons[i].listen(banCharacter); - buttons[i].node.hp.style.transition = 'all 0s'; - buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; - if (mode != 'mode_banned') { - buttons[i].updateBanned = updateBanned; - } - } - } - page.classList.add('menu-buttons'); - page.classList.add('leftbutton'); - if (!connectMenu) { - if (lib.config.all.sgscharacters.includes(mode)) { - ui.create.div('.config.pointerspan', '该武将包不可被隐藏', page); - } - else if (!mode.startsWith('mode_')) { - ui.create.div('.config.pointerspan', '隐藏武将包', page, function () { - if (this.firstChild.innerHTML == '隐藏武将包') { - if (confirm('真的要隐藏“' + get.translation(mode + '_character_config') + '”武将包吗?\n建议使用“关闭”而不是“隐藏”功能,否则将会影响其他相关武将包的正常运行!')) { - this.firstChild.innerHTML = '武将包将在重启后隐藏'; - lib.config.hiddenCharacterPack.add(mode); - if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); - } - } - } - else { - this.firstChild.innerHTML = '隐藏武将包'; - lib.config.hiddenCharacterPack.remove(mode); - } - game.saveConfig('hiddenCharacterPack', lib.config.hiddenCharacterPack); - }); - } - } - }; - if (!get.config('menu_loadondemand')) node._initLink(); - return node; - }; - if (lib.config.show_favourite_menu && !connectMenu && Array.isArray(lib.config.favouriteCharacter)) { - lib.characterPack.mode_favourite = {}; - for (var i = 0; i < lib.config.favouriteCharacter.length; i++) { - var favname = lib.config.favouriteCharacter[i]; - if (lib.character[favname]) { - lib.characterPack.mode_favourite[favname] = lib.character[favname]; - } - } - var favouriteCharacterNode = createModeConfig('mode_favourite', start.firstChild); - if (!favouriteCharacterNode.link) favouriteCharacterNode._initLink(); - ui.favouriteCharacter = favouriteCharacterNode.link; - if (get.is.empty(lib.characterPack.mode_favourite)) { - ui.favouriteCharacter.node.style.display = 'none'; - } - delete lib.characterPack.mode_favourite; - } - if (!connectMenu && lib.config.show_ban_menu) { - lib.characterPack.mode_banned = {}; - for (var i = 0; i < lib.config.all.mode.length; i++) { - var banned = lib.config[lib.config.all.mode[i] + '_banned']; - if (banned) { - for (var j = 0; j < banned.length; j++) { - if (lib.character[banned[j]]) { - lib.characterPack.mode_banned[banned[j]] = lib.character[banned[j]]; - } - } - } - } - var bannednode = createModeConfig('mode_banned', start.firstChild); - if (get.is.empty(lib.characterPack.mode_banned)) { - bannednode.style.display = 'none'; - } - delete lib.characterPack.mode_banned; - } - var characterlist = connectMenu ? lib.connectCharacterPack : lib.config.all.characters; - for (var i = 0; i < characterlist.length; i++) { - createModeConfig(characterlist[i], start.firstChild); - } - if (!connectMenu) Object.keys(lib.characterPack).forEach(key => { - if (key.startsWith('mode_')) createModeConfig(key, start.firstChild); - }); - var active = start.firstChild.querySelector('.active'); - if (!active) { - active = start.firstChild.firstChild; - if (active.style.display == 'none') { - active = active.nextSibling; - if (active.style.display == 'none') { - active = active.nextSibling; - } - } - active.classList.add('active'); - updateActive(active); - } - if (!active.link) active._initLink(); - rightPane.appendChild(active.link); - - if (!connectMenu) { - var node1 = ui.create.div('.lefttext', '全部开启', start.firstChild, function () { - game.saveConfig('characters', lib.config.all.characters); - updateNodes(); - }); - var node2 = ui.create.div('.lefttext', '恢复默认', start.firstChild, function () { - game.saveConfig('characters', lib.config.defaultcharacters); - updateNodes(); - }); - node1.style.marginTop = '12px'; - node2.style.marginTop = '7px'; - } - - updateNodes(); - }()); - - (function () { - var start = menuxpages.shift(); - var rightPane = start.lastChild; - var pileCreated = false; - var recreatePile = function () { - lib.config.customcardpile['当前牌堆'] = [lib.config.bannedpile, lib.config.addedpile]; - game.saveConfig('customcardpile', lib.config.customcardpile); - game.saveConfig('cardpilename', '当前牌堆', true); - pileCreated = false; - }; - - var clickMode = function () { - var active = this.parentNode.querySelector('.active'); - if (active === this) { - return; - } - active.classList.remove('active'); - active.link.remove(); - active = this; - this.classList.add('active'); - updateActiveCard(this); - if (this.mode == 'cardpile') { - this.create(); - } - if (this.link) rightPane.appendChild(this.link); - else { - this._initLink(); - rightPane.appendChild(this.link); - } - }; - updateActiveCard = function (node) { - if (!node) { - node = start.firstChild.querySelector('.active'); - if (!node) { - return; - } - } - if (!node.link) node._initLink(); - for (var i = 0; i < node.link.childElementCount; i++) { - if (node.link.childNodes[i].updateBanned) { - node.link.childNodes[i].updateBanned(); - } - } - }; - var updateNodes = function () { - for (var i = 0; i < start.firstChild.childNodes.length; i++) { - var node = start.firstChild.childNodes[i]; - if (node.mode) { - if (node.mode.startsWith('mode_')) continue; - if (node.mode == 'custom') continue; - if (node.mode == 'cardpile') continue; - if (connectMenu) { - if (!lib.config.connect_cards.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - else { - if (lib.config.cards.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - } - } - } - var togglePack = function (bool) { - var name = this._link.config._name; - if (connectMenu) { - if (!bool) { - lib.config.connect_cards.add(name); - } - else { - lib.config.connect_cards.remove(name); - } - game.saveConfig('connect_cards', lib.config.connect_cards); - } - else { - if (bool) { - lib.config.cards.add(name); - } - else { - lib.config.cards.remove(name); - } - game.saveConfig('cards', lib.config.cards); - } - updateNodes(); - }; - var toggleCardPile = function (bool) { - var name = this._link.config._name; - var number = this._link.config._number; - if (!lib.config.bannedpile[name]) { - lib.config.bannedpile[name] = []; - } - if (bool) { - lib.config.bannedpile[name].remove(number); - } - else { - lib.config.bannedpile[name].add(number); - } - recreatePile(); - } - - var createModeConfig = function (mode, position) { - var info = lib.cardPack[mode]; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', lib.translate[mode + '_card_config'], position, clickMode); - if (node.innerHTML.length >= 5) { - node.classList.add('smallfont'); - } - node.mode = mode; - node._initLink = function () { - node.link = page; - var list = []; - for (var i = 0; i < info.length; i++) { - if (!lib.card[info[i]] || (lib.card[info[i]].derivation && mode != 'mode_derivation')) continue; - list.push([get.translation(get.type(info[i], 'trick')), '', info[i]]); - } - var sortCard = function (card) { - var type = lib.card[card[2]].type; - var subtype = lib.card[card[2]].subtype; - if (lib.cardType[subtype]) { - return lib.cardType[subtype]; - } - if (lib.cardType[type]) { - return lib.cardType[type]; - } - switch (type) { - case 'basic': return 0; - case 'chess': return 1.5; - case 'trick': return 2; - case 'delay': return 3; - case 'equip': { - switch (lib.card[card[2]].subtype) { - case 'equip1': return 4.1; - case 'equip2': return 4.2; - case 'equip3': return 4.3; - case 'equip4': return 4.4; - case 'equip5': return 4.5; - default: return 4; - } - } - case 'zhenfa': return 5; - default: return 6; - } - } - list.sort(function (a, b) { - var sort1 = sortCard(a); - var sort2 = sortCard(b); - if (sort1 == sort2) { - return (b[2] < a[2]) ? 1 : -1; - } - else if (sort1 > sort2) { - return 1; - } - else { - return -1; - } - }); - var cfgnode = createConfig({ - name: '开启', - _name: mode, - init: lib.config.cards.includes(mode), - onclick: togglePack - }); - if (!mode.startsWith('mode_')) { - page.appendChild(cfgnode); - } - else { - page.style.paddingTop = '8px'; - } - var banCard = function (e) { - if (_status.clicked) { - _status.clicked = false; - return; - } - if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && mode != 'mode_banned') { - return; - } - ui.click.touchpop(); - this._banning = connectMenu ? 'online' : 'offline'; - ui.click.intro.call(this, e); - _status.clicked = false; - delete this._banning; - }; - var updateBanned = function () { - var list; - if (connectMenu) { - var mode = menux.pages[0].firstChild.querySelector('.active'); - if (mode && mode.mode) { - list = lib.config['connect_' + mode.mode + '_bannedcards']; - } - } - else { - list = lib.config[get.mode() + '_bannedcards']; - } - if (list && list.includes(this.link[2])) { - this.classList.add('banned'); - } - else { - this.classList.remove('banned'); - } - }; - var buttons = ui.create.buttons(list, 'vcard', page); - for (var i = 0; i < buttons.length; i++) { - buttons[i].classList.add('noclick'); - buttons[i].listen(banCard); - if (mode != 'mode_banned') { - buttons[i].updateBanned = updateBanned; - } - } - page.classList.add('menu-buttons'); - page.classList.add('leftbutton'); - if (!connectMenu && !lib.config.all.sgscards.includes(mode) && !mode.startsWith('mode_')) { - ui.create.div('.config.pointerspan', '隐藏卡牌包', page, function () { - if (this.firstChild.innerHTML == '隐藏卡牌包') { - this.firstChild.innerHTML = '卡牌包将在重启后隐藏'; - lib.config.hiddenCardPack.add(mode); - if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); - } - } - else { - this.firstChild.innerHTML = '隐藏卡牌包'; - lib.config.hiddenCardPack.remove(mode); - } - game.saveConfig('hiddenCardPack', lib.config.hiddenCardPack); - }); - } - if (!mode.startsWith('mode_') && lib.cardPile[mode]) { - var cardpileNodes = []; - var cardpileexpanded = false; - if (!lib.config.bannedpile[mode]) { - lib.config.bannedpile[mode] = []; - } - if (!lib.config.addedpile[mode]) { - lib.config.addedpile[mode] = []; - } - ui.create.div('.config.more.pile', '编辑牌堆
>
', page, function () { - if (cardpileexpanded) { - this.classList.remove('on'); - for (var k = 0; k < cardpileNodes.length; k++) { - cardpileNodes[k].style.display = 'none'; - } - } - else { - this.classList.add('on'); - for (var k = 0; k < cardpileNodes.length; k++) { - cardpileNodes[k].style.display = ''; - } - } - cardpileexpanded = !cardpileexpanded; - }); - var cfgnode = ui.create.div(page, '.config.pointerspan.cardpilecfg.toggle'); - var cfgaddcard = ui.create.node('button', '', '添加卡牌', cfgnode, function () { - this.parentNode.nextSibling.classList.toggle('hidden'); - }); - var cfgbancard = ui.create.node('button', '', '全部关闭', cfgnode, function () { - for (var i = 0; i < cardpileNodes.length; i++) { - if (cardpileNodes[i].type == 'defaultcards' && cardpileNodes[i].classList.contains('on')) { - clickToggle.call(cardpileNodes[i]); - } - } - }); - var cfgenablecard = ui.create.node('button', '', '全部开启', cfgnode, function () { - for (var i = 0; i < cardpileNodes.length; i++) { - if (cardpileNodes[i].type == 'defaultcards' && !cardpileNodes[i].classList.contains('on')) { - clickToggle.call(cardpileNodes[i]); - } - } - }); - cfgbancard.style.marginLeft = '5px'; - cfgenablecard.style.marginLeft = '5px'; - cardpileNodes.push(cfgnode); - cfgnode.style.display = 'none'; - cfgnode.classList.add('cardpilecfg'); - cfgnode.classList.add('toggle'); - cfgnode.style.marginTop = '5px'; - page.appendChild(cfgnode); - - var cardpileadd = ui.create.div('.config.toggle.hidden.cardpilecfg.cardpilecfgadd', page); - var pileaddlist = []; - for (var i = 0; i < lib.config.cards.length; i++) { - if (!lib.cardPack[lib.config.cards[i]]) continue; - for (var j = 0; j < lib.cardPack[lib.config.cards[i]].length; j++) { - var cname = lib.cardPack[lib.config.cards[i]][j]; - pileaddlist.push([cname, get.translation(cname)]); - if (cname == 'sha') { - pileaddlist.push(['huosha', '火杀']); - pileaddlist.push(['leisha', '雷杀']); - pileaddlist.push(['icesha', '冰杀']); - pileaddlist.push(['cisha', '刺杀']); - } - } - } - var cardpileaddname = ui.create.selectlist(pileaddlist, null, cardpileadd); - cardpileaddname.style.width = '75px'; - cardpileaddname.style.marginRight = '2px'; - cardpileaddname.style.marginLeft = '-1px'; - var cardpileaddsuit = ui.create.selectlist([ - ['heart', '红桃'], - ['diamond', '方片'], - ['club', '梅花'], - ['spade', '黑桃'], - ], null, cardpileadd); - cardpileaddsuit.style.width = '53px'; - cardpileaddsuit.style.marginRight = '2px'; - var cardpileaddnumber = ui.create.selectlist([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 - ], null, cardpileadd); - cardpileaddnumber.style.width = '43px'; - cardpileaddnumber.style.marginRight = '2px'; - var button = document.createElement('button'); - button.innerHTML = '确定'; - button.style.width = '40px'; - var deletecard = function () { - this.parentNode.remove(); - var info = this.parentNode._info; - var list = lib.config.addedpile[mode]; - for (var i = 0; i < list.length; i++) { - if (list[i][0] == info[0] && list[i][1] == info[1] && list[i][2] == info[2]) { - list.splice(i, 1); break; - } - } - recreatePile(); - }; - button.onclick = function () { - var card = [ - cardpileaddsuit.value, - cardpileaddnumber.value, - cardpileaddname.value, - ]; - lib.config.addedpile[mode].push(card); - recreatePile(); - var cfgnode = ui.create.div('.config.toggle.cardpilecfg'); - cfgnode._info = card; - cfgnode.innerHTML = get.translation(card[2]) + ' ' + get.translation(card[0]) + get.strNumber(card[1]); - var cfgnodedelete = document.createElement('span'); - cfgnodedelete.classList.add('cardpiledelete'); - cfgnodedelete.innerHTML = '删除'; - cfgnodedelete.onclick = deletecard; - cfgnode.appendChild(cfgnodedelete); - page.insertBefore(cfgnode, cardpileadd.nextSibling); - }; - cardpileadd.appendChild(button); - cardpileadd.style.whiteSpace = 'nowrap'; - cardpileNodes.push(cardpileadd); - - for (var i = 0; i < lib.config.addedpile[mode].length; i++) { - var card = lib.config.addedpile[mode][i]; - var cfgnode = ui.create.div('.config.toggle.cardpilecfg'); - cfgnode._info = card; - cfgnode.innerHTML = get.translation(card[2]) + ' ' + get.translation(card[0]) + card[1]; - var cfgnodedelete = document.createElement('span'); - cfgnodedelete.classList.add('cardpiledelete'); - cfgnodedelete.innerHTML = '删除'; - cfgnodedelete.onclick = deletecard; - cfgnode.appendChild(cfgnodedelete); - cfgnode.style.display = 'none'; - cardpileNodes.push(cfgnode); - page.appendChild(cfgnode); - } - - for (var i = 0; i < lib.cardPile[mode].length; i++) { - var card = lib.cardPile[mode][i]; - var cfgnode = createConfig({ - name: ((card[2] == 'sha' && card[3]) ? (get.translation(card[3])) : '') + get.translation(card[2]) + ' ' + get.translation(card[0]) + get.strNumber(card[1]), - _number: i, - _name: mode, - init: !lib.config.bannedpile[mode].includes(i), - onclick: toggleCardPile - }); - cfgnode.type = 'defaultcards'; - cardpileNodes.push(cfgnode); - cfgnode.style.display = 'none'; - cfgnode.classList.add('cardpilecfg'); - page.appendChild(cfgnode); - } - ui.create.div('.menuplaceholder', page); - } - }; - if (!get.config('menu_loadondemand')) node._initLink(); - return node; - }; - if (!connectMenu && lib.config.show_ban_menu) { - lib.cardPack.mode_banned = []; - for (var i = 0; i < lib.config.all.mode.length; i++) { - var banned = lib.config[lib.config.all.mode[i] + '_bannedcards']; - if (banned) { - for (var j = 0; j < banned.length; j++) { - lib.cardPack.mode_banned.add(banned[j]); - } - } - } - var bannednode = createModeConfig('mode_banned', start.firstChild); - if (lib.cardPack.mode_banned.length == 0) { - bannednode.style.display = 'none'; - } - delete lib.cardPack.mode_banned; - } - for (var i = 0; i < lib.config.all.cards.length; i++) { - if (connectMenu && !lib.connectCardPack.includes(lib.config.all.cards[i])) continue; - createModeConfig(lib.config.all.cards[i], start.firstChild); - } - if (!connectMenu) Object.keys(lib.cardPack).forEach(key => { - if (key.startsWith('mode_')) createModeConfig(key, start.firstChild); - }); - var active = start.firstChild.querySelector('.active'); - if (!active) { - active = start.firstChild.firstChild; - if (active.style.display == 'none') { - active = active.nextSibling; - } - active.classList.add('active'); - updateActiveCard(active); - } - if (!active.link) active._initLink(); - rightPane.appendChild(active.link); - - (function () { - if (connectMenu) return; - var page = ui.create.div('.menu-buttons'); - var node = ui.create.div('.menubutton.large', '牌堆', clickMode); - start.firstChild.insertBefore(node, start.firstChild.querySelector('.lefttext')); - node.link = page; - node.mode = 'cardpile'; - node.create = function () { - if (pileCreated) return; - pileCreated = true; - page.innerHTML = ''; - - var pileList = null; - var createList = function () { - if (pileList) { - pileList.remove(); - } - var list = ['默认牌堆']; - if (lib.config.customcardpile['当前牌堆']) { - list.push('当前牌堆'); - } - for (var i in lib.config.customcardpile) { - list.add(i); - } - var currentpile = get.config('cardpilename'); - if (!currentpile) { - if (list.includes('当前牌堆')) { - currentpile = '当前牌堆'; - } - else { - currentpile = '默认牌堆'; - } - } - pileList = ui.create.selectlist(list, currentpile, pileChoose, function (e) { - game.saveConfig('cardpilename', this.value, true); - restart.style.display = ''; - }); - pileList.style.float = 'right'; - } - var pileChoose = ui.create.div('.config.toggle.cardpilecfg.nomarginleft', '选择牌堆', page); - createList(); - - var pileDel = function () { - delete lib.config.customcardpile[this.parentNode.link]; - this.parentNode.remove(); - game.saveConfig('customcardpile', lib.config.customcardpile); - for (var i in lib.config.mode_config) { - if (i == 'global') continue; - if (lib.config.mode_config[i].cardpilename == this.parentNode.link) { - game.saveConfig('cardpilename', null, i); - } - } - createList(); - }; - - var restart = ui.create.div('.config.more', '重新启动', game.reload, page); - restart.style.display = 'none'; - var createPileNode = function (name) { - var node = ui.create.div('.config.toggle.cardpilecfg.nomarginleft', name); - node.link = name; - var del = document.createElement('span'); - del.innerHTML = '删除'; - del.classList.add('cardpiledelete'); - del.onclick = pileDel; - node.appendChild(del); - if (name == '当前牌堆') { - page.insertBefore(node, pileChoose.nextSibling); - } - else { - page.insertBefore(node, restart); - } - }; - for (var i in lib.config.customcardpile) { - createPileNode(i); - } - var exportCardPile; - ui.create.div('.config.more', '保存当前牌堆
>
', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - exportCardPile.classList.remove('hidden'); - } - else { - exportCardPile.classList.add('hidden'); - } - }); - exportCardPile = ui.create.div('.config.cardpileadd.indent', page); - exportCardPile.classList.add('hidden'); - ui.create.div('', '名称:', exportCardPile); - var input = exportCardPile.firstChild.lastChild.previousSibling; - input.value = '自定义牌堆'; - input.style.marginRight = '3px'; - input.style.width = '120px'; - exportCardPile.firstChild.lastChild.onclick = function () { - var name = input.value; - var ok = true; - if (lib.config.customcardpile[name] || name == '默认牌堆' || name == '当前牌堆') { - for (var i = 1; i <= 1000; i++) { - if (!lib.config.customcardpile[name + '(' + i + ')']) { - name = name + '(' + i + ')'; - break; - } - } - } - lib.config.customcardpile[name] = [lib.config.bannedpile, lib.config.addedpile]; - delete lib.config.customcardpile['当前牌堆']; - for (var i in lib.mode) { - if (lib.config.mode_config[i] && - (lib.config.mode_config[i].cardpilename == '当前牌堆' || !lib.config.mode_config[i].cardpilename)) { - game.saveConfig('cardpilename', name, i); - } - } - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].link == '当前牌堆') { - page.childNodes[i].remove(); - break; - } - } - game.saveConfig('customcardpile', lib.config.customcardpile); - createPileNode(name); - createList(); - }; - } - }()); - - if (!connectMenu) { - var node1 = ui.create.div('.lefttext', '全部开启', start.firstChild, function () { - game.saveConfig('cards', lib.config.all.cards); - updateNodes(); - }); - var node2 = ui.create.div('.lefttext', '恢复默认', start.firstChild, function () { - game.saveConfig('cards', lib.config.defaultcards); - updateNodes(); - }); - node1.style.marginTop = '12px'; - node2.style.marginTop = '7px'; - } - - updateNodes(); - }()); - - (function () { - if (connectMenu) return; - var start = menuxpages.shift(); - var rightPane = start.lastChild; - - var clickMode = function () { - if (this.mode == 'get') { - this.update(); - } - var active = this.parentNode.querySelector('.active'); - if (active === this) { - return; - } - active.classList.remove('active'); - active.link.remove(); - active = this; - this.classList.add('active'); - if (this.link) rightPane.appendChild(this.link); - else { - this._initLink(); - rightPane.appendChild(this.link); - } - updateNodes(); - }; - ui.click.extensionTab = function (name) { - ui.click.menuTab('扩展'); - for (var i = 0; i < start.firstChild.childElementCount; i++) { - if (start.firstChild.childNodes[i].innerHTML == name) { - clickMode.call(start.firstChild.childNodes[i]); - break; - } - } - } - var updateNodes = function () { - for (var i = 0; i < start.firstChild.childNodes.length; i++) { - var node = start.firstChild.childNodes[i]; - if (node.mode == 'get') continue; - if (node.mode == 'create') continue; - if (node.mode && node.mode.startsWith('extension_')) { - if (lib.config[node.mode + '_enable']) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - else { - if (lib.config.plays.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - } - } - var togglePack = function (bool) { - var name = this._link.config._name; - if (name.startsWith('extension_')) { - if (bool) { - game.saveConfig(name, true); - } - else { - game.saveConfig(name, false); - } - } - else { - name = name.slice(0, name.indexOf('_enable_playpackconfig')); - if (bool) { - lib.config.plays.add(name); - } - else { - lib.config.plays.remove(name); - } - game.saveConfig('plays', lib.config.plays); - } - if (this.onswitch) { - this.onswitch(bool); - } - updateNodes(); - }; - - var createModeConfig = function (mode, position) { - var page = ui.create.div(''); - page.style.paddingBottom = '10px'; - var node; - if (mode.startsWith('extension_')) { - node = ui.create.div('.menubutton.large', mode.slice(10), position, clickMode); - } - else { - node = ui.create.div('.menubutton.large', lib.translate[mode + '_play_config'], position, clickMode); - } - if (node.innerHTML.length >= 5) { - node.classList.add('smallfont'); - } - node.mode = mode; - // node._initLink=function(){ - node.link = page; - for (var i in lib.extensionMenu[mode]) { - if (i == 'game') continue; - var cfg = copyObj(lib.extensionMenu[mode][i]); - var j; - if (mode.startsWith('extension_')) { - j = mode + '_' + i; - } - else { - j = mode + '_' + i + '_playpackconfig'; - } - cfg._name = j; - if (j in lib.config) { - cfg.init = lib.config[j]; - } - else { - game.saveConfig(j, cfg.init); - } - - if (i == 'enable') { - cfg.onclick = togglePack; - } - else if (!lib.extensionMenu[mode][i].onclick) { - cfg.onclick = function (result) { - var cfg = this._link.config; - game.saveConfig(cfg._name, result); - }; - } - var cfgnode = createConfig(cfg); - if (cfg.onswitch) { - cfgnode.onswitch = cfg.onswitch; - } - page.appendChild(cfgnode); - } - // }; - // if(!get.config('menu_loadondemand')) node._initLink(); - return node; - }; - for (var i in lib.extensionMenu) { - if (lib.config.all.stockextension.includes(i) && !lib.config.all.plays.includes(i)) continue; - if (lib.config.hiddenPlayPack.includes(i)) continue; - createModeConfig(i, start.firstChild); - } - (function () { - if (!lib.device && !lib.db) return; - if (lib.config.show_extensionmaker == false) return; - var page = ui.create.div('#create-extension'); - var node = ui.create.div('.menubutton.large', '制作扩展', start.firstChild, clickMode); - node.mode = 'create'; - game.editExtension = function (name) { - node._initLink(); - game.editExtension(name); - }; - node._initLink = function () { - node.link = page; - var pageboard = ui.create.div(page); - var inputExtLine = ui.create.div(pageboard); - inputExtLine.style.transition = 'all 0s'; - inputExtLine.style.padding = '10px'; - inputExtLine.style.height = '22px'; - inputExtLine.style.lineHeight = '22px'; - inputExtLine.style.whiteSpace = 'nowrap'; - inputExtLine.style.overflow = 'visible'; - var inputExtSpan = document.createElement('span'); - inputExtSpan.innerHTML = '扩展名:'; - inputExtLine.appendChild(inputExtSpan); - var inputExtName = document.createElement('input'); - inputExtName.type = 'text'; - inputExtName.value = '无名扩展'; - inputExtName.style.width = '80px'; - inputExtName.style.textAlign = 'center'; - inputExtLine.appendChild(inputExtName); - - var buttonConfirmOnclick = function () { - buttonConfirm.style.display = 'none'; - inputExtSpan.style.display = 'none'; - inputExtName.style.display = 'none'; - authorExtLine.style.display = 'none'; - introExtLine.style.display = 'none'; - forumExtLine.style.display = 'none'; - diskExtLine.style.display = 'none'; - versionExtLine.style.display = 'none'; - okExtLine.style.display = 'none'; - inputExtLine.style.padding = '10px'; - buttonRename.style.display = ''; - buttonSave.style.display = ''; - buttonReset.style.display = ''; - buttonExport.style.display = ''; - inputExtSpan.innerHTML = '扩展名称:'; - inputExtName.style.width = '100px'; - inputExtName.style.textAlign = ''; - - dashboard.style.display = ''; - }; - var createExtLine = function (str, str2) { - var infoExtLine = ui.create.div(pageboard); - infoExtLine.style.display = 'none'; - infoExtLine.style.padding = '0 10px 10px 10px'; - infoExtLine.style.height = '22px'; - infoExtLine.style.lineHeight = '22px'; - infoExtLine.style.whiteSpace = 'nowrap'; - infoExtLine.style.overflow = 'visible'; - if (typeof str == 'boolean') { - var inputConfirm = document.createElement('button'); - inputConfirm.innerHTML = '确定'; - inputConfirm.onclick = buttonConfirmOnclick; - infoExtLine.appendChild(inputConfirm); - return infoExtLine; - } - var infoExtSpan = document.createElement('span'); - infoExtSpan.innerHTML = str + ':'; - infoExtLine.appendChild(infoExtSpan); - var infoExtName = document.createElement('input'); - infoExtName.type = 'text'; - infoExtName.style.width = '100px'; - infoExtName.value = str2 || ''; - infoExtLine.appendChild(infoExtName); - return infoExtLine; - }; - var authorExtLine = createExtLine('扩展作者', get.connectNickname()); - var introExtLine = createExtLine('扩展描述'); - var versionExtLine = createExtLine('扩展版本', '1.0'); - var diskExtLine = createExtLine('网盘地址'); - var forumExtLine = createExtLine('讨论地址'); - var okExtLine = createExtLine(true); - - game.editExtension = function (name) { - page.currentExtension = name || '无名扩展'; - inputExtName.value = page.currentExtension; - if (name && lib.extensionPack[name]) { - authorExtLine.querySelector('input').value = lib.extensionPack[name].author || ''; - introExtLine.querySelector('input').value = lib.extensionPack[name].intro || ''; - diskExtLine.querySelector('input').value = lib.extensionPack[name].diskURL || ''; - forumExtLine.querySelector('input').value = lib.extensionPack[name].forumURL || ''; - versionExtLine.querySelector('input').value = lib.extensionPack[name].version || ''; - } - else { - authorExtLine.querySelector('input').value = get.connectNickname() || ''; - introExtLine.querySelector('input').value = ''; - diskExtLine.querySelector('input').value = ''; - forumExtLine.querySelector('input').value = ''; - versionExtLine.querySelector('input').value = '1.0'; - } - if (name) { - inputExtName.disabled = true; - buttonConfirm.style.display = 'none'; - inputExtSpan.style.display = 'none'; - inputExtName.style.display = 'none'; - buttonRename.style.display = ''; - buttonSave.style.display = ''; - buttonReset.style.display = ''; - buttonExport.style.display = ''; - } - else { - inputExtName.disabled = false; - buttonConfirm.style.display = ''; - inputExtSpan.innerHTML = '扩展名:'; - inputExtName.style.width = '80px'; - inputExtName.style.textAlign = 'center'; - inputExtSpan.style.display = ''; - inputExtName.style.display = ''; - buttonRename.style.display = 'none'; - buttonSave.style.display = 'none'; - buttonReset.style.display = 'none'; - buttonExport.style.display = 'none'; - } - - dashboard.style.display = ''; - - exportExtLine.style.display = 'none'; - shareExtLine.style.display = 'none'; - authorExtLine.style.display = 'none'; - introExtLine.style.display = 'none'; - forumExtLine.style.display = 'none'; - diskExtLine.style.display = 'none'; - versionExtLine.style.display = 'none'; - okExtLine.style.display = 'none'; - inputExtLine.style.padding = '10px'; - dash1.reset(name); - dash2.reset(name); - dash3.reset(name); - dash4.reset(name); - dash1.link.classList.remove('active'); - dash2.link.classList.remove('active'); - dash3.link.classList.remove('active'); - dash4.link.classList.remove('active'); - var active = node.parentNode.querySelector('.active'); - if (active === node) { - return; - } - active.classList.remove('active'); - active.link.remove(); - node.classList.add('active'); - rightPane.appendChild(node.link); - } - var processExtension = function (exportext) { - if (page.currentExtension) { - if (page.currentExtension != inputExtName.value && !exportext) { - game.removeExtension(page.currentExtension); - } - } - inputExtName.disabled = true; - setTimeout(function () { - var ext = {}; - var config = null, help = null; - for (var i in dash4.content) { - try { - if (i == 'content' || i == 'precontent') { - eval('ext[i]=' + dash4.content[i]); - if (typeof ext[i] != 'function') { - throw ('err'); - } - else { - ext[i] = ext[i].toString(); - } - } - else { - eval(dash4.content[i]); - eval('ext[i]=' + i); - if (ext[i] == null || typeof ext[i] != 'object') { - throw ('err'); - } - else { - ext[i] = JSON.stringify(ext[i]); - } - } - } - catch (e) { - console.log(e); - delete ext[i]; - } - } - page.currentExtension = inputExtName.value || '无名扩展'; - var str = '{name:"' + page.currentExtension + '"'; - for (var i in ext) { - str += ',' + i + ':' + ext[i]; - } - dash2.content.pack.list = []; - for (var i = 0; i < dash2.pile.childNodes.length; i++) { - dash2.content.pack.list.push(dash2.pile.childNodes[i].link); - } - str += ',package:' + get.stringify({ - //替换die audio,加上扩展名 - character: (pack => { - var character = pack.character; - for (var key in character) { - var info = character[key]; - if (Array.isArray(info[4])) { - var tag = info[4].find(tag => /^die:.+$/.test(tag)); - if (tag) { - info[4].remove(tag); - if (typeof game.readFile == 'function') { - info[4].push('die:ext:' + page.currentExtension + '/audio/die/' + tag.slice(tag.lastIndexOf('/') + 1)); - } else { - info[4].push('die:db:extension-' + page.currentExtension + ':audio/die/' + tag.slice(tag.lastIndexOf('/') + 1)); - } - } - } - } - return pack; - })(dash1.content.pack), - card: dash2.content.pack, - skill: dash3.content.pack, - intro: introExtLine.querySelector('input').value || '', - author: authorExtLine.querySelector('input').value || '', - diskURL: diskExtLine.querySelector('input').value || '', - forumURL: forumExtLine.querySelector('input').value || '', - version: versionExtLine.querySelector('input').value || '', - }); - var files = { character: [], card: [], skill: [], audio: [] }; - for (var i in dash1.content.image) { - files.character.push(i); - } - for (var i in dash1.content.audio) { - files.audio.push('audio/die/' + i); - } - for (var i in dash2.content.image) { - files.card.push(i); - } - for (var i in dash3.content.audio) { - files.skill.push(i); - } - str += ',files:' + JSON.stringify(files); - str += '}'; - var extension = { 'extension.js': 'game.import("extension",function(lib,game,ui,get,ai,_status){return ' + str + '})' }; - for (var i in dash1.content.image) { - extension[i] = dash1.content.image[i]; - } - for (var i in dash1.content.audio) { - extension['audio/die/' + i] = dash1.content.audio[i]; - } - for (var i in dash2.content.image) { - extension[i] = dash2.content.image[i]; - } - var callback = () => { - if (exportext) { - var proexport = function () { - game.importExtension(extension, null, page.currentExtension, { - intro: introExtLine.querySelector('input').value || '', - author: authorExtLine.querySelector('input').value || '', - netdisk: diskExtLine.querySelector('input').value || '', - forum: forumExtLine.querySelector('input').value || '', - version: versionExtLine.querySelector('input').value || '', - }); - }; - if (game.getFileList) { - game.getFileList('extension/' + page.currentExtension, function (folders, files) { - extension._filelist = files; - proexport(); - }); - } - else { - proexport(); - } - } - else { - game.importExtension(extension, function () { - exportExtLine.style.display = ''; - }); - } - }; - //兼容网页版情况 - if (typeof game.readFile == "function") { - game.readFile('LICENSE', function (data) { - extension['LICENSE'] = data; - game.writeFile(data, 'extension/' + page.currentExtension, 'LICENSE', function () { }) - callback(); - }, function () { - alert('许可证文件丢失,无法导出扩展'); - }); - } else { - callback(); - } - }, 500); - }; - var buttonConfirm = document.createElement('button'); - buttonConfirm.innerHTML = '确定'; - buttonConfirm.style.marginLeft = '5px'; - buttonConfirm.onclick = buttonConfirmOnclick; - inputExtLine.appendChild(buttonConfirm); - var buttonRename = document.createElement('button'); - buttonRename.innerHTML = '选项'; - buttonRename.style.marginLeft = '2px'; - buttonRename.style.marginRight = '2px'; - buttonRename.style.display = 'none'; - buttonRename.onclick = function () { - inputExtSpan.style.display = ''; - inputExtName.style.display = ''; - authorExtLine.style.display = ''; - introExtLine.style.display = ''; - forumExtLine.style.display = ''; - diskExtLine.style.display = ''; - versionExtLine.style.display = ''; - okExtLine.style.display = 'block'; - inputExtLine.style.padding = '20px 10px 10px 10px'; - inputExtName.disabled = false; - buttonRename.style.display = 'none'; - buttonSave.style.display = 'none'; - buttonReset.style.display = 'none'; - buttonExport.style.display = 'none'; - inputExtSpan.innerHTML = '扩展名称:'; - inputExtName.style.width = '100px'; - inputExtName.style.textAlign = ''; - - dashboard.style.display = 'none'; - }; - inputExtLine.appendChild(buttonRename); - var buttonReset = document.createElement('button'); - buttonReset.innerHTML = '重置'; - buttonReset.style.marginLeft = '2px'; - buttonReset.style.marginRight = '2px'; - buttonReset.style.display = 'none'; - buttonReset.onclick = function () { - if (confirm('当前扩展将被清除,是否确定?')) { - game.editExtension(); - } - }; - inputExtLine.appendChild(buttonReset); - var buttonSave = document.createElement('button'); - buttonSave.innerHTML = '保存'; - buttonSave.style.marginLeft = '2px'; - buttonSave.style.marginRight = '2px'; - buttonSave.style.display = 'none'; - buttonSave.onclick = function () { - dash1.link.classList.remove('active'); - dash2.link.classList.remove('active'); - dash3.link.classList.remove('active'); - dash4.link.classList.remove('active'); - processExtension(); - }; - inputExtLine.appendChild(buttonSave); - var buttonExport = document.createElement('button'); - buttonExport.innerHTML = '导出'; - buttonExport.style.marginLeft = '2px'; - buttonExport.style.marginRight = '2px'; - buttonExport.style.display = 'none'; - buttonExport.onclick = function () { - function oldExport() { - processExtension(true); - if (lib.config.show_extensionshare) { - shareExtLine.style.display = ''; - } - } - if (typeof game.readFile == 'function' && - window.noname_shijianInterfaces && - typeof window.noname_shijianInterfaces.shareExtensionWithPassWordAsync == 'function' && - confirm('是否使用诗笺版自带的导出功能来导出扩展?')) { - const extName = inputExtName.value; - if (!extName) { - alert('未检测到扩展名,将使用无名杀自带的导出功能'); - oldExport(); - return; - } - game.readFile(`extension/${extName}/extension.js`, () => { - const pwd = prompt("请输入压缩包密码,不设密码直接点确定"); - let result; - if (pwd === '' || pwd === null) { - window.noname_shijianInterfaces.shareExtensionAsync(extName); - } else { - window.noname_shijianInterfaces.shareExtensionWithPassWordAsync(extName, pwd); - } - }, () => { - alert('未检测到扩展文件,将使用无名杀自带的导出功能'); - oldExport(); - }); - } else { - oldExport(); - } - }; - inputExtLine.appendChild(buttonExport); - var exportExtLine = ui.create.div(pageboard); - exportExtLine.style.display = 'none'; - exportExtLine.style.width = 'calc(100% - 40px)'; - exportExtLine.style.textAlign = 'left'; - exportExtLine.style.marginBottom = '5px'; - if (lib.device == 'ios') { - exportExtLine.innerHTML = '已保存。退出游戏并重新打开后生效×'; - exportExtLine.querySelectorAll('span')[0].onclick = function () { - exportExtLine.style.display = 'none'; - }; - } - else { - exportExtLine.innerHTML = '重启后生效。立即重启×'; - exportExtLine.querySelectorAll('span')[0].onclick = game.reload; - exportExtLine.querySelectorAll('span')[1].onclick = function () { - exportExtLine.style.display = 'none'; - }; - } - - - var shareExtLine = ui.create.div(pageboard); - shareExtLine.style.display = 'none'; - shareExtLine.style.width = 'calc(100% - 40px)'; - shareExtLine.style.textAlign = 'left'; - shareExtLine.style.marginBottom = '5px'; - shareExtLine.innerHTML = '已导出扩展。分享扩展×'; - shareExtLine.querySelectorAll('span')[0].onclick = function () { - //这个链接404了 - //game.open('https://tieba.baidu.com/p/5439380222'); - //无名杀贴吧首页 - game.open('https://tieba.baidu.com/f?ie=utf-8&kw=%E6%97%A0%E5%90%8D%E6%9D%80'); - }; - shareExtLine.querySelectorAll('span')[1].onclick = function () { - shareExtLine.style.display = 'none'; - }; - - var dashboard = ui.create.div(pageboard); - var clickDash = function () { - ui.create.templayer(); - pageboard.hide(); - this.link.show(); - if (this.link.init) { - this.link.init(); - } - }; - var createDash = function (str1, str2, node) { - var dash = ui.create.div('.menubutton.large.dashboard'); - dashboard.appendChild(dash); - page.appendChild(node); - dash.link = node; - node.link = dash; - dash.listen(clickDash); - lib.setScroll(node); - ui.create.div('', str1, dash); - ui.create.div('', str2, dash); - }; - var dash1 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - var currentButton = null; - page.init = function () { - if (!page.querySelector('.button.character')) { - toggle.classList.add('on'); - newCharacter.style.display = ''; - } - }; - var updateButton = function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - editnode.classList.add('disabled'); - return; - } - name = name.split('|'); - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { - if (lib.character[name] || page.content.pack.character[name]) { - editnode.classList.add('disabled'); - return; - } - } - } - else { - if (lib.character[name] || page.content.pack.character[name]) { - editnode.classList.add('disabled'); - return; - } - } - if (!fakeme.image) { - if (!page.content.image[name + '.jpg']) { - editnode.classList.add('disabled'); - return; - } - } - editnode.classList.remove('disabled'); - }; - var clickButton = async () => { - if (currentButton == this) { - resetEditor(); - return; - } - resetEditor(); - currentButton = this; - toggle.classList.add('on'); - newCharacter.style.display = ''; - fakeme.classList.add('inited'); - fakeme.style.backgroundImage = this.style.backgroundImage; - if (page.content.pack.translate[this.link] != this.link) { - newCharacter.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; - } - else { - newCharacter.querySelector('.new_name').value = this.link; - } - var info = page.content.pack.character[this.link]; - newCharacter.querySelector('.new_hp').value = info[2]; - sexes.value = info[0]; - groups.value = info[1]; - if (info[4]) { - for (var i = 0; i < options.childNodes.length - 1; i++) { - if (options.childNodes[i].lastChild && info[4].includes(options.childNodes[i].lastChild.name)) { - options.childNodes[i].lastChild.checked = true; - } - else if (options.childNodes[i].lastChild) { - options.childNodes[i].lastChild.checked = false; - } - } - for (var i = 0; i < info[4].length; i++) { - if (info[4][i].startsWith('des:')) { - newCharacter.querySelector('.new_des').value = info[4][i].slice(4); - } - if (info[4][i].startsWith('die:')) { - var dieaudionode = newCharacter.querySelector('.die_audio'); - dieaudionode.file = { - name: info[4][i].slice(info[4][i].lastIndexOf('/') + 1) - }; - await new Promise((resolve) => { - if (typeof game.readFile == 'function') { - game.readFile(info[4][i].slice(4).replace('ext:', 'extension/'), arraybuffer => { - dieaudionode.arrayBuffer = arraybuffer; - resolve(); - }, () => { - console.warn(`未找到${info[4][i].slice(4).replace('ext:', 'extension/')}阵亡配音`); - resolve(); - }); - } else { - game.getDB('image', info[4][i].slice(7)).then(octetStream => { - dieaudionode.arrayBuffer = octetStream; - resolve(); - }, () => { - console.warn(`未找到${info[4][i].slice(4)}阵亡配音`); - resolve(); - }); - } - }); - } - } - } - - var skills = info[3]; - for (var i = 0; i < skills.length; i++) { - var node = document.createElement('button'); - node.skill = skills[i]; - node.onclick = deletenode; - node.innerHTML = lib.translate[skills[i]]; - skillList.firstChild.appendChild(node); - } - - toggle.innerHTML = '编辑武将
>
'; - editnode.innerHTML = '编辑武将'; - editnode.classList.remove('disabled'); - delnode.innerHTML = '删除'; - delnode.button = this; - }; - var createButton = function (name, image) { - var button = ui.create.div('.button.character'); - button.link = name; - button.image = image; - button.style.backgroundImage = 'url(' + image + ')'; - button.style.backgroundSize = 'cover'; - button.listen(clickButton); - button.classList.add('noclick'); - button.nodename = ui.create.div(button, '.name', get.verticalStr(page.content.pack.translate[name])); - button.nodename.style.top = '8px'; - page.insertBefore(button, page.childNodes[1]); - } - page.reset = function (name) { - resetEditor(); - var buttons = page.querySelectorAll('.button.character'); - var list = []; - for (var i = 0; i < buttons.length; i++) { - list.push(buttons[i]); - } - for (var i = 0; i < list.length; i++) { - list[i].remove(); - } - if (lib.extensionPack[name]) { - page.content.pack = lib.extensionPack[name].character || { - character: {}, - translate: {} - }; - page.content.image = {}; - for (var i in page.content.pack.character) { - var file = i + '.jpg'; - var loadImage = function (file, data) { - var img = new Image(); - img.crossOrigin = 'Anonymous'; - img.onload = function () { - var canvas = document.createElement('CANVAS'); - var ctx = canvas.getContext('2d'); - var dataURL; - canvas.height = this.height; - canvas.width = this.width; - ctx.drawImage(this, 0, 0); - canvas.toBlob(function (blob) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - page.content.image[file] = e.target.result; - }; - fileReader.readAsArrayBuffer(blob, "UTF-8"); - }); - }; - img.src = data; - } - if (game.download) { - var url = lib.assetURL + 'extension/' + name + '/' + file; - createButton(i, url); - if (lib.device == 'ios' || lib.device == 'android') { - window.resolveLocalFileSystemURL(lib.assetURL + 'extension/' + name, function (entry) { - entry.getFile(file, {}, function (fileEntry) { - fileEntry.file(function (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - page.content.image[file] = e.target.result; - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - }); - }); - }); - } - else { - loadImage(file, url); - } - } - else game.getDB('image', `extension-${name}:${file}`).then(value => { - createButton(i, value); - loadImage(file, value); - }); - } - } - else { - page.content = { - pack: { - character: {}, - translate: {} - }, - image: {}, - audio: {} - }; - toggle.classList.add('on'); - newCharacter.style.display = ''; - } - }; - ui.create.div('.config.more', '
返回', page, function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }); - page.content = { - pack: { - character: {}, - translate: {} - }, - image: {}, - audio: {} - }; - var newCharacter; - var toggle = ui.create.div('.config.more.on', '创建武将
>
', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - newCharacter.style.display = ''; - } - else { - newCharacter.style.display = 'none'; - } - }); - var resetEditor = function () { - currentButton = null; - toggle.classList.remove('on'); - newCharacter.style.display = 'none'; - fakeme.classList.remove('inited'); - delete fakeme.image; - delete fakeme.image64; - fakeme.style.backgroundImage = ''; - var inputs = newCharacter.querySelectorAll('input'); - for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; - } - inputs = newCharacter.querySelectorAll('textarea'); - for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; - } - skillList.firstChild.innerHTML = ''; - toggle.innerHTML = '创建武将
>
'; - editnode.innerHTML = '创建武将'; - editnode.classList.add('disabled'); - delnode.innerHTML = '取消'; - delete delnode.button; - } - - newCharacter = ui.create.div('.new_character', page); - var fakeme = ui.create.div('.avatar', newCharacter); - - var input = document.createElement('input'); - input.type = 'file'; - input.accept = 'image/*'; - input.className = 'fileinput'; - input.onchange = function () { - var fileToLoad = input.files[0]; - if (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { - var data = fileLoadedEvent.target.result; - fakeme.style.backgroundImage = 'url(' + data + ')'; - fakeme.image64 = data; - fakeme.classList.add('inited'); - var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { - fakeme.image = fileLoadedEvent.target.result; - updateButton(); - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - }; - fileReader.readAsDataURL(fileToLoad, "UTF-8"); - } - } - fakeme.appendChild(input); - - ui.create.div('.select_avatar', '选择头像', fakeme); - - ui.create.div('.indent', '姓名:', newCharacter).style.paddingTop = '8px'; - ui.create.div('.indent', '介绍:', newCharacter).style.paddingTop = '8px'; - ui.create.div('.indent', '体力:', newCharacter).style.paddingTop = '8px'; - newCharacter.querySelector('input.new_name').onblur = updateButton; - var sexes = ui.create.selectlist([ - ['male', '男'], - ['female', '女'], - ['double', '双性'], - ['none', '无'] - ], null, ui.create.div('.indent', '性别:', newCharacter)); - var grouplist = lib.group.map((group, i) => [lib.group[i], get.translation(lib.group[i])]); - var groups = ui.create.selectlist(grouplist, null, ui.create.div('.indent', '势力:', newCharacter)); - var dieaudio = ui.create.div('.die_audio', newCharacter, { textAlign: 'left' }); - var dieaudiolabel = ui.create.node('label', '阵亡配音:', dieaudio); - var dieaudioUpload = dieaudio.appendChild(document.createElement('input')); - dieaudioUpload.type = 'file'; - dieaudioUpload.accept = 'audio/*'; - dieaudioUpload.style.width = 'calc(100% - 100px)'; - dieaudioUpload.onchange = function () { - var fileToLoad = dieaudioUpload.files[0]; - if (fileToLoad) { - console.log(fileToLoad); - var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { - var data = fileLoadedEvent.target.result; - var blob = new Blob([data]); - dieaudio.file = fileToLoad; - dieaudio.arrayBuffer = data; - dieaudio.blob = blob; - var new_name = newCharacter.querySelector('input.new_name'); - dieaudioUpload.style.display = 'none'; - dieaudiopreview.style.display = - dieaudiocancel.style.display = ''; - dieaudiotag.src = window.URL.createObjectURL(blob); - }; - fileReader.readAsArrayBuffer(fileToLoad); - } - }; - var dieaudiotag = ui.create.node('audio', dieaudio); - var dieaudiopreview = ui.create.node('button', dieaudio, () => { - if (dieaudiotag.error) { - alert('您使用的客户端不支持预览此音频!') - } else dieaudiotag.play(); - }); - dieaudiopreview.innerHTML = '播放'; - dieaudiopreview.style.display = 'none'; - var dieaudiocancel = ui.create.node('button', dieaudio, () => { - dieaudiopreview.style.display = 'none'; - dieaudiocancel.style.display = 'none'; - if (dieaudio.blob) { - window.URL.revokeObjectURL(dieaudio.blob); - dieaudiotag.src = null; - delete dieaudio.file; - delete dieaudio.arrayBuffer; - delete dieaudio.blob; - } - dieaudioUpload.value = ''; - dieaudioUpload.style.display = ''; - }); - dieaudiocancel.innerHTML = '取消'; - dieaudiocancel.style.display = 'none'; - var options = ui.create.div('.add_skill.options', '主公BOSS仅点将可用
隐匿技
', newCharacter); - var addSkill = ui.create.div('.add_skill', '添加技能
', newCharacter); - var list = []; - for (var i in lib.character) { - if (lib.character[i][3].length) { - list.push([i, lib.translate[i]]); - } - } - list.sort(function (a, b) { - a = a[0]; b = b[0]; - var aa = a, bb = b; - if (aa.includes('_')) { - aa = aa.slice(aa.indexOf('_') + 1); - } - if (bb.includes('_')) { - bb = bb.slice(bb.indexOf('_') + 1); - } - if (aa != bb) { - return aa > bb ? 1 : -1; - } - return a > b ? 1 : -1; - }); - var list2 = []; - var skills = lib.character[list[0][0]][3]; - for (var i = 0; i < skills.length; i++) { - list2.push([skills[i], lib.translate[skills[i]]]); - } - list.unshift(['current_extension', '此扩展']); - - var selectname = ui.create.selectlist(list, list[1], addSkill); - page.selectname = selectname; - selectname.onchange = function () { - skillopt.innerHTML = ''; - if (this.value == 'current_extension') { - for (var i in dash3.content.pack.skill) { - var option = document.createElement('option'); - option.value = i; - option.innerHTML = dash3.content.pack.translate[i]; - skillopt.appendChild(option); - } - } - else { - var skills = lib.character[this.value][3]; - for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); - option.value = skills[i]; - option.innerHTML = lib.translate[skills[i]]; - skillopt.appendChild(option); - } - } - }; - selectname.style.maxWidth = '85px'; - var skillopt = ui.create.selectlist(list2, list2[0], addSkill); - skillopt.style.maxWidth = '60px'; - page.skillopt = skillopt; - var addSkillButton = document.createElement('button'); - addSkillButton.innerHTML = '添加'; - addSkill.appendChild(addSkillButton); - page.addSkillButton = addSkillButton; - var deletenode = function () { - this.remove(); - } - addSkillButton.onclick = function () { - for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { - if (skillList.firstChild.childNodes[i].skill == skillopt.value) return alert(selectname.value == 'current_extension' ? '此扩展还未添加技能' : '此武将没有技能可添加'); - } - //无技能时 - if (!skillopt.value || skillopt.childElementCount == 0) return; - var node = document.createElement('button'); - node.skill = skillopt.value; - node.onclick = deletenode; - for (var i = 0; i < skillopt.childElementCount; i++) { - if (skillopt.childNodes[i].value == skillopt.value) { - node.innerHTML = skillopt.childNodes[i].innerHTML; break; - } - } - skillList.firstChild.appendChild(node); - }; - var createSkillButton = document.createElement('button'); - createSkillButton.innerHTML = '创建'; - createSkillButton.style.marginLeft = '3px'; - addSkill.appendChild(createSkillButton); - createSkillButton.onclick = function () { - ui.create.templayer(); - page.hide(); - dash3.show(); - dash3.fromchar = 'add'; - dash3.toggle.classList.add('on'); - dash3.newSkill.style.display = ''; - }; - page.updateSkill = function () { - for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { - var node = skillList.firstChild.childNodes[i]; - var skill = skillList.firstChild.childNodes[i].skill; - if (dash3.content.pack.skill[skill]) { - node.innerHTML = dash3.content.pack.translate[skill]; - } - else if (lib.skill[skill]) { - node.innerHTML = lib.translate[skill]; - } - else { - node.remove(); i--; - } - } - }; - var skillList = ui.create.div('.skill_list', newCharacter); - ui.create.div(skillList); - var editnode = ui.create.div('.menubutton.large.disabled', '创建武将', ui.create.div(skillList), function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - alert('请填写武将名\n提示:武将名格式为id+|+中文名,其中id必须惟一'); - return; - } - name = name.split('|'); - var translate = name[1] || name[0]; - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { - if (lib.character[name] || page.content.pack.character[name]) { - alert('武将名与现有武将重复,请更改\n提示:武将名格式为id+|+中文名,其中id必须惟一'); - return; - } - page.content.image[name + '.jpg'] = page.content.image[currentButton.link + '.jpg']; - delete page.content.image[currentButton.link + '.jpg']; - delete page.content.pack.character[currentButton.link]; - delete page.content.pack.translate[currentButton.link]; - currentButton.link = name; - } - } - else { - if (lib.character[name] || page.content.pack.character[name]) { - alert('武将名与现有武将重复,请更改\n提示:武将名格式为id+|+中文名,其中id必须惟一'); - return; - } - } - if (fakeme.image) { - page.content.image[name + '.jpg'] = fakeme.image; - } - else { - if (!page.content.image[name + '.jpg']) { - alert('请选择武将头像'); - return; - } - } - var hp = page.querySelector('input.new_hp').value; - //体力支持‘Infinity,∞,无限’表示无限 - if (['Infinity', '∞', '无限'].includes(hp)) hp = Infinity; - else if (hp.indexOf('/') == -1) hp = parseInt(hp) || 1; - var skills = []; - for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { - skills.add(skillList.firstChild.childNodes[i].skill); - } - var tags = []; - for (var i = 0; i < options.childNodes.length - 1; i++) { - if (options.childNodes[i].lastChild && options.childNodes[i].lastChild.checked) { - tags.push(options.childNodes[i].lastChild.name); - } - } - if (tags.includes('boss')) { - tags.add('bossallowed'); - } - var des = page.querySelector('input.new_des').value; - if (des) { - tags.add('des:' + des); - } - //阵亡配音 - if (dieaudio.file && dieaudio.arrayBuffer) { - var audioname = name + dieaudio.file.name.slice(dieaudio.file.name.indexOf('.')); - tags.add(`die:${typeof game.readFile == 'function' ? 'ext' : 'db'}:audio/die/${audioname}`); - page.content.audio[audioname] = dieaudio.arrayBuffer; - } - - page.content.pack.translate[name] = translate; - page.content.pack.character[name] = [sexes.value, groups.value, hp, skills, tags]; - if (this.innerHTML == '创建武将') { - createButton(name, fakeme.image64); - } - else if (currentButton) { - if (fakeme.image64) { - currentButton.image = fakeme.image64; - currentButton.style.backgroundImage = 'url(' + fakeme.image64 + ')'; - } - currentButton.nodename.innerHTML = get.verticalStr(translate); - } - resetEditor(); - dash1.link.classList.add('active'); - }); - var delnode = ui.create.div('.menubutton.large', '取消', editnode.parentNode, function () { - if (this.innerHTML == '删除') { - this.button.remove(); - var name = this.button.link; - delete dash1.content.pack.character[name]; - delete dash1.content.pack.translate[name]; - delete dash1.content.image[name]; - delete dash1.content.audio[name]; - dash1.link.classList.add('active'); - } - resetEditor(); - }); - delnode.style.marginLeft = '13px'; - - return page; - }()); - var dash2 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - var currentButton = null; - page.init = function () { - if (!page.querySelector('.button.card')) { - toggle.classList.add('on'); - newCard.style.display = ''; - } - }; - var updateButton = function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - editnode.classList.add('disabled'); - return; - } - name = name.split('|'); - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { - if (lib.card[name] || page.content.pack.card[name]) { - editnode.classList.add('disabled'); - return; - } - } - } - else { - if (lib.card[name] || page.content.pack.card[name]) { - editnode.classList.add('disabled'); - return; - } - } - if (!fakeme.image && !fakeme.classList.contains('inited')) { - editnode.classList.add('disabled'); - return; - } - editnode.classList.remove('disabled'); - }; - var clickButton = function () { - if (currentButton == this) { - resetEditor(); - return; - } - resetEditor(); - currentButton = this; - toggle.classList.add('on'); - newCard.style.display = ''; - fakeme.classList.add('inited'); - delete fakeme.image; - delete fakeme.image64; - if (this.classList.contains('fullskin')) { - fakeme.imagenode.style.backgroundImage = this.imagenode.style.backgroundImage; - fakeme.classList.add('fullskin'); - } - else { - fakeme.style.backgroundImage = this.style.backgroundImage; - fakeme.classList.remove('fullskin'); - } - if (page.content.pack.translate[this.link] != this.link) { - newCard.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; - } - else { - newCard.querySelector('.new_name').value = this.link; - } - newCard.querySelector('.new_description').value = page.content.pack.translate[this.link + '_info']; - var info = page.content.pack.card[this.link]; - container.code = 'card=' + get.stringify(info); - - toggle.innerHTML = '编辑卡牌
>
'; - editnode.innerHTML = '编辑卡牌'; - editnode.classList.remove('disabled'); - delnode.innerHTML = '删除'; - delnode.button = this; - } - var createButton = function (name, image, fullskin) { - var button = ui.create.div('.button.card'); - button.link = name; - button.image = image; - button.imagenode = ui.create.div('.image', button); - if (image) { - if (fullskin) { - button.imagenode.style.backgroundImage = 'url(' + image + ')'; - button.style.backgroundImage = ''; - button.style.backgroundSize = ''; - button.classList.add('fullskin'); - } - else { - button.style.color = 'white'; - button.style.textShadow = 'black 0 0 2px'; - button.imagenode.style.backgroundImage = ''; - button.style.backgroundImage = 'url(' + image + ')'; - button.style.backgroundSize = 'cover'; - } - } - button.listen(clickButton); - button.classList.add('noclick'); - button.nodename = ui.create.div(button, '.name', get.verticalStr(page.content.pack.translate[name])); - page.insertBefore(button, page.childNodes[1]); - } - page.reset = function (name) { - resetEditor(); - var buttons = page.querySelectorAll('.button.card'); - var list = []; - for (var i = 0; i < buttons.length; i++) { - list.push(buttons[i]); - } - for (var i = 0; i < list.length; i++) { - list[i].remove(); - } - if (lib.extensionPack[name]) { - page.content.pack = lib.extensionPack[name].card || { - card: {}, - translate: {} - }; - page.content.image = {}; - if (Array.isArray(page.content.pack.list)) { - for (var i = 0; i < page.content.pack.list.length; i++) { - var card = page.content.pack.list[i]; - var node = document.createElement('button'); - node.innerHTML = page.content.pack.translate[card[2]] + ' ' + lib.translate[card[0]] + card[1]; - node.name = card[2]; - node.link = card; - pile.appendChild(node); - node.onclick = function () { - this.remove(); - } - } - } - for (var i in page.content.pack.card) { - var file; - var fullskin = page.content.pack.card[i].fullskin ? true : false; - if (fullskin) { - file = i + '.png'; - } - else { - file = i + '.jpg'; - } - var loadImage = function (file, data) { - var img = new Image(); - img.crossOrigin = 'Anonymous'; - img.onload = function () { - var canvas = document.createElement('CANVAS'); - var ctx = canvas.getContext('2d'); - var dataURL; - canvas.height = this.height; - canvas.width = this.width; - ctx.drawImage(this, 0, 0); - canvas.toBlob(function (blob) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - page.content.image[file] = e.target.result; - }; - fileReader.readAsArrayBuffer(blob, "UTF-8"); - }); - }; - img.src = data; - } - if (game.download) { - var url = lib.assetURL + 'extension/' + name + '/' + file; - createButton(i, url, fullskin); - if (lib.device == 'ios' || lib.device == 'android') { - window.resolveLocalFileSystemURL(lib.assetURL + 'extension/' + name, function (entry) { - entry.getFile(file, {}, function (fileEntry) { - fileEntry.file(function (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - page.content.image[file] = e.target.result; - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - }); - }); - }); - } - else { - loadImage(file, url); - } - } - else game.getDB('image', `extension-${name}:${file}`).then(value => { - createButton(i, value, fullskin); - loadImage(file, value); - }); - } - } - else { - page.content = { - pack: { - card: {}, - translate: {} - }, - image: {} - }; - toggle.classList.add('on'); - newCard.style.display = ''; - } - updatePile(); - }; - ui.create.div('.config.more.margin-bottom', '
返回', page, function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }); - page.content = { - pack: { - card: {}, - translate: {}, - list: [] - }, - image: {} - }; - var newCard; - var toggle = ui.create.div('.config.more.on', '创建卡牌
>
', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - newCard.style.display = ''; - } - else { - newCard.style.display = 'none'; - } - }); - var resetEditor = function () { - currentButton = null; - toggle.classList.remove('on'); - newCard.style.display = 'none'; - fakeme.classList.remove('inited'); - fakeme.classList.add('fullskin'); - delete fakeme.image; - delete fakeme.image64; - fakeme.style.backgroundImage = ''; - fakeme.imagenode.style.backgroundImage = ''; - var inputs = newCard.querySelectorAll('input'); - for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; - } - toggle.innerHTML = '创建卡牌
>
'; - editnode.innerHTML = '创建卡牌'; - editnode.classList.add('disabled'); - delnode.innerHTML = '取消'; - delete delnode.button; - container.code = 'card={\n \n}\n\n/*\n示例:\ncard={\n type:"basic",\n enable:true,\n filterTarget:true,\n content:function(){\n target.draw()\n },\n ai:{\n order:1,\n result:{\n target:1\n }\n }\n}\n此例的效果为目标摸一张牌\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - } - - newCard = ui.create.div('.new_character', page); - newCard.style.height = '173px'; - var fakeme = ui.create.div('.card.fullskin', newCard); - - var input = document.createElement('input'); - input.type = 'file'; - input.accept = 'image/*'; - input.className = 'fileinput'; - input.onchange = function () { - var fileToLoad = input.files[0]; - if (fileToLoad) { - var fileReader = new FileReader(); - var fullimage = (fileToLoad.name.includes('.jpg')); - fileReader.onload = function (fileLoadedEvent) { - var data = fileLoadedEvent.target.result; - if (fullimage) { - fakeme.imagenode.style.backgroundImage = ''; - fakeme.style.backgroundImage = 'url(' + data + ')'; - fakeme.classList.remove('fullskin'); - } - else { - fakeme.style.backgroundImage = ''; - fakeme.imagenode.style.backgroundImage = 'url(' + data + ')'; - fakeme.classList.add('fullskin'); - } - fakeme.image64 = data; - fakeme.classList.add('inited'); - var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { - fakeme.image = fileLoadedEvent.target.result; - updateButton(); - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - }; - fileReader.readAsDataURL(fileToLoad, "UTF-8"); - } - } - fakeme.appendChild(input); - - fakeme.imagenode = ui.create.div('.image', fakeme); - ui.create.div('.name', '选择背景', fakeme); - - ui.create.div('.indent', '名称:', newCard).style.paddingTop = '8px'; - ui.create.div('.indent', '描述:', newCard).style.paddingTop = '6px'; - newCard.querySelector('input.new_name').onblur = updateButton; - var codeButton = document.createElement('button'); - newCard.appendChild(codeButton); - codeButton.innerHTML = '编辑代码'; - codeButton.style.left = '123px'; - codeButton.style.top = '66px'; - codeButton.style.position = 'absolute'; - - var citeButton = document.createElement('button'); - newCard.appendChild(citeButton); - citeButton.innerHTML = '引用代码'; - citeButton.style.left = '123px'; - citeButton.style.top = '90px'; - citeButton.style.position = 'absolute'; - citeButton.onclick = function () { - codeButton.style.display = 'none'; - citeButton.style.display = 'none'; - selectname.style.display = ''; - confirmcontainer.style.display = ''; - } - - var list = []; - for (var i in lib.card) { - if (lib.translate[i]) { - list.push([i, lib.translate[i]]); - } - } - list.sort(function (a, b) { - a = a[0]; b = b[0]; - var aa = a, bb = b; - if (aa.includes('_')) { - aa = aa.slice(aa.indexOf('_') + 1); - } - if (bb.includes('_')) { - bb = bb.slice(bb.indexOf('_') + 1); - } - if (aa != bb) { - return aa > bb ? 1 : -1; - } - return a > b ? 1 : -1; - }); - var selectname = ui.create.selectlist(list, list[0], newCard); - selectname.style.left = '123px'; - selectname.style.top = '66px'; - selectname.style.position = 'absolute'; - selectname.style.display = 'none'; - - var confirmcontainer = ui.create.div(newCard); - confirmcontainer.style.left = '123px'; - confirmcontainer.style.top = '90px'; - confirmcontainer.style.position = 'absolute'; - confirmcontainer.style.display = 'none'; - - var citeconfirm = document.createElement('button'); - citeconfirm.innerHTML = '引用'; - confirmcontainer.appendChild(citeconfirm); - citeconfirm.onclick = function () { - codeButton.style.display = ''; - citeButton.style.display = ''; - selectname.style.display = 'none'; - confirmcontainer.style.display = 'none'; - container.code = 'card=' + get.stringify(lib.card[selectname.value]); - codeButton.onclick.call(codeButton); - if (lib.translate[selectname.value + '_info']) { - newCard.querySelector('input.new_description').value = lib.translate[selectname.value + '_info']; - } - } - - var citecancel = document.createElement('button'); - citecancel.innerHTML = '取消'; - citecancel.style.marginLeft = '3px'; - confirmcontainer.appendChild(citecancel); - citecancel.onclick = function () { - codeButton.style.display = ''; - citeButton.style.display = ''; - selectname.style.display = 'none'; - confirmcontainer.style.display = 'none'; - } - - codeButton.onclick = function () { - var node = container; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); - window.saveNonameInput = saveInput; - if (node.aced) { - ui.window.appendChild(node); - node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { - ui.window.appendChild(node); - if (!node.textarea) { - var textarea = document.createElement('textarea'); - editor.appendChild(textarea); - node.textarea = textarea; - lib.setScroll(textarea); - } - node.textarea.value = node.code; - } - else { - if (!window.CodeMirror) { - import('../../game/codemirror.js').then(() => { - lib.codeMirrorReady(node, editor); - }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { - lib.codeMirrorReady(node, editor); - } - } - } - - var container = ui.create.div('.popup-container.editor'); - var saveInput = function () { - var code; - if (container.editor) { - code = container.editor.getValue(); - } - else if (container.textarea) { - code = container.textarea.value; - } - try { - var card = null; - eval(code); - if (card == null || typeof card != 'object') { - throw ('err'); - } - } - catch (e) { - if (e == 'err') { - alert('代码格式有错误,请对比示例代码仔细检查'); - } - else { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); - } - window.focus(); - if (container.editor) { - container.editor.focus(); - } - else if (container.textarea) { - container.textarea.focus(); - } - return; - } - dash2.link.classList.add('active'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); - container.delete(); - container.code = code; - delete window.saveNonameInput; - }; - var editor = ui.create.editor(container, saveInput); - container.code = 'card={\n \n}\n\n/*\n示例:\ncard={\n type:"basic",\n enable:true,\n filterTarget:true,\n content:function(){\n target.draw()\n },\n ai:{\n order:1,\n result:{\n target:1\n }\n }\n}\n此例的效果为目标摸一张牌\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - - var editnode = ui.create.div('.menubutton.large.new_card.disabled', '创建卡牌', newCard, function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - alert('请填写卡牌名\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); - return; - } - name = name.split('|'); - var translate = name[1] || name[0]; - var info = page.querySelector('input.new_description').value; - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { - if (lib.card[name] || page.content.pack.card[name]) { - alert('卡牌名与现有卡牌重复,请更改\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); - return; - } - var extname; - if (currentButton.classList.contains('fullskin')) { - extname = '.png'; - } - else { - extname = '.jpg'; - } - page.content.image[name + extname] = page.content.image[currentButton.link + extname]; - delete page.content.image[currentButton.link + extname]; - delete page.content.pack.card[currentButton.link]; - delete page.content.pack.translate[currentButton.link]; - delete page.content.pack.translate[currentButton.link + '_info']; - currentButton.link = name; - } - } - else { - if (lib.card[name] || page.content.pack.card[name]) { - alert('卡牌名与现有卡牌重复,请更改\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); - return; - } - } - if (fakeme.image) { - if (fakeme.classList.contains('fullskin')) { - page.content.image[name + '.png'] = fakeme.image; - delete page.content.image[name + '.jpg']; - } - else { - page.content.image[name + '.jpg'] = fakeme.image; - delete page.content.image[name + '.png']; - } - } - else if (!fakeme.classList.contains('inited')) { - alert('请选择一个卡牌背景'); - return; - } - page.content.pack.translate[name] = translate; - page.content.pack.translate[name + '_info'] = info; - try { - var card = null; - eval(container.code); - if (card == null || typeof card != 'object') { - throw ('err'); - } - page.content.pack.card[name] = card; - } - catch (e) { - page.content.pack.card[name] = {}; - } - if (fakeme.classList.contains('inited')) { - if (fakeme.classList.contains('fullskin')) { - page.content.pack.card[name].fullskin = true; - delete page.content.pack.card[name].fullimage; - } - else { - page.content.pack.card[name].fullimage = true; - delete page.content.pack.card[name].fullskin; - } - } - if (this.innerHTML == '创建卡牌') { - createButton(name, fakeme.image64, fakeme.classList.contains('fullskin')); - } - else if (currentButton) { - if (fakeme.image64) { - if (fakeme.classList.contains('fullskin')) { - currentButton.style.color = ''; - currentButton.style.textShadow = ''; - currentButton.imagenode.style.backgroundImage = 'url(' + fakeme.image64 + ')'; - currentButton.style.backgroundImage = ''; - currentButton.style.backgroundSize = ''; - currentButton.classList.add('fullskin'); - } - else { - currentButton.style.color = 'white'; - currentButton.style.textShadow = 'black 0 0 2px'; - currentButton.imagenode.style.backgroundImage = ''; - currentButton.style.backgroundImage = 'url(' + fakeme.image64 + ')'; - currentButton.style.backgroundSize = 'cover'; - currentButton.classList.remove('fullskin'); - } - } - currentButton.nodename.innerHTML = get.verticalStr(translate); - } - resetEditor(); - updatePile(); - dash2.link.classList.add('active'); - }); - var delnode = ui.create.div('.menubutton.large.new_card_delete', '取消', editnode.parentNode, function () { - if (this.innerHTML == '删除') { - this.button.remove(); - var name = this.button.link; - delete dash2.content.pack.card[name]; - delete dash2.content.pack.translate[name]; - delete dash2.content.pack.translate[name + '_info']; - delete dash2.content.image[name]; - updatePile(); - dash2.link.classList.add('active'); - } - resetEditor(); - }); - - var editPile; - var toggle2 = ui.create.div('.config.more', '编辑牌堆
>
', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - editPile.style.display = ''; - } - else { - editPile.style.display = 'none'; - } - }); - - editPile = ui.create.div('.edit_pile', page); - editPile.style.display = 'none'; - - - var cardpileadd = ui.create.div('.config.toggle.cardpilecfg.cardpilecfgadd', editPile); - var pile = ui.create.div(editPile); - page.pile = pile; - var cardpileaddname = document.createElement('select'); - var updatePile = function () { - cardpileaddname.innerHTML = ''; - var list = []; - var list2 = []; - for (var i in page.content.pack.card) { - list.push([i, page.content.pack.translate[i]]); - list2.push(i); - } - if (list.length) { - toggle2.style.display = ''; - if (toggle2.classList.contains('on')) { - editPile.style.display = ''; - } - else { - editPile.style.display = 'none'; - } - for (var i = 0; i < list.length; i++) { - var option = document.createElement('option'); - option.value = list[i][0]; - option.innerHTML = list[i][1]; - cardpileaddname.appendChild(option); - } - for (var i = 0; i < pile.childNodes.length; i++) { - if (!list2.includes(pile.childNodes[i].name)) { - pile.childNodes[i].remove(); i--; - } - } - } - else { - toggle2.style.display = 'none'; - editPile.style.display = 'none'; - pile.innerHTML = ''; - } - }; - updatePile(); - cardpileadd.appendChild(cardpileaddname); - cardpileaddname.style.width = '75px'; - cardpileaddname.style.marginRight = '2px'; - cardpileaddname.style.marginLeft = '-1px'; - var cardpileaddsuit = ui.create.selectlist([ - ['heart', '红桃'], - ['diamond', '方片'], - ['club', '梅花'], - ['spade', '黑桃'], - ], null, cardpileadd); - cardpileaddsuit.style.width = '53px'; - cardpileaddsuit.style.marginRight = '2px'; - var cardpileaddnumber = ui.create.selectlist([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 - ], null, cardpileadd); - cardpileaddnumber.style.width = '43px'; - cardpileaddnumber.style.marginRight = '2px'; - var button = document.createElement('button'); - button.innerHTML = '确定'; - button.style.width = '40px'; - button.onclick = function () { - var card = [ - cardpileaddsuit.value, - cardpileaddnumber.value, - cardpileaddname.value, - ]; - var node = document.createElement('button'); - node.innerHTML = page.content.pack.translate[card[2]] + ' ' + lib.translate[card[0]] + card[1]; - node.name = card[2]; - node.link = card; - pile.appendChild(node); - node.onclick = function () { - this.remove(); - } - }; - cardpileadd.appendChild(button); - cardpileadd.style.whiteSpace = 'nowrap'; - cardpileadd.style.position = 'relative'; - cardpileadd.style.right = '-4px'; - - return page; - }()); - var dash3 = (function () { - var page = ui.create.div('.hidden.menu-buttons.new_skill'); - var updateButton = function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - editnode.classList.add('disabled'); - return; - } - name = name.split('|'); - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { - if (lib.skill[name] || page.content.pack.skill[name]) { - editnode.classList.add('disabled'); - return; - } - } - } - else { - if (lib.skill[name] || page.content.pack.skill[name]) { - editnode.classList.add('disabled'); - return; - } - } - editnode.classList.remove('disabled'); - }; - page.init = function () { - if (!page.querySelector('.menubutton:not(.large)')) { - toggle.classList.add('on'); - newSkill.style.display = ''; - } - }; - page.reset = function (name) { - resetEditor(); - var buttons = page.querySelectorAll('.menubutton:not(.large)'); - var list = []; - for (var i = 0; i < buttons.length; i++) { - list.push(buttons[i]); - } - for (var i = 0; i < list.length; i++) { - list[i].remove(); - } - if (lib.extensionPack[name]) { - page.content.pack = lib.extensionPack[name].skill || { - skill: {}, - translate: {} - }; - page.content.audio = {}; - for (var i in page.content.pack.skill) { - createButton(i); - } - dash1.updateSkill(); - } - else { - page.content = { - pack: { - skill: {}, - translate: {} - }, - audio: {} - }; - toggle.classList.add('on'); - newSkill.style.display = ''; - } - }; - ui.create.div('.config.more.margin-bottom', '
返回', page, function () { - ui.create.templayer(); - page.hide(); - if (page.fromchar) { - dash1.show(); - delete page.fromchar; - } - else { - pageboard.show(); - } - }); - var currentButton = null; - var clickButton = function () { - if (currentButton == this) { - resetEditor(); - return; - } - resetEditor(); - currentButton = this; - toggle.classList.add('on'); - newSkill.style.display = ''; - if (page.content.pack.translate[this.link] != this.link) { - newSkill.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; - } - else { - newSkill.querySelector('.new_name').value = this.link; - } - newSkill.querySelector('.new_description').value = page.content.pack.translate[this.link + '_info']; - var info = page.content.pack.skill[this.link]; - container.code = 'skill=' + get.stringify(Object.defineProperty({ ...info }, '_priority', { enumerable: false, writable: true, configurable: true })); - toggle.innerHTML = '编辑技能
>
'; - editnode.innerHTML = '编辑技能'; - editnode.classList.remove('disabled'); - delnode.button = this; - delnode.innerHTML = '删除'; - } - var createButton = function (name) { - var button = ui.create.div('.menubutton'); - button.link = name; - button.innerHTML = page.content.pack.translate[name]; - button.listen(clickButton); - page.insertBefore(button, page.childNodes[1]); - } - var newSkill; - var toggle = ui.create.div('.config.more.on', '创建技能
>
', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - newSkill.style.display = ''; - } - else { - newSkill.style.display = 'none'; - } - }); - page.toggle = toggle; - var resetEditor = function () { - currentButton = null; - toggle.classList.remove('on'); - newSkill.style.display = 'none'; - var inputs = newSkill.querySelectorAll('input'); - for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; - } - var inputs = newSkill.querySelectorAll('textarea'); - for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; - } - toggle.innerHTML = '创建技能
>
'; - editnode.innerHTML = '创建技能'; - editnode.classList.add('disabled'); - delnode.innerHTML = '取消'; - delete delnode.button; - container.code = 'skill={\n \n}\n\n/*\n示例:\nskill={\n trigger:{player:"phaseJieshuBegin"},\n frequent:true,\n content:function(){\n player.draw()\n }\n}\n此例为闭月代码\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - if (page.fromchar == 'add') { - page.fromchar = true; - } - } - - newSkill = ui.create.div('.new_character.new_skill', page); - page.newSkill = newSkill; - var namenode = ui.create.div('.config', '名称:', newSkill); - var descnode = ui.create.div('.config', '描述:', newSkill); - namenode.querySelector('input.new_name').onblur = updateButton; - var commandline = ui.create.div('.config', newSkill); - var editbutton = document.createElement('button'); - editbutton.innerHTML = '编辑代码'; - commandline.appendChild(editbutton); - editbutton.onclick = function () { - var node = container; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); - window.saveNonameInput = saveInput; - if (node.aced) { - ui.window.appendChild(node); - node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { - ui.window.appendChild(node); - if (!node.textarea) { - var textarea = document.createElement('textarea'); - editor.appendChild(textarea); - node.textarea = textarea; - lib.setScroll(textarea); - } - node.textarea.value = node.code; - } - else { - if (!window.CodeMirror) { - import('../../game/codemirror.js').then(() => { - lib.codeMirrorReady(node, editor); - }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { - lib.codeMirrorReady(node, editor); - } - } - } - - var container = ui.create.div('.popup-container.editor'); - var saveInput = function () { - var code; - if (container.editor) { - code = container.editor.getValue(); - } - else if (container.textarea) { - code = container.textarea.value; - } - try { - var skill = null; - eval(code); - if (skill == null || typeof skill != 'object') { - throw ('err'); - } - } - catch (e) { - if (e == 'err') { - alert('代码格式有错误,请对比示例代码仔细检查'); - } - else { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); - } - window.focus(); - if (container.editor) { - container.editor.focus(); - } - else if (container.textarea) { - container.textarea.focus(); - } - return; - } - dash3.link.classList.add('active'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); - container.delete(); - container.code = code; - delete window.saveNonameInput; - }; - var editor = ui.create.editor(container, saveInput); - container.code = 'skill={\n \n}\n\n/*\n示例:\nskill={\n trigger:{player:"phaseJieshuBegin"},\n frequent:true,\n content:function(){\n player.draw()\n }\n}\n此例为闭月代码\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - - var citebutton = document.createElement('button'); - citebutton.innerHTML = '引用代码'; - commandline.appendChild(citebutton); - citebutton.onclick = function () { - editbutton.style.display = 'none'; - citebutton.style.display = 'none'; - selectname.style.display = ''; - skillopt.style.display = ''; - addSkillButton.style.display = ''; - cancelSkillButton.style.display = ''; - } - - var list = []; - for (var i in lib.character) { - if (lib.character[i][3].length) { - list.push([i, lib.translate[i]]); - } - } - list.sort(function (a, b) { - a = a[0]; b = b[0]; - var aa = a, bb = b; - if (aa.includes('_')) { - aa = aa.slice(aa.indexOf('_') + 1); - } - if (bb.includes('_')) { - bb = bb.slice(bb.indexOf('_') + 1); - } - if (aa != bb) { - return aa > bb ? 1 : -1; - } - return a > b ? 1 : -1; - }); - list.push(['others', '其它']); - var list2 = []; - var skills = lib.character[list[0][0]][3]; - for (var i = 0; i < skills.length; i++) { - list2.push([skills[i], lib.translate[skills[i]]]); - } - var selectname = ui.create.selectlist(list, list[0], commandline); - var list3 = []; - for (var i in lib.skill) { - if (i != 'global' && !get.is.empty(lib.skill[i]) && !lib.skilllist.includes(i)) { - list3.push(i); - } - } - list3.sort(function (a, b) { - return a > b ? 1 : -1; - }); - selectname.onchange = function () { - var skills; - skillopt.innerHTML = ''; - if (this.value == 'others') { - skills = list3; - for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); - option.value = skills[i]; - option.innerHTML = skills[i]; - skillopt.appendChild(option); - } - } - else { - skills = lib.character[this.value][3]; - for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); - option.value = skills[i]; - option.innerHTML = lib.translate[skills[i]]; - skillopt.appendChild(option); - } - } - }; - selectname.style.display = 'none'; - selectname.style.maxWidth = '80px'; - var skillopt = ui.create.selectlist(list2, list2[0], commandline); - skillopt.style.display = 'none'; - skillopt.style.maxWidth = '60px'; - var addSkillButton = document.createElement('button'); - addSkillButton.style.display = 'none'; - addSkillButton.innerHTML = '引用'; - commandline.appendChild(addSkillButton); - addSkillButton.onclick = function () { - editbutton.style.display = ''; - citebutton.style.display = ''; - selectname.style.display = 'none'; - skillopt.style.display = 'none'; - addSkillButton.style.display = 'none'; - cancelSkillButton.style.display = 'none'; - container.code = 'skill=' + get.stringify(Object.defineProperty({ ...lib.skill[skillopt.value] }, '_priority', { enumerable: false, writable: true, configurable: true })); - editbutton.onclick.call(editbutton); - if (lib.translate[skillopt.value + '_info']) { - newSkill.querySelector('input.new_description').value = lib.translate[skillopt.value + '_info']; - } - } - var cancelSkillButton = document.createElement('button'); - cancelSkillButton.style.display = 'none'; - cancelSkillButton.innerHTML = '取消'; - commandline.appendChild(cancelSkillButton); - cancelSkillButton.onclick = function () { - editbutton.style.display = ''; - citebutton.style.display = ''; - selectname.style.display = 'none'; - skillopt.style.display = 'none'; - addSkillButton.style.display = 'none'; - cancelSkillButton.style.display = 'none'; - } - - var editnode = ui.create.div('.menubutton.large.new_skill.disabled', '创建技能', function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - alert('请填写技能名\n提示:技能名格式为id+|+中文名,其中id必须惟一'); - return; - } - name = name.split('|'); - var translate = name[1] || name[0]; - var info = page.querySelector('input.new_description').value; - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { - if (lib.skill[name] || page.content.pack.skill[name]) { - alert('技能名与现有技能重复,请更改\n提示:技能名格式为id+|+中文名,其中id必须惟一'); - return; - } - delete page.content.pack.skill[currentButton.link]; - delete page.content.pack.translate[currentButton.link]; - delete page.content.pack.translate[currentButton.link + '_info']; - currentButton.link = name; - } - } - else { - if (lib.skill[name] || page.content.pack.skill[name]) { - alert('技能名与现有技能重复,请更改\n提示:技能名格式为id+|+中文名,其中id必须惟一'); - return; - } - } - page.content.pack.translate[name] = translate; - page.content.pack.translate[name + '_info'] = info; - try { - var skill = null; - eval(container.code); - if (skill == null || typeof skill != 'object') { - throw ('err'); - } - page.content.pack.skill[name] = skill; - } - catch (e) { - page.content.pack.skill[name] = {}; - } - dash1.selectname.value = 'current_extension'; - dash1.selectname.onchange.call(dash1.selectname); - if (this.innerHTML == '创建技能') { - createButton(name); - if (page.fromchar == 'add') { - ui.create.templayer(); - page.hide(); - dash1.show(); - dash1.skillopt.value = name; - dash1.addSkillButton.onclick(); - delete page.fromchar; - } - } - else if (currentButton) { - currentButton.innerHTML = translate; - } - resetEditor(); - dash3.link.classList.add('active'); - dash1.updateSkill(); - }, newSkill); - var delnode = ui.create.div('.menubutton.large.new_card_delete', '取消', editnode.parentNode, function () { - if (this.innerHTML == '删除') { - this.button.remove(); - var name = this.button.link; - delete dash3.content.pack.skill[name]; - delete dash3.content.pack.translate[name]; - delete dash3.content.pack.translate[name + '_info']; - dash3.link.classList.add('active'); - if (get.is.empty(dash3.content.pack.skill)) { - dash1.selectname.value = dash1.selectname.childNodes[1].value; - } - dash1.selectname.onchange.call(dash1.selectname); - dash1.updateSkill(); - resetEditor(); - } - else if (page.fromchar == 'add') { - ui.create.templayer(); - page.hide(); - dash1.show(); - delete page.fromchar; - setTimeout(resetEditor, 600); - } - else { - resetEditor(); - } - }); - - page.content = { - pack: { - skill: {}, - translate: {} - }, - audio: {} - }; - return page; - }()); - var dash4 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - ui.create.div('.config.more.margin-bottom', '
返回', page, function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }); - page.reset = function (name) { - page.content = {}; - if (lib.extensionPack[name]) { - for (var i in dashes) { - dashes[i].node.code = ''; - } - for (var i in lib.extensionPack[name].code) { - switch (typeof lib.extensionPack[name].code[i]) { - case 'function': page.content[i] = lib.extensionPack[name].code[i].toString(); break; - case 'object': page.content[i] = i + '=' + get.stringify(lib.extensionPack[name].code[i]); break; - } - } - for (var i in page.content) { - dashes[i].node.code = page.content[i] || ''; - } - } - else { - dashes.content.node.code = 'function(config,pack){\n \n}\n\n/*\n函数执行时机为游戏数据加载之后、界面加载之前\n参数1扩展选项(见选项代码);参数2为扩展定义的武将、卡牌和技能等(可在此函数中修改)\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - dashes.precontent.node.code = 'function(){\n \n}\n\n/*\n函数执行时机为游戏数据加载之前,且不受禁用扩展的限制\n除添加模式外请慎用\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - dashes.config.node.code = 'config={\n \n}\n\n/*\n示例:\nconfig={\n switcher_example:{\n name:"示例列表选项",\n init:"3",\n item:{"1":"一","2":"二","3":"三"}\n },\n toggle_example:{\n name:"示例开关选项",\n init:true\n }\n}\n此例中传入的主代码函数的默认参数为{switcher_example:"3",toggle_example:true}\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - dashes.help.node.code = 'help={\n \n}\n\ns/*\n示例:\nhelp={\n "帮助条目":"
  • 列表1-条目1
  • 列表1-条目2
  1. 列表2-条目1
  2. 列表2-条目2"\n}\n帮助内容将显示在菜单-选项-帮助中\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - } - }; - var dashes = {}; - var createCode = function (str1, str2, sub, func, link, str) { - var dash = ui.create.div('.menubutton.large.dashboard'); - dashes[link] = dash; - sub.appendChild(dash); - dash.listen(func); - dash.link = link; - ui.create.div('', str1, dash); - ui.create.div('', str2, dash); - var container = ui.create.div('.popup-container.editor'); - var saveInput = function () { - var code; - if (container.editor) { - code = container.editor.getValue(); - } - else if (container.textarea) { - code = container.textarea.value; - } - try { - if (link == 'content' || link == 'precontent') { - var func = null; - eval('func=' + code); - if (typeof func != 'function') { - throw ('err'); - } - } - else if (link == 'config') { - var config = null; - eval(code); - if (config == null || typeof config != 'object') { - throw ('err'); - } - } - else if (link == 'help') { - var help = null; - eval(code); - if (help == null || typeof help != 'object') { - throw ('err'); - } - } - } - catch (e) { - if (e == 'err') { - alert('代码格式有错误,请对比示例代码仔细检查'); - } - else { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); - } - window.focus(); - if (container.editor) { - container.editor.focus(); - } - else if (container.textarea) { - container.textarea.focus(); - } - return; - } - dash4.link.classList.add('active'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); - container.delete(); - container.code = code; - page.content[link] = code; - delete window.saveNonameInput; - }; - var editor = ui.create.editor(container, saveInput); - container.code = str; - dash.editor = editor; - dash.node = container; - dash.saveInput = saveInput; - page.content[link] = str; - }; - var clickCode = function () { - var node = this.node; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); - window.saveNonameInput = this.saveInput; - if (node.aced) { - ui.window.appendChild(node); - node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { - ui.window.appendChild(node); - if (!node.textarea) { - var textarea = document.createElement('textarea'); - this.editor.appendChild(textarea); - node.textarea = textarea; - lib.setScroll(textarea); - } - node.textarea.value = node.code; - } - else { - if (!window.CodeMirror) { - import('../../game/codemirror.js').then(() => { - lib.codeMirrorReady(node, editor); - }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { - lib.codeMirrorReady(node, this.editor); - } - } - }; - page.content = {} - createCode('主', '主代码', page, clickCode, 'content', 'function(config,pack){\n \n}\n\n/*\n函数执行时机为游戏数据加载之后、界面加载之前\n参数1扩展选项(见选项代码);参数2为扩展定义的武将、卡牌和技能等(可在此函数中修改)\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); - createCode('启', '启动代码', page, clickCode, 'precontent', 'function(){\n \n}\n\n/*\n函数执行时机为游戏数据加载之前,且不受禁用扩展的限制\n除添加模式外请慎用\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); - createCode('选', '选项代码', page, clickCode, 'config', 'config={\n \n}\n\n/*\n示例:\nconfig={\n switcher_example:{\n name:"示例列表选项",\n init:"3",\n item:{"1":"一","2":"二","3":"三"}\n },\n toggle_example:{\n name:"示例开关选项",\n init:true\n }\n}\n此例中传入的主代码函数的默认参数为{switcher_example:"3",toggle_example:true}\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); - createCode('帮', '帮助代码', page, clickCode, 'help', 'help={\n \n}\n\n/*\n示例:\nhelp={\n "帮助条目":"
    • 列表1-条目1
    • 列表1-条目2
    1. 列表2-条目1
    2. 列表2-条目2"\n}\n帮助内容将显示在菜单-选项-帮助中\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); - - return page; - }()); - createDash('将', '编辑武将', dash1); - createDash('卡', '编辑卡牌', dash2); - createDash('技', '编辑技能', dash3); - createDash('码', '编辑代码', dash4); - }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - (function () { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '获取扩展', start.firstChild, clickMode); - node.mode = 'get'; - var _thisUpdate = false; - node.update = function () { - _thisUpdate = true; - }; - node._initLink = function () { - node.link = page; - page.listen(function () { - if (!page.currenttimeout) { - var active = page.querySelector('.videonode.current'); - if (active) { - active.classList.remove('current'); - } - } - }); - var importextensionexpanded = false; - page.style.paddingBottom = '10px'; - var importExtension; - var extensionNode = ui.create.div('.config.more', '导入扩展
      >
      ', page, function () { - if (importextensionexpanded) { - this.classList.remove('on'); - importExtension.style.display = 'none'; - } - else { - this.classList.add('on'); - importExtension.style.display = ''; - } - importextensionexpanded = !importextensionexpanded; - }); - importExtension = ui.create.div('.new_character.export.import', page); - importExtension.style.marginLeft = '5px'; - importExtension.style.marginTop = '5px'; - importExtension.style.marginBottom = '5px'; - importExtension.style.display = 'none'; - importExtension.style.width = '100%'; - importExtension.style.textAlign = 'left'; - ui.create.div('', '', importExtension); - ui.create.div('.config', '修改下载地址', page, function () { - alert('您可以在“设置→通用→获取扩展地址”中,修改下载扩展时所采用的地址。') - }) - - var extensionURL; - var source = lib.config.extension_sources, index = lib.config.extension_source; - if (source && source[index]) extensionURL = source[index]; - else extensionURL = lib.updateURL.replace(/noname/g, 'noname-extension') + '/master/'; - - var reloadnode = ui.create.div('.config.toggle.pointerdiv', '重新启动', page, game.reload); - reloadnode.style.display = 'none'; - var placeholder = ui.create.div('.config.toggle', page); - placeholder.style.height = 0; - placeholder.style.marginTop = '5px'; - - importExtension.firstChild.lastChild.onclick = function () { - const fileToLoad = this.previousSibling.files[0]; - if (!fileToLoad) return; - new Promise((resolve, reject) => { - const fileReader = new FileReader(); - fileReader.onerror = reject; - fileReader.onload = resolve; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - }).then(progressEvent => { - if (game.importExtension(progressEvent.target.result, () => { - extensionNode.innerHTML = '导入成功,3秒后将重启'; - new Promise(resolve => setTimeout(resolve, 1000)).then(() => { - extensionNode.innerHTML = '导入成功,2秒后将重启'; - return new Promise(resolve => setTimeout(resolve, 1000)); - }).then(() => { - extensionNode.innerHTML = '导入成功,1秒后将重启'; - return new Promise(resolve => setTimeout(resolve, 1000)); - }).then(game.reload); - }) !== false) importExtension.style.display = 'none'; - }); - } - - var clickExtension = function () { - var active = this.parentNode.querySelector('.videonode.current'); - if (active && active != this) { - active.classList.remove('current'); - } - this.classList.add('current'); - clearTimeout(page.currenttimeout); - page.currenttimeout = setTimeout(function () { - delete page.currenttimeout; - }, 200); - }; - var downloadExtension = function (e) { - if ((this.innerHTML != '下载扩展' && this.innerHTML != '更新扩展') || !window.JSZip) return; - this.classList.remove('update'); - if (e) { - e.stopPropagation(); - } - node.updated = true; - var that = this; - var list = []; - var size = parseFloat(this.info.size) || 0; - if (size) { - if (this.info.size.includes('MB')) { - size *= 1024 * 1024; - } - else if (this.info.size.includes('KB')) { - size *= 1024; - } - } - - this.innerHTML = '正在下载
      正在下载
      '; - this.classList.add('nopointer'); - this.classList.add('button-downloading'); - var progress = ui.create.div('.button-progress', this); - ui.create.div(progress); - var url = extensionURL + this.info.name + '.zip'; - var onprogress = function (byte, total) { - if (total) { - size = total; - } - if (byte == -1) { - byte = size; - } - progress.firstChild.style.width = Math.round(100 * byte / size) + '%'; - }; - var files = this.info.files || []; - for (var i = 0; i < files.length; i++) { - files[i] = 'extension/' + that.info.name + '/' + files[i]; - } - game.checkFileList(files, function () { - files.unshift('extension/' + that.info.name + '/extension.js'); - for (var i = 0; i < files.length; i++) { - files[i] = extensionURL + that.info.name + '/' + files[i].slice(10 + that.info.name.length + 1); - } - var n1 = 0, n2 = files.length; - game.multiDownload(files, function () { - n1++; - onprogress(n1, n2); - }, function (e) { - game.print('下载失败:' + e.source); - }, function () { - onprogress(-1); - _status.importingExtension = true; - window.game = game; - lib.init.js(lib.assetURL + 'extension/' + that.info.name, 'extension', function () { - if (!lib.config.dev) delete window.game; - if (game.importedPack) { - var extname = game.importedPack.name; - if (lib.config.extensions.includes(extname)) { - game.removeExtension(extname, true); - } - lib.config.extensions.add(extname); - game.saveConfig('extensions', lib.config.extensions); - game.saveConfig('extension_' + extname + '_enable', true); - game.saveConfig('extension_' + extname + '_version', that.info.version); - for (var i in game.importedPack.config) { - if (game.importedPack.config[i] && 'init' in game.importedPack.config[i]) { - game.saveConfig('extension_' + extname + '_' + i, game.importedPack.config[i].init); - } - } - reloadnode.style.display = ''; - that.childNodes[0].innerHTML = '安装成功'; - that.childNodes[1].innerHTML = '安装成功'; - that.classList.remove('active'); - that.classList.remove('highlight'); - delete game.importedPack; - } - else { - that.innerHTML = '安装失败'; - that.classList.add('nopointer'); - } - _status.importingExtension = false; - }, function () { - that.innerHTML = '下载失败'; - that.classList.add('nopointer'); - _status.importingExtension = false; - }); - }, function (current) { - return 'extension/' + current.slice(extensionURL.length); - }); - }); - }; - - node.update = function () { - if (this.updated) return; - if (!window.JSZip) { - lib.init.js(lib.assetURL + 'game', 'jszip'); - } - var toremove = []; - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].classList.contains('menubutton') || page.childNodes[i].classList.contains('loading')) { - toremove.push(page.childNodes[i]); - } - } - for (var i = 0; i < toremove.length; i++) { - toremove[i].remove(); - } - - var loading = ui.create.div('.loading.config.toggle', '载入中...', page); - var loaded = function () { - var list = []; - var extension = window.extension; - for (var i in extension) { - extension[i].name = i; - list.push(extension[i]); - } - list.randomSort(); - delete window.extension; - loading.style.display = 'none'; - for (var i = 0; i < list.length; i++) { - var node = ui.create.div('.videonode.menubutton.extension.large', page, clickExtension); - ui.create.div('.caption', list[i].name, node); - ui.create.div('.text.author', '作者:' + list[i].author + '(' + list[i].size + ')', node); - ui.create.div('.text', '更新日期:' + list[i].date, node); - ui.create.div('.text', list[i].intro, node); - var download = ui.create.div('.menubutton.text.active', '下载扩展', node.firstChild, { 'zIndex': '5' }); - if (game.download) { - if (list[i].netdisk) { - var linknode = ui.create.div('.text', node); - ui.create.node('span.hrefnode', '网盘链接', function () { - game.open(this.link); - }, linknode).link = list[i].netdisk; - if (list[i].forum) { - ui.create.node('span', linknode).style.marginRight = '10px'; - ui.create.node('span.hrefnode', '参与讨论', function () { - game.open(this.link); - }, linknode).link = list[i].forum; - } - } - else if (list[i].forum) { - var linknode = ui.create.div('.text', node); - ui.create.node('span.hrefnode', '参与讨论', function () { - game.open(this.link); - }, linknode).link = list[i].forum; - } - download.listen(downloadExtension); - if (lib.config.extensions.includes(list[i].name)) { - download.classList.remove('active'); - if (lib.extensionPack[list[i].name] && lib.extensionPack[list[i].name].version == list[i].version) { - download.classList.add('transparent2'); - download.classList.remove('active'); - download.innerHTML = '已安装'; - } - else if (lib.config['extension_' + list[i].name + '_version'] != list[i].version) { - download.innerHTML = '更新扩展'; - download.classList.add('highlight'); - download.classList.add('update'); - } - else { - download.classList.add('transparent2'); - download.classList.remove('active'); - download.innerHTML = '已安装'; - } - } - download.info = list[i]; - } - else { - if (list[i].forum) { - var linknode = ui.create.div('.text', node); - ui.create.node('span', linknode); - ui.create.node('span.hrefnode', '参与讨论', function () { - game.open(this.link); - }, linknode).link = list[i].forum; - } - download.listen(function () { - game.open(this.link); - }); - download.link = list[i].netdisk; - } - } - }; - window.extension = {}; - fetch(`${extensionURL}catalog.js`, { - referrerPolicy: 'no-referrer' - }).then(response => response.text()).then(eval).then(loaded).catch(reason => { - console.log(reason); - delete window.extension; - loading.innerHTML = '连接失败:' + (reason instanceof Error ? reason.message : String(reason)); - }); - }; - if (_thisUpdate) node.update(); - }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - var active = start.firstChild.querySelector('.active'); - if (!active) { - active = start.firstChild.firstChild; - active.classList.add('active'); - } - if (!active.link) active._initLink(); - rightPane.appendChild(active.link); - updateNodes(); - }()); - - (function () { - if (connectMenu) return; - var start = menuxpages.shift(); - var rightPane = start.lastChild; - var cheatButton = ui.create.div('.menubutton.round.highlight', '作', start); - cheatButton.style.display = 'none'; - var runButton = ui.create.div('.menubutton.round.highlight', '执', start); - runButton.style.display = 'none'; - var clearButton = ui.create.div('.menubutton.round.highlight', '清', start); - clearButton.style.display = 'none'; - clearButton.style.left = '275px'; - var playButton = ui.create.div('.menubutton.round.highlight.hidden', '播', start); - playButton.style.display = 'none'; - playButton.style.left = '215px'; - playButton.style.transition = 'opacity 0.3s'; - var deleteButton = ui.create.div('.menubutton.round.highlight.hidden', '删', start); - deleteButton.style.display = 'none'; - deleteButton.style.left = '275px'; - deleteButton.style.transition = 'opacity 0.3s'; - var saveButton = ui.create.div('.menubutton.round.highlight.hidden', '存', start); - saveButton.style.display = 'none'; - saveButton.style.transition = 'opacity 0.3s'; - - - var clickMode = function () { - if (this.classList.contains('off')) return; - var active = this.parentNode.querySelector('.active'); - if (active === this) { - return; - } - if (active) { - active.classList.remove('active'); - active.link.remove(); - } - active = this; - this.classList.add('active'); - if (this.link) rightPane.appendChild(this.link); - else { - this._initLink(); - rightPane.appendChild(this.link); - } - if (this.type == 'cheat') { - cheatButton.style.display = ''; - } - else { - cheatButton.style.display = 'none'; - } - if (this.type == 'cmd') { - runButton.style.display = ''; - clearButton.style.display = ''; - } - else { - runButton.style.display = 'none'; - clearButton.style.display = 'none'; - } - if (this.type == 'video') { - playButton.style.display = ''; - saveButton.style.display = ''; - deleteButton.style.display = ''; - } - else { - playButton.style.display = 'none'; - saveButton.style.display = 'none'; - deleteButton.style.display = 'none'; - } - }; - - ui.click.consoleMenu = function () { - ui.click.menuTab('其它'); - clickMode.call(ui.commandnode); - }; - //更新菜单有本体函数赋值,就不要懒加载了 - (function () { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '更新', start.firstChild, clickMode); - node.link = page; - page.classList.add('menu-help'); - var ul = document.createElement('ul'); - var li1 = document.createElement('li'); - var li2 = document.createElement('li'); - var li3 = document.createElement('li'); - const trimURL = url => { - const updateURLS = lib.updateURLS; - for (const key in updateURLS) { - const updateURL = updateURLS[key]; - if (url == updateURL) return lib.configMenu.general.config.update_link.item[key]; - } - let index = url.indexOf('://'); - if (index != -1) url = url.slice(index + 3); - index = url.indexOf('/'); - if (index != -1) url = url.slice(0, index); - if (url.length > 15) { - const list = url.split('.'); - if (list.length > 1) list.shift(); - url = list.join('.'); - } - if (url.length > 15) { - const list = url.split('.'); - if (list.length > 1) list.pop(); - url = list.join('.'); - } - return url; - } - li1.innerHTML = '游戏版本:' + lib.version + '

      '; - li2.innerHTML = '素材版本:' + (lib.config.asset_version || '无') + '

      '; - li3.innerHTML = '更新地址:' + trimURL(lib.config.updateURL || lib.updateURL) + '

      '; - li3.style.whiteSpace = 'nowrap'; - li3.style.display = 'none';// coding - - var button1, button2, button3, button4, button5; - - game.checkForUpdate = function (forcecheck, dev) { - if (!dev && button1.disabled) { - return; - } - else if (dev && button3.disabled) { - return; - } - else if (!game.download) { - alert('此版本不支持游戏内更新,请手动更新'); - return; - } - else { - if (dev) { - button3.innerHTML = '正在检查更新'; - } - else { - button1.innerHTML = '正在检查更新'; - } - button3.disabled = true; - button1.disabled = true; - - var goupdate = function (files, update) { - lib.version = update.version; - if (update.dev && !lib.config.debug) { - dev = 'nodev'; - } - lib.init.req('game/source.js', function () { - try { - eval(this.responseText); - if (!window.noname_source_list) { - throw ('err'); - } - } - catch (e) { - alert('更新地址有误'); - console.log(e); - return; - } - - var updates = window.noname_source_list; - delete window.noname_source_list; - if (Array.isArray(files)) { - files.add('game/update.js'); - var files2 = []; - for (var i = 0; i < files.length; i++) { - var str = files[i].indexOf('*'); - if (str != -1) { - str = files[i].slice(0, str); - files.splice(i--, 1); - for (var j = 0; j < updates.length; j++) { - if (updates[j].startsWith(str)) { - files2.push(updates[j]); - } - } - } - } - updates = files.concat(files2); - } - for (var i = 0; i < updates.length; i++) { - if (updates[i].startsWith('theme/') && !updates[i].includes('.css')) { - updates.splice(i--, 1); - } - else if (updates[i].startsWith('node_modules/') && !update.node) { - updates.splice(i--, 1); - } - } - - if (!ui.arena.classList.contains('menupaused')) { - ui.click.configMenu(); - ui.click.menuTab('其它'); - } - var p = button1.parentNode; - button1.remove(); - button3.remove(); - var span = document.createElement('span'); - var n1 = 0; - var n2 = updates.length; - span.innerHTML = '正在下载文件(' + n1 + '/' + n2 + ')'; - p.appendChild(span); - var finish = function () { - span.innerHTML = '游戏更新完毕(' + n1 + '/' + n2 + ')'; - p.appendChild(document.createElement('br')); - var button = document.createElement('button'); - button.innerHTML = '重新启动'; - button.onclick = game.reload; - button.style.marginTop = '8px'; - p.appendChild(button); - } - game.multiDownload(updates, function () { - n1++; - span.innerHTML = '正在下载文件(' + n1 + '/' + n2 + ')'; - }, function (e) { - game.print('下载失败:' + e.source); - }, function () { - setTimeout(finish, 500); - }, null, dev); - }, function () { - alert('更新地址有误'); - }, true); - }; - - lib.init.req('game/update.js', function () { - try { - eval(this.responseText); - if (!window.noname_update) { - throw ('err'); - } - } - catch (e) { - alert('更新地址有误'); - console.log(e); - return; - } - - var update = window.noname_update; - delete window.noname_update; - if (forcecheck === false) { - if (update.version == lib.config.check_version) { - return; - } - } - game.saveConfig('check_version', update.version); - var goon = true; - if (!dev) { - if (update.version.includes('beta') || update.version == lib.version) { - goon = false; - } - } - if (goon) { - var files = null; - var version = lib.version; - if (Array.isArray(update.dev) && dev) { - files = update.dev; - } - else if (Array.isArray(update.files) && update.update && !dev) { - var version1 = version.split('.'); - var version2 = update.update.split('.'); - for (var i = 0; i < version1.length && i < version2.length; i++) { - if (version2[i] > version1[i]) { - files = false; break; - } - else if (version1[i] > version2[i]) { - files = update.files.slice(0); break; - } - } - if (files === null) { - if (version1.length >= version2.length) { - files = update.files.slice(0); - } - } - } - var str; - if (dev) { - str = '开发版仅供测试使用,可能存在风险,是否确定更新?' - } - else { - str = '有新版本' + update.version + '可用,是否下载?'; - } - if (navigator.notification && navigator.notification.confirm) { - var str2; - if (dev) { - str2 = str; - str = '更新到开发版'; - } - else { - str2 = update.changeLog[0]; - for (var i = 1; i < update.changeLog.length; i++) { - if (update.changeLog[i].indexOf('://') == -1) { - str2 += ';' + update.changeLog[i]; - } - } - } - navigator.notification.confirm( - str2, - function (index) { - if (index == 1) { - goupdate(files, update); - } - else { - button1.disabled = false; - button1.innerHTML = '检查游戏更新'; - button3.disabled = false; - button3.innerHTML = '更新到开发版'; - } - }, - str, - ['确定', '取消'] - ); - } - else { - if (confirm(str)) { - goupdate(files, update); - } - else { - button1.disabled = false; - button1.innerHTML = '检查游戏更新'; - button3.disabled = false; - button3.innerHTML = '更新到开发版'; - } - } - } - else { - alert('当前版本已是最新'); - button1.disabled = false; - button1.innerHTML = '检查游戏更新'; - button3.disabled = false; - button3.innerHTML = '更新到开发版'; - } - }, function () { - if (forcecheck === false) { - return; - } - alert('连接失败'); - button1.disabled = false; - button1.innerHTML = '检查游戏更新'; - button3.disabled = false; - button3.innerHTML = '更新到开发版'; - }, true); - } - }; - game.checkForAssetUpdate = function (type) { - if (button2.disabled) { - return; - } - else if (game.download) { - button2.innerHTML = '正在检查更新'; - button2.disabled = true; - lib.init.req('game/asset.js', function () { - try { - eval(this.responseText); - if (!window.noname_asset_list || !window.noname_skin_list) { - throw ('err'); - } - } - catch (e) { - alert('更新地址有误'); - console.log(e); - return; - } - - var updates = window.noname_asset_list; - delete window.noname_asset_list; - var skins = window.noname_skin_list; - delete window.noname_skin_list; - var asset_version = updates.shift(); - - var skipcharacter = [], skipcard = ['tiesuo_mark', 'shield']; - if (!lib.config.asset_full) { - for (var i = 0; i < lib.config.all.sgscharacters.length; i++) { - var pack = lib.characterPack[lib.config.all.sgscharacters[i]]; - for (var j in pack) { - skipcharacter.add(j); - } - } - for (var i = 0; i < lib.config.all.sgscards.length; i++) { - var pack = lib.cardPack[lib.config.all.sgscards[i]]; - if (pack) { - skipcard = skipcard.concat(pack); - } - } - } - for (var i = 0; i < updates.length; i++) { - switch (updates[i].slice(0, 5)) { - case 'image': { - if (!lib.config.asset_full) { - if (!lib.config.asset_image) { - updates.splice(i--, 1); - } - else { - if (updates[i].startsWith('image/character')) { - if (updates[i].indexOf('jun_') != 16 && updates[i].indexOf('gz_') != 16 && !skipcharacter.includes(updates[i].slice(16, updates[i].lastIndexOf('.')))) { - updates.splice(i--, 1); - } - } - else if (updates[i].startsWith('image/card')) { - let cardname = updates[i].slice(11, updates[i].lastIndexOf('.')); - if (lib.card[cardname] && !skipcard.includes(cardname)) { - updates.splice(i--, 1); - } - } - else if (updates[i].startsWith('image/mode/stone')) { - updates.splice(i--, 1); - } - } - } - break; - } - case 'audio': { - if (!lib.config.asset_audio) { - updates.splice(i--, 1); - } - break; - } - case 'font/': { - if (!lib.config.asset_font) { - updates.splice(i--, 1); - } - } - } - } - if (lib.config.asset_skin) { - for (var i in skins) { - for (var j = 1; j <= skins[i]; j++) { - updates.push('image/skin/' + i + '/' + j + '.jpg'); - } - } - } - if (!ui.arena.classList.contains('menupaused')) { - ui.click.configMenu(); - ui.click.menuTab('其它'); - } - - var proceed = function () { - if (updates.length == 0) { - game.print(updates); - game.saveConfig('asset_version', asset_version); - alert('素材已是最新'); - button2.disabled = false; - button2.innerHTML = '检查素材更新'; - return; - } - var p = button2.parentNode; - button2.remove(); - var span = document.createElement('span'); - span.style.whiteSpace = 'nowrap'; - var n1 = 0; - var n2 = updates.length; - span.innerHTML = '正在下载素材(' + n1 + '/' + n2 + ')'; - span1.remove(); - span2.remove(); - span2_check.remove(); - span3.remove(); - span3_check.remove(); - span4.remove(); - span4_check.remove(); - span5.remove(); - span5_check.remove(); - span6.remove(); - span6_check.remove(); - span2_br.remove(); - span3_br.remove(); - span4_br.remove(); - span5_br.remove(); - span6_br.remove(); - p.appendChild(span); - - var br6 = ui.create.node('br'); - var span7 = ui.create.div('.hrefnode', '详细信息'); - span7.style.marginTop = '6px'; - span7.listen(ui.click.consoleMenu); - p.appendChild(br6); - p.appendChild(span7); - - var finish = function () { - if (n1 == n2) { - game.saveConfig('asset_version', asset_version); - } - span.innerHTML = '素材更新完毕(' + n1 + '/' + n2 + ')'; - p.appendChild(document.createElement('br')); - var button = document.createElement('button'); - button.innerHTML = '重新启动'; - button.onclick = game.reload; - button.style.marginTop = '8px'; - p.appendChild(button); - } - game.multiDownload(updates, function () { - n1++; - span.innerHTML = '正在下载素材(' + n1 + '/' + n2 + ')'; - }, function (e) { - game.print('下载失败:' + e.source); - }, function () { - setTimeout(finish, 500); - }); - }; - game.checkFileList(updates, proceed); - }, function () { - alert('连接失败'); - button2.disabled = false; - button2.innerHTML = '检查素材更新'; - }, true); - } - else { - alert('此版本不支持游戏内更新素材,请手动更新'); - } - }; - - button1 = document.createElement('button'); - button1.innerHTML = '检查游戏更新'; - button1.onclick = game.checkForUpdate; - li1.lastChild.appendChild(button1); - - button3 = document.createElement('button'); - button3.innerHTML = '更新到开发版'; - button3.style.marginLeft = '5px'; - button3.onclick = function () { - game.checkForUpdate(null, true); - }; - // if(lib.config.dev){ - // li1.lastChild.appendChild(button3); - // } - - (function () { - var updatep1 = li1.querySelector('p'); - var updatep2 = li2; - var updatep3 = li3; - var updatep4 = node; - var updatepx = ui.create.node('p'); - li1.appendChild(updatepx); - updatepx.style.display = 'none'; - updatepx.style.whiteSpace = 'nowrap'; - updatepx.style.marginTop = '8px'; - var buttonx = ui.create.node('button', '访问项目主页', function () { - window.open('https://github.com/libccy/noname'); - }); - updatepx.appendChild(buttonx); - ui.updateUpdate = function () { - if (!game.download) { - updatep1.style.display = 'none'; - updatep2.style.display = 'none'; - updatep3.style.display = 'none'; - updatepx.style.display = ''; - updatep4.innerHTML = '关于'; - } - else { - updatep1.style.display = ''; - updatep2.style.display = ''; - updatep3.style.display = 'none'; // coding - updatepx.style.display = 'none'; - updatep4.innerHTML = '更新'; - } - } - ui.updateUpdate(); - }()); - - button4 = document.createElement('button'); - button4.innerHTML = '设置更新地址'; - button4.onclick = function () { - game.prompt('设置更新地址', function (str) { - if (str) { - game.saveConfig('updateURL', str); - li3.querySelector('span').innerHTML = trimURL(str); - button5.style.display = ''; - button6.style.display = 'none'; - } - }); - }; - // li3.lastChild.appendChild(button4); - - var button6 = document.createElement('button'); - button6.innerHTML = '设为备用镜像'; - button6.style.display = 'none';// coding - // button6.style.marginLeft='5px'; - button6.onclick = function () { - game.saveConfig('updateURL', lib.mirrorURL); - button5.style.display = ''; - button6.style.display = 'none'; - li3.querySelector('span').innerHTML = trimURL(lib.mirrorURL); - }; - li3.lastChild.appendChild(button6); - - button5 = document.createElement('button'); - button5.innerHTML = '设为默认镜像'; - // button5.style.marginLeft='5px'; - button5.onclick = function () { - game.saveConfig('updateURL'); - button5.style.display = 'none'; - button6.style.display = ''; - li3.querySelector('span').innerHTML = trimURL(lib.updateURL); - }; - li3.lastChild.appendChild(button5); - if (!lib.config.updateURL) { - button5.style.display = 'none'; - } - else { - button6.style.display = 'none'; - } - - button2 = document.createElement('button'); - button2.innerHTML = '检查素材更新'; - button2.onclick = game.checkForAssetUpdate; - li2.lastChild.appendChild(button2); - - var span1 = ui.create.div('.config.more', '选项
      >
      '); - span1.style.fontSize = 'small'; - span1.style.display = 'inline'; - span1.toggle = function () { - if (!this.classList.toggle('on')) { - game.saveConfig('asset_toggle_off', true); - span2.style.display = 'none'; - span2_br.style.display = 'none'; - span2_check.style.display = 'none'; - span3.style.display = 'none'; - span3_br.style.display = 'none'; - span3_check.style.display = 'none'; - span4.style.display = 'none'; - span4_br.style.display = 'none'; - span4_check.style.display = 'none'; - span5.style.display = 'none'; - span5_br.style.display = 'none'; - span5_check.style.display = 'none'; - span6.style.display = 'none'; - span6_br.style.display = 'none'; - span6_check.style.display = 'none'; - } - else { - game.saveConfig('asset_toggle_off'); - span2.style.display = ''; - span2_br.style.display = ''; - span2_check.style.display = ''; - span3.style.display = ''; - span3_br.style.display = ''; - span3_check.style.display = ''; - span4.style.display = ''; - span4_br.style.display = ''; - span4_check.style.display = ''; - span5.style.display = ''; - span5_br.style.display = ''; - span5_check.style.display = ''; - span6.style.display = ''; - span6_br.style.display = ''; - span6_check.style.display = ''; - } - }; - span1.listen(span1.toggle); - li2.lastChild.appendChild(span1); - - var span6_br = ui.create.node('br'); - li2.lastChild.appendChild(span6_br); - - var span5 = ui.create.div('', '图片素材(精简,126MB)'); - span5.style.fontSize = 'small'; - span5.style.lineHeight = '16px'; - var span5_check = document.createElement('input'); - span5_check.type = 'checkbox'; - span5_check.style.marginLeft = '5px'; - if (lib.config.asset_image) { - span5_check.checked = true; - } - span5_check.onchange = function () { - game.saveConfig('asset_image', this.checked); - } - var span2_br = ui.create.node('br'); - - var span4 = ui.create.div('', '字体素材(48MB)'); - span4.style.fontSize = 'small'; - span4.style.lineHeight = '16px'; - li2.lastChild.appendChild(span4); - var span4_check = document.createElement('input'); - span4_check.type = 'checkbox'; - span4_check.style.marginLeft = '5px'; - if (lib.config.asset_font) { - span4_check.checked = true; - } - span4_check.onchange = function () { - game.saveConfig('asset_font', this.checked); - } - li2.lastChild.appendChild(span4_check); - var span3_br = ui.create.node('br'); - li2.lastChild.appendChild(span3_br); - - var span3 = ui.create.div('', '音效素材(125MB)'); - span3.style.fontSize = 'small'; - span3.style.lineHeight = '16px'; - li2.lastChild.appendChild(span3); - var span3_check = document.createElement('input'); - span3_check.type = 'checkbox'; - span3_check.style.marginLeft = '5px'; - if (lib.config.asset_audio) { - span3_check.checked = true; - } - span3_check.onchange = function () { - game.saveConfig('asset_audio', this.checked); - } - li2.lastChild.appendChild(span3_check); - var span4_br = ui.create.node('br'); - li2.lastChild.appendChild(span4_br); - - var span2 = ui.create.div('', '皮肤素材(351MB)'); - span2.style.fontSize = 'small'; - span2.style.lineHeight = '16px'; - li2.lastChild.appendChild(span2); - var span2_check = document.createElement('input'); - span2_check.type = 'checkbox'; - span2_check.style.marginLeft = '5px'; - if (lib.config.asset_skin) { - span2_check.checked = true; - } - span2_check.onchange = function () { - game.saveConfig('asset_skin', this.checked); - } - li2.lastChild.appendChild(span2_check); - var span5_br = ui.create.node('br'); - li2.lastChild.appendChild(span5_br); - - - li2.lastChild.appendChild(span5); - li2.lastChild.appendChild(span5_check); - li2.lastChild.appendChild(span2_br); - - var span6 = ui.create.div('', '图片素材(完整,203MB)'); - span6.style.fontSize = 'small'; - span6.style.lineHeight = '16px'; - li2.lastChild.appendChild(span6); - var span6_check = document.createElement('input'); - span6_check.type = 'checkbox'; - span6_check.style.marginLeft = '5px'; - if (lib.config.asset_full) { - span6_check.checked = true; - } - span6_check.onchange = function () { - game.saveConfig('asset_full', this.checked); - } - li2.lastChild.appendChild(span6_check); - - span2.style.display = 'none'; - span2_br.style.display = 'none'; - span2_check.style.display = 'none'; - span3.style.display = 'none'; - span3_br.style.display = 'none'; - span3_check.style.display = 'none'; - span4.style.display = 'none'; - span4_br.style.display = 'none'; - span4_check.style.display = 'none'; - span5.style.display = 'none'; - span5_br.style.display = 'none'; - span5_check.style.display = 'none'; - span6.style.display = 'none'; - span6_br.style.display = 'none'; - span6_check.style.display = 'none'; - - ul.appendChild(li1); - ul.appendChild(li2); - ul.appendChild(li3); - page.appendChild(ul); - - - if (!lib.config.asset_toggle_off) { - span1.toggle(); - } - }()); - (function () { - var norow2 = function () { - var node = currentrow1; - if (!node) return false; - return node.innerHTML == '横置' || node.innerHTML == '翻面' || node.innerHTML == '换人' || node.innerHTML == '复活'; - }; - var checkCheat = function () { - if (norow2()) { - for (var i = 0; i < row2.childElementCount; i++) { - row2.childNodes[i].classList.remove('selectedx'); - row2.childNodes[i].classList.add('unselectable'); - } - } - else { - for (var i = 0; i < row2.childElementCount; i++) { - row2.childNodes[i].classList.remove('unselectable'); - } - } - if (currentrow1 && currentrow1.innerHTML == '复活') { - for (var i = 0; i < row3.childNodes.length; i++) { - if (row3.childNodes[i].dead) { - row3.childNodes[i].style.display = ''; - } - else { - row3.childNodes[i].style.display = 'none'; - row3.childNodes[i].classList.remove('glow'); - } - row3.childNodes[i].classList.remove('unselectable'); - } - } - else { - for (var i = 0; i < row3.childElementCount; i++) { - if (currentrow1 && currentrow1.innerHTML == '换人' && row3.childNodes[i].link == game.me) { - row3.childNodes[i].classList.add('unselectable'); - } - else { - row3.childNodes[i].classList.remove('unselectable'); - } - if (!row3.childNodes[i].dead) { - row3.childNodes[i].style.display = ''; - } - else { - row3.childNodes[i].style.display = 'none'; - row3.childNodes[i].classList.remove('glow'); - } - } - } - if (currentrow1 && (currentrow2 || norow2()) && row3.querySelector('.glow')) { - cheatButton.classList.add('glowing'); - return true; - } - else { - cheatButton.classList.remove('glowing'); - return false; - } - } - cheatButton.listen(function () { - if (checkCheat()) { - var num; - if (currentrow2) { - switch (currentrow2.innerHTML) { - case '一': num = 1; break; - case '二': num = 2; break; - case '三': num = 3; break; - case '四': num = 4; break; - case '五': num = 5; break; - } - } - var targets = []; - var buttons = row3.querySelectorAll('.glow'); - for (var i = 0; i < buttons.length; i++) { - targets.push(buttons[i].link); - } - while (targets.length) { - var target = targets.shift(); - switch (currentrow1.innerHTML) { - case '伤害': target.damage(num, 'nosource'); break; - case '回复': target.recover(num, 'nosource'); break; - case '摸牌': target.draw(num); break; - case '弃牌': target.discard(target.getCards('he').randomGets(num)); break; - case '横置': target.link(); break; - case '翻面': target.turnOver(); break; - case '复活': target.revive(target.maxHp); break; - case '换人': { - if (_status.event.isMine()) { - if (!ui.auto.classList.contains('hidden')) { - setTimeout(function () { - ui.click.auto(); - setTimeout(function () { - ui.click.auto(); - game.swapPlayer(target); - }, 500); - }); - } - } - else { - game.swapPlayer(target); - } - break; - } - } - } - if (ui.coin) { - game.changeCoin(-20); - } - clickContainer.call(menuContainer); - } - }); - - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '控制', start.firstChild, clickMode); - node.link = page; - node.type = 'cheat'; - page.classList.add('menu-sym'); - - var currentrow1 = null; - var row1 = ui.create.div('.menu-cheat', page); - var clickrow1 = function () { - if (this.classList.contains('unselectable')) return; - if (currentrow1 == this) { - this.classList.remove('selectedx'); - currentrow1 = null; - } - else { - this.classList.add('selectedx'); - if (currentrow1) { - currentrow1.classList.remove('selectedx'); - } - currentrow1 = this; - if (this.innerHTML == '换人') { - for (var i = 0; i < row3.childNodes.length; i++) { - row3.childNodes[i].classList.remove('glow'); - } - } - } - checkCheat(); - }; - var nodedamage = ui.create.div('.menubutton', '伤害', row1, clickrow1); - var noderecover = ui.create.div('.menubutton', '回复', row1, clickrow1); - var nodedraw = ui.create.div('.menubutton', '摸牌', row1, clickrow1); - var nodediscard = ui.create.div('.menubutton', '弃牌', row1, clickrow1); - var nodelink = ui.create.div('.menubutton', '横置', row1, clickrow1); - var nodeturnover = ui.create.div('.menubutton', '翻面', row1, clickrow1); - var noderevive = ui.create.div('.menubutton', '复活', row1, clickrow1); - var nodereplace = ui.create.div('.menubutton', '换人', row1, clickrow1); - if (!game.canReplaceViewpoint || !game.canReplaceViewpoint()) { - nodereplace.classList.add('unselectable'); - } - - var currentrow2 = null; - var row2 = ui.create.div('.menu-cheat', page); - var clickrow2 = function () { - if (this.classList.contains('unselectable')) return; - if (currentrow2 == this) { - this.classList.remove('selectedx'); - currentrow2 = null; - } - else { - this.classList.add('selectedx'); - if (currentrow2) { - currentrow2.classList.remove('selectedx'); - } - currentrow2 = this; - } - checkCheat(); - }; - var nodex1 = ui.create.div('.menubutton', '一', row2, clickrow2); - var nodex2 = ui.create.div('.menubutton', '二', row2, clickrow2); - var nodex3 = ui.create.div('.menubutton', '三', row2, clickrow2); - var nodex4 = ui.create.div('.menubutton', '四', row2, clickrow2); - var nodex5 = ui.create.div('.menubutton', '五', row2, clickrow2); - - var row3 = ui.create.div('.menu-buttons.leftbutton.commandbutton', page); - row3.style.marginTop = '3px'; - var clickrow3 = function () { - if (this.classList.contains('unselectable')) return; - this.classList.toggle('glow'); - if (currentrow1 && currentrow1.innerHTML == '换人' && this.classList.contains('glow')) { - if (this.link == game.me) { - this.classList.remove('glow'); - } - for (var i = 0; i < row3.childElementCount; i++) { - if (row3.childNodes[i] != this) { - row3.childNodes[i].classList.remove('glow'); - } - } - } - checkCheat(); - }; - menuUpdates.push(function () { - if (_status.video || _status.connectMode) { - node.classList.add('off'); - if (node.classList.contains('active')) { - node.classList.remove('active'); - node.link.remove(); - active = start.firstChild.firstChild; - active.classList.add('active'); - rightPane.appendChild(active.link); - } - - page.remove(); - cheatButton.remove(); - if (_status.video) node.remove(); - return; - } - var list = []; - for (var i = 0; i < game.players.length; i++) { - if (lib.character[game.players[i].name] || game.players[i].name1) { - list.push(game.players[i]); - } - } - for (var i = 0; i < game.dead.length; i++) { - if (lib.character[game.dead[i].name] || game.dead[i].name1) { - list.push(game.dead[i]); - } - } - if (list.length) { - row1.show(); - row2.show(); - row3.innerHTML = ''; - var buttons = ui.create.buttons(list, 'player', row3, true); - for (var i = 0; i < buttons.length; i++) { - buttons[i].listen(clickrow3); - if (game.dead.includes(buttons[i].link)) { - buttons[i].dead = true; - } - } - checkCheat(); - } - else { - row1.hide(); - row2.hide(); - } - if (lib.config.mode == 'identity' || lib.config.mode == 'guozhan' || lib.config.mode == 'doudizhu') { - if (game.notMe || (game.me && (game.me._trueMe || game.hasPlayer(function (current) { - return current._trueMe == game.me; - }))) || !game.phaseNumber || _status.qianlidanji) { - nodereplace.classList.add('unselectable'); - } - else if (_status.event.isMine() && ui.auto.classList.contains('hidden')) { - nodereplace.classList.add('unselectable'); - } - else { - nodereplace.classList.remove('unselectable'); - } - } - if (game.dead.length == 0) { - noderevive.classList.add('unselectable'); - } - else { - noderevive.classList.remove('unselectable'); - } - checkCheat(); - }); - }()); - (function () { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '命令', start.firstChild, clickMode); - ui.commandnode = node; - node.type = 'cmd'; - menuUpdates.push(function () { - if (_status.connectMode) { - node.classList.add('off'); - if (node.classList.contains('active')) { - node.classList.remove('active'); - if (node.link) node.link.remove(); - active = start.firstChild.firstChild; - active.classList.add('active'); - rightPane.appendChild(active.link); - } - } - }); - node._initLink = function () { - node.link = page; - page.classList.add('menu-sym'); - - const text = document.createElement('div'); - text.css({ - 'width': '194px', - 'height': '124px', - 'padding': '3px', - 'borderRadius': '2px', - 'boxShadow': 'rgba(0, 0, 0, 0.2) 0 0 0 1px', - 'textAlign': 'left', - 'webkitUserSelect': 'initial', - 'overflow': 'scroll', - 'position': 'absolute', - 'left': '30px', - 'top': '50px', - 'wordBreak': 'break-all' - }); - - const pre = ui.create.node('pre.fullsize', text); - text.css.call(pre, { - 'margin': '0', - 'padding': '0', - 'position': 'relative', - 'webkitUserSelect': 'text', - 'userSelect': 'text' - }); - lib.setScroll(pre); - page.appendChild(text); - - const text2 = document.createElement('input'); - text.css.call(text2, { - 'width': '200px', - 'height': '20px', - 'padding': '0', - 'position': 'absolute', - 'top': '15px', - 'left': '30px', - 'resize': 'none', - 'border': 'none', - 'borderRadius': '2px', - 'boxShadow': 'rgba(0, 0, 0, 0.2) 0 0 0 1px' - }); - - const g = {}; - const logs = []; - let logindex = -1; - let proxyWindow = Object.assign({}, window, { - _status: _status, - lib: lib, - game: game, - ui: ui, - get: get, - ai: ai, - cheat: lib.cheat - }); - Object.defineProperties(proxyWindow, { - '_status': { - configurable: false, - enumerable: true, - writable: false - }, - 'lib': { - configurable: false, - enumerable: true, - writable: false - }, - 'game': { - configurable: false, - enumerable: true, - writable: false - }, - 'ui': { - configurable: false, - enumerable: true, - writable: false - }, - 'get': { - configurable: false, - enumerable: true, - writable: false - }, - 'ai': { - configurable: false, - enumerable: true, - writable: false - }, - 'cheat': { - configurable: false, - enumerable: true, - writable: false - } - }); - proxyWindow = new Proxy(proxyWindow, { - set(target, prop, newValue) { - if (!['_status', 'lib', 'game', 'ui', 'get', 'ai', 'cheat'].includes(prop)) { - Reflect.set(window, prop, newValue); - } - return Reflect.set(target, prop, newValue); - } - }); - //使用new Function隔绝作用域,避免在控制台可以直接访问到runCommand等变量 - /** - * @type { (value:string)=>any } - */ - const fun = (new Function('window', ` - const _status=window._status; - const lib=window.lib; - const game=window.game; - const ui=window.ui; - const get=window.get; - const ai=window.ai; - const cheat=window.lib.cheat; - //使用正则匹配绝大多数的普通obj对象,避免解析成代码块。 - const reg=${/^\{([^{}]+:\s*([^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\)))(?:,\s*([^{}]+:\s*(?:[^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\))))*\}$/}; - return function(value){ - "use strict"; - return eval(reg.test(value)?('('+value+')'):value); - } - `))(proxyWindow); - const runCommand = () => { - if (text2.value && !['up', 'down'].includes(text2.value)) { - logindex = -1; - logs.unshift(text2.value); - } - if (text2.value == 'cls') { - pre.innerHTML = ''; - text2.value = ''; - } - else if (text2.value == 'up') { - if (logindex + 1 < logs.length) { - text2.value = logs[++logindex]; - } - else { - text2.value = ''; - } - } - else if (text2.value == 'down') { - if (logindex >= 0) { - logindex--; - if (logindex < 0) { - text2.value = ''; - } - else { - text2.value = logs[logindex]; - } - } - else { - text2.value = ''; - } - } - else if (text2.value.includes('无天使') && (text2.value.includes('无神佛') || text2.value.includes('无神') && text2.value.includes('无佛'))) { - game.print('密码正确!欢迎来到死后世界战线!'); - _status.keyVerified = true; - text2.value = ''; - } - else { - if (!game.observe && !game.online) { - try { - let value = text2.value.trim(); - if (value.endsWith(";")) value = value.slice(0, -1).trim(); - game.print(fun(value)); - } - catch (e) { - game.print(e); - } - } - text2.value = ''; - } - } - text2.addEventListener('keydown', e => { - if (e.keyCode == 13) { - runCommand(); - } - else if (e.keyCode == 38) { - if (logindex + 1 < logs.length) { - text2.value = logs[++logindex]; - } - } - else if (e.keyCode == 40) { - if (logindex >= 0) { - logindex--; - if (logindex < 0) { - text2.value = ''; - } - else { - text2.value = logs[logindex]; - } - } - } - }); - page.appendChild(text2); - game.print = function () { - const args = [...arguments]; - const printResult = args.map(arg => { - if (typeof arg != 'string') { - const parse = (obj) => { - if (Array.isArray(obj)) { - return `[${obj.map(v => parse(v))}]`; - } else if (typeof obj == 'function') { - return `[Function ${obj.name}]`; - } else if (typeof obj != 'string') { - if (obj instanceof Error) { - return `${String(obj)}`; - } - return String(obj); - } else { - return `'${String(obj)}'`; - } - }; - if (typeof arg == 'function') { - let argi; - try { - argi = get.stringify(arg); - if (argi === '') argi = arg.toString(); - } catch (_) { - argi = arg.toString(); - } - return argi.replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - } - else if (typeof arg == 'object') { - let msg = ''; - for (const name of Object.getOwnPropertyNames(arg)) { - msg += `${name}: ${parse(arg[name])}
      `; - } - return `
      ${parse(arg)}${msg}
      `; - } else { - return parse(arg); - } - } else { - const str = String(arg); - if (!/<[a-zA-Z]+[^>]*?\/?>.*?(?=<\/[a-zA-Z]+[^>]*?>|$)/.exec(str)) return str - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - else return str; - } - }).join(' '); - pre.innerHTML += printResult + '
      '; - text.scrollTop = text.scrollHeight; - } - if (_status.toprint) { - game.print(..._status.toprint); - delete _status.toprint; - } - runButton.listen(runCommand); - clearButton.listen(() => { - pre.innerHTML = ''; - }); - }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - (function () { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '战绩', start.firstChild, clickMode); - node.type = 'rec'; - node._initLink = function () { - node.link = page; - page.style.paddingBottom = '10px'; - var reset = function () { - if (this.innerHTML == '重置') { - this.innerHTML = '确定'; - var that = this; - setTimeout(function () { - that.innerHTML = '重置'; - }, 1000); - } - else { - this.parentNode.previousSibling.remove(); - this.parentNode.remove(); - lib.config.gameRecord[this.parentNode.link] = { data: {} }; - game.saveConfig('gameRecord', lib.config.gameRecord); - } - } - for (var i = 0; i < lib.config.all.mode.length; i++) { - if (!lib.config.gameRecord[lib.config.all.mode[i]]) continue; - if (lib.config.gameRecord[lib.config.all.mode[i]].str) { - ui.create.div('.config.indent', lib.translate[lib.config.all.mode[i]], page).style.marginBottom = '-5px'; - var item = ui.create.div('.config.indent', lib.config.gameRecord[lib.config.all.mode[i]].str + '重置', page); - item.style.height = 'auto'; - item.lastChild.addEventListener('click', reset); - item.lastChild.classList.add('pointerdiv'); - item.link = lib.config.all.mode[i]; - } - } - }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - (function () { - if (!window.indexedDB || window.nodb) return; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '录像', start.firstChild, clickMode); - node.type = 'video'; - lib.videos = []; - ui.create.videoNode = (video, before) => { - lib.videos.remove(video); - lib.videos[before === true ? 'unshift' : 'push'](video); - }; - node._initLink = function () { - node.link = page; - var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); - store.openCursor().onsuccess = function (e) { - var cursor = e.target.result; - if (cursor) { - lib.videos.push(cursor.value); - cursor.continue(); - } - else { - lib.videos.sort(function (a, b) { - return parseInt(b.time) - parseInt(a.time); - }); - var clickcapt = function () { - var current = this.parentNode.querySelector('.videonode.active'); - if (current && current != this) { - current.classList.remove('active'); - } - if (this.classList.toggle('active')) { - playButton.show(); - deleteButton.show(); - saveButton.show(); - } - else { - playButton.hide(); - deleteButton.hide(); - saveButton.hide(); - } - }; - var staritem = function () { - this.parentNode.classList.toggle('starred'); - var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); - if (this.parentNode.classList.contains('starred')) { - this.parentNode.link.starred = true; - } - else { - this.parentNode.link.starred = false; - } - store.put(this.parentNode.link); - } - var createNode = function (video, before) { - var node = ui.create.div('.videonode.menubutton.large', clickcapt); - node.link = video; - var nodename1 = ui.create.div('.menubutton.videoavatar', node); - nodename1.setBackground(video.name1, 'character'); - if (video.name2) { - var nodename2 = ui.create.div('.menubutton.videoavatar2', node); - nodename2.setBackground(video.name2, 'character'); - } - var date = new Date(video.time); - var str = date.getFullYear() + '.' + (date.getMonth() + 1) + '.' + (date.getDate()) + ' ' + - date.getHours() + ':'; - var minutes = date.getMinutes(); - if (minutes < 10) { - str += '0'; - } - str += minutes; - ui.create.div('.caption', video.name[0], node); - ui.create.div('.text', str + '
      ' + video.name[1], node); - if (video.win) { - ui.create.div('.victory', '胜', node); - } - - if (before) { - page.insertBefore(node, page.firstChild); - } - else { - page.appendChild(node); - } - ui.create.div('.video_star', '★', node, staritem); - if (video.starred) { - node.classList.add('starred'); - } - } - for (var i = 0; i < lib.videos.length; i++) { - createNode(lib.videos[i]); - } - ui.create.videoNode = createNode; - var importVideoNode = ui.create.div('.config.switcher.pointerspan', - '导入录像...', function () { - this.nextSibling.classList.toggle('hidden'); - }, page); - importVideoNode.style.marginLeft = '12px'; - importVideoNode.style.marginTop = '3px'; - var importVideo = ui.create.div('.config.hidden', page); - importVideo.style.whiteSpace = 'nowrap'; - importVideo.style.marginBottom = '80px'; - importVideo.style.marginLeft = '13px'; - importVideo.style.width = 'calc(100% - 30px)'; - importVideo.innerHTML = '' + - ''; - importVideo.lastChild.onclick = function () { - var fileToLoad = importVideo.firstChild.files[0]; - var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { - var data = fileLoadedEvent.target.result; - if (!data) return; - try { - data = JSON.parse(lib.init.decode(data)); - } - catch (e) { - console.log(e); - alert('导入失败'); - return; - } - var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); - var videos = lib.videos.slice(0); - for (var i = 0; i < videos.length; i++) { - if (videos[i].starred) { - videos.splice(i--, 1); - } - } - for (var deletei = 0; deletei < 5; deletei++) { - if (videos.length >= parseInt(lib.config.video) && videos.length) { - var toremove = videos.pop(); - lib.videos.remove(toremove); - store.delete(toremove.time); - for (var i = 0; i < page.childNodes.length; i++) { - if (page.childNodes[i].link == toremove) { - page.childNodes[i].remove(); - break; - } - } - } - else { - break; - } - } - for (var i = 0; i < lib.videos.length; i++) { - if (lib.videos[i].time == data.time) { - alert('录像已存在'); - return; - } - } - lib.videos.unshift(data); - store.put(data); - createNode(data, true); - }; - fileReader.readAsText(fileToLoad, "UTF-8"); - } - - playButton.listen(function () { - var current = this.parentNode.querySelector('.videonode.active'); - if (current) { - game.playVideo(current.link.time, current.link.mode); - } - }); - deleteButton.listen(function () { - var current = this.parentNode.querySelector('.videonode.active'); - if (current) { - lib.videos.remove(current.link); - var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); - store.delete(current.link.time); - current.remove(); - } - }); - saveButton.listen(function () { - var current = this.parentNode.querySelector('.videonode.active'); - if (current) { - game.export(lib.init.encode(JSON.stringify(current.link)), - '无名杀 - 录像 - ' + current.link.name[0] + ' - ' + current.link.name[1]); - } - }); - - ui.updateVideoMenu = function () { - var active = start.firstChild.querySelector('.active'); - if (active) { - active.classList.remove('active'); - active.link.remove(); - } - node.classList.add('active'); - rightPane.appendChild(page); - playButton.style.display = ''; - deleteButton.style.display = ''; - saveButton.style.display = ''; - } - } - }; - }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - - - for (var i in lib.help) { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', i, start.firstChild, clickMode); - node.type = 'help'; - node.link = page; - node.style.display = 'none'; - page.classList.add('menu-help'); - page.innerHTML = lib.help[i]; - } - - if (!connectMenu) { - var node = ui.create.div('.menubutton.large', '帮助', start.firstChild, function () { - var activex = start.firstChild.querySelector('.active'); - if (this.innerHTML == '帮助') { - cheatButton.style.display = 'none'; - runButton.style.display = 'none'; - clearButton.style.display = 'none'; - playButton.style.display = 'none'; - saveButton.style.display = 'none'; - deleteButton.style.display = 'none'; - - this.innerHTML = '返回'; - for (var i = 0; i < start.firstChild.childElementCount; i++) { - var nodex = start.firstChild.childNodes[i]; - if (nodex == node) continue; - if (nodex.type == 'help') { - nodex.style.display = ''; - if (activex && activex.type != 'help') { - activex.classList.remove('active'); - activex.link.remove(); - activex = null; - nodex.classList.add('active'); - rightPane.appendChild(nodex.link); - } - } - else { - nodex.style.display = 'none'; - } - } - } - else { - this.innerHTML = '帮助'; - for (var i = 0; i < start.firstChild.childElementCount; i++) { - var nodex = start.firstChild.childNodes[i]; - if (nodex == node) continue; - if (nodex.type != 'help') { - nodex.style.display = ''; - if (activex && activex.type == 'help') { - activex.classList.remove('active'); - activex.link.remove(); - activex = null; - clickMode.call(nodex); - } - } - else { - nodex.style.display = 'none'; - } - } - } - }); - } - - var active = start.firstChild.querySelector('.active'); - if (!active) { - active = start.firstChild.firstChild; - active.classList.add('active'); - } - if (!active.link) active._initLink(); - rightPane.appendChild(active.link); - }()); - - if (menuTimeout) { - clearTimeout(menuTimeout); - delete window.resetExtension; - localStorage.removeItem(lib.configprefix + 'disable_extension', true); - } - } - static statictable() { - var str, row, col, position, position2, fixed, style, divposition; - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') str = arguments[i]; - else if (typeof arguments[i] == 'number') { - if (typeof row == 'number') { - if (typeof col == 'number') position2 = arguments[i]; - else col = arguments[i]; - } - else row = arguments[i]; - } - else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; - else if (typeof arguments[i] == 'boolean') fixed = arguments[i]; - else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; - else if (typeof arguments[i] == 'object') style = arguments[i]; - } - if (str == undefined) str = ''; - var node = document.createElement('table'); - for (var i = 0; i < str.length; i++) { - if (str[i] == '.') { - if (node.className.length != 0) { - node.className += ' '; - } - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { - node.className += str[i + 1]; - i++; - } - } - else if (str[i] == '#') { - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { - node.id += str[i + 1]; - i++; - } - } - } - var tr, td; - for (var i = 0; i < row; i++) { - tr = document.createElement('tr'); - if (fixed) tr.style.height = (100 / row) + '%'; - node.appendChild(tr); - for (var j = 0; j < col; j++) { - td = document.createElement('td'); - tr.appendChild(td); - } - } - if (position) { - if (typeof position2 == 'number' && position.childNodes.length > position2) { - position.insertBefore(node, position.childNodes[position2]); - } - else { - position.appendChild(node); - } - } - return node; - } - static giveup() { - if (ui.giveup) return; - if (!lib.config.show_giveup) return; - ui.giveup = ui.create.system('投降', function () { - var player = game.me; - this.remove(); - if (game.online) { - game.send('giveup', player); - } - else { - _status.event.next.length = 0; - game.createEvent('giveup', false).set('includeOut', true).setContent(function () { - game.log(player, '投降'); - player.popup('投降'); - player.die('nosource').includeOut = true; - }).player = player; - } - if (_status.paused && _status.imchoosing && !_status.auto) { - ui.click.auto(); - } - }, true, true); - } - static groupControl(dialog) { - return ui.create.control('wei', 'shu', 'wu', 'qun', 'jin', 'western', 'key', function (link, node) { - if (link == '全部') { - dialog.currentcapt = ''; - dialog.currentgroup = ''; - for (var i = 0; i < dialog.buttons.length; i++) { - dialog.buttons[i].style.display = ''; - } - } - else { - if (node.classList.contains('thundertext')) { - dialog.currentgroup = null; - dialog.currentgroupnode = null; - node.classList.remove('thundertext'); - for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - else { - if (dialog.currentgroupnode) { - dialog.currentgroupnode.classList.remove('thundertext'); - } - dialog.currentgroup = link; - dialog.currentgroupnode = node; - node.classList.add('thundertext'); - for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.buttons[i].group != link || - (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt))) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - } - }); - } - static cardDialog() { - var args = ['thisiscard']; - for (var i = 0; i < arguments.length; i++) { - args.push(arguments[i]); - } - return ui.create.characterDialog.apply(this, args); - } - static characterDialog2(filter) { - var list = []; - for (var i in lib.character) { - if (lib.character[i][4].includes('minskin')) continue; - if (lib.character[i][4].includes('boss') || lib.character[i][4].includes('hiddenboss')) { - if (lib.config.mode == 'boss') continue; - if (!lib.character[i][4].includes('bossallowed')) continue; - } - - if (lib.character[i][4].includes('stonehidden')) continue; - if (lib.config.banned.includes(i)) continue; - if (filter && filter(i)) continue; - list.push(i); - } - var dialog = ui.create.dialog('hidden'); - dialog.classList.add('noupdate'); - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('scroll3'); - list.sort(lib.sort.character); - dialog.classList.add('character'); - dialog.classList.add('choose-character'); - var getPack = function (name) { - for (var i in lib.characterPack) { - if (lib.characterPack[i][name]) return i; - } - return null; - } - var packs = {}; - var packnode = ui.create.div('.packnode', dialog); - lib.setScroll(packnode); - var clickCapt = function () { - var active = this.parentNode.querySelector('.active'); - if (active) { - active.classList.remove('active'); - } - this.classList.add('active'); - for (var i = 0; i < dialog.buttons.length; i++) { - if (this.pack && !this.pack.includes(dialog.buttons[i].link)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - var createNode = function (packname) { - var translate; - var pack = null; - if (packname == '最近') { - pack = get.config('recentCharacter') || []; - } - else if (packname == '收藏') { - pack = lib.config.favouriteCharacter; - } - var node = ui.create.div('.dialogbutton.menubutton.large', packname, packnode, clickCapt); - node.pack = pack; - return node; - } - dialog.add([list, 'character']); - var bool = true; - var node; - var recent = get.config('recentCharacter'); - if (recent && recent.length) { - node = createNode('最近'); - if (lib.config.character_dialog_tool == '最近') { - clickCapt.call(node); - bool = false; - } - } - if (lib.config.favouriteCharacter.length) { - node = createNode('收藏'); - if (lib.config.character_dialog_tool == '收藏') { - clickCapt.call(node); - bool = false; - } - } - var node = createNode('全部'); - if (lib.config.character_dialog_tool == 'all') { - clickCapt.call(node); - bool = false; - } - if (bool) { - clickCapt.call(packnode.firstChild); - } - - var node = ui.create.div('.dialogbutton.menubutton.large', '筛选', packnode); - return dialog; - } - static characterDialog() { - // if(lib.config.character_dialog_style=='newstyle'){ - // for(var i=0;i b ? 1 : -1; - }); - groups.sort(lib.sort.group); - if (!thisiscard) { - namecapt.remove('自定义'); - namecapt.push('newline'); - for (var i in lib.characterDialogGroup) { - namecapt.push(i); - } - } - var newlined = false; - var newlined2; - var packsource; - var clickCapt = function (e) { - if (_status.dragged) return; - if (dialog.currentcapt2 == '最近' && dialog.currentcaptnode2 != this && !dialog.currentcaptnode2.inited) { - dialog.currentcapt2 = null; - dialog.currentcaptnode2.classList.remove('thundertext'); - dialog.currentcaptnode2.inited = true; - dialog.currentcaptnode2 = null; - } - if (this.alphabet) { - if (this.classList.contains('thundertext')) { - dialog.currentcapt = null; - dialog.currentcaptnode = null; - this.classList.remove('thundertext'); - if (this.touchlink) { - this.touchlink.classList.remove('active'); - } - for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.currentgroup && dialog.buttons[i].group != dialog.currentgroup) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentcapt2 && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - else { - if (dialog.currentcaptnode) { - dialog.currentcaptnode.classList.remove('thundertext'); - if (dialog.currentcaptnode.touchlink) { - dialog.currentcaptnode.touchlink.classList.remove('active'); - } - } - dialog.currentcapt = this.link; - dialog.currentcaptnode = this; - this.classList.add('thundertext'); - if (this.touchlink) { - this.touchlink.classList.add('active'); - } - for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentcapt2 && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentgroup && dialog.buttons[i].group != dialog.currentgroup) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - } - else { - if (newlined2) { - newlined2.style.display = 'none'; - if (!packsource.onlypack) { - packsource.classList.remove('thundertext'); - if (!get.is.phoneLayout() || !lib.config.filternode_button) { - packsource.innerHTML = '武将包'; - } - } - } - if (this.classList.contains('thundertext')) { - dialog.currentcapt2 = null; - dialog.currentcaptnode2 = null; - this.classList.remove('thundertext'); - if (this.touchlink) { - this.touchlink.classList.remove('active'); - } - for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.currentgroup && dialog.buttons[i].group != dialog.currentgroup) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - else { - if (dialog.currentcaptnode2) { - dialog.currentcaptnode2.classList.remove('thundertext'); - if (dialog.currentcaptnode2.touchlink) { - dialog.currentcaptnode2.touchlink.classList.remove('active'); - } - } - dialog.currentcapt2 = this.link; - dialog.currentcaptnode2 = this; - this.classList.add('thundertext'); - if (this.touchlink) { - this.touchlink.classList.add('active'); - } - else if (this.parentNode == newlined2) { - packsource.innerHTML = this.innerHTML; - packsource.classList.add('thundertext'); - } - for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentgroup && dialog.buttons[i].group != dialog.currentgroup) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - if (dialog.buttons[i].activate) { - dialog.buttons[i].activate(); - } - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - } - if (dialog.seperate) { - for (var i = 0; i < dialog.seperate.length; i++) { - if (!dialog.seperate[i].nextSibling.querySelector('.button:not(.nodisplay)')) { - dialog.seperate[i].style.display = 'none'; - dialog.seperate[i].nextSibling.style.display = 'none'; - } - else { - dialog.seperate[i].style.display = ''; - dialog.seperate[i].nextSibling.style.display = ''; - } - } - } - if (filternode) { - if (filternode.querySelector('.active')) { - packsource.classList.add('thundertext'); - } - else { - packsource.classList.remove('thundertext'); - } - } - if (e) e.stopPropagation(); - }; - for (i = 0; i < namecapt.length; i++) { - if (namecapt[i] == 'newline') { - newlined = document.createElement('div'); - newlined.style.marginTop = '5px'; - newlined.style.display = 'block'; - // newlined.style.fontFamily='xinwei'; - if (get.is.phoneLayout()) { - newlined.style.fontSize = '32px'; - } - else { - newlined.style.fontSize = '22px'; - } - newlined.style.textAlign = 'center'; - node.appendChild(newlined); - } - else if (newlined) { - var span = ui.create.div('.tdnode.pointerdiv.shadowed.reduce_radius'); - span.style.margin = '3px'; - span.style.width = 'auto'; - span.innerHTML = ' ' + namecapt[i].toUpperCase() + ' '; - span.link = namecapt[i]; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); - newlined.appendChild(span); - node[namecapt[i]] = span; - if (namecapt[i] == '收藏') { - span._nature = 'fire'; - } - else { - span._nature = 'wood'; - } - } - else { - var span = document.createElement('span'); - span.innerHTML = ' ' + namecapt[i].toUpperCase() + ' '; - span.link = namecapt[i]; - span.alphabet = true; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); - node.appendChild(span); - } - } - if (!thisiscard) { - var natures = ['water', 'soil', 'wood', 'metal']; - var span = document.createElement('span'); - newlined.appendChild(span); - span.style.margin = '8px'; - var clickGroup = function () { - if (_status.dragged) return; - if (dialog.currentcapt2 == '最近' && dialog.currentcaptnode2 != this && !dialog.currentcaptnode2.inited) { - dialog.currentcapt2 = null; - dialog.currentcaptnode2.classList.remove('thundertext'); - dialog.currentcaptnode2.inited = true; - dialog.currentcaptnode2 = null; - } - var node = this, link = this.link; - if (node.classList.contains('thundertext')) { - dialog.currentgroup = null; - dialog.currentgroupnode = null; - node.classList.remove('thundertext'); - for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentcapt2 && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - else { - if (dialog.currentgroupnode) { - dialog.currentgroupnode.classList.remove('thundertext'); - } - dialog.currentgroup = link; - dialog.currentgroupnode = node; - node.classList.add('thundertext'); - for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentcapt2 && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentgroup == 'double') { - if (dialog.buttons[i]._changeGroup) dialog.buttons[i].classList.remove('nodisplay'); - else dialog.buttons[i].classList.add('nodisplay'); - } - else if (dialog.currentgroup == 'ye') { - if (dialog.buttons[i].group == 'ye') dialog.buttons[i].classList.remove('nodisplay'); - else dialog.buttons[i].classList.add('nodisplay'); - } - else { - if (dialog.buttons[i]._changeGroup || dialog.buttons[i].group != dialog.currentgroup) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); - } - } - } - } - }; - for (var i = 0; i < groups.length; i++) { - var span = ui.create.div('.tdnode.pointerdiv.shadowed.reduce_radius.reduce_margin'); - span.style.margin = '3px'; - newlined.appendChild(span); - span.innerHTML = get.translation(groups[i]); - span.link = groups[i]; - span._nature = natures[i]; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickGroup); - } - - var span = document.createElement('span'); - newlined.appendChild(span); - span.style.margin = '8px'; - - packsource = ui.create.div('.tdnode.pointerdiv.shadowed.reduce_radius.reduce_margin'); - packsource.style.margin = '3px'; - newlined.appendChild(packsource); - var filternode = null; - var clickCaptNode = function (e) { - delete _status.filterCharacter; - ui.window.classList.remove('shortcutpaused'); - filternode.delete(); - filternode.classList.remove('shown'); - clickCapt.call(this.link, e); - }; - if (get.is.phoneLayout() && lib.config.filternode_button) { - newlined.style.marginTop = ''; - packsource.innerHTML = '筛选'; - filternode = ui.create.div('.popup-container.filter-character.modenopause'); - ui.create.div(filternode); - filternode.listen(function (e) { - if (this.classList.contains('removing')) return; - delete _status.filterCharacter; - ui.window.classList.remove('shortcutpaused'); - this.delete(); - this.classList.remove('shown'); - e.stopPropagation(); - }); - for (var i = 0; i < node.childElementCount; i++) { - if (node.childNodes[i].tagName.toLowerCase() == 'span') { - node.childNodes[i].style.display = 'none'; - node.childNodes[i].touchlink = ui.create.div(filternode.firstChild, clickCaptNode, '.menubutton.large.capt', node.childNodes[i].innerHTML); - node.childNodes[i].touchlink.link = node.childNodes[i]; - } - } - ui.create.node('br', filternode.firstChild); - } - else { - if (onlypack) { - packsource.onlypack = true; - packsource.innerHTML = get.translation(onlypack + '_character_config'); - packsource.style.display = 'none'; - packsource.previousSibling.style.display = 'none'; - } - else { - packsource.innerHTML = '武将包'; - } - } - - newlined2 = document.createElement('div'); - newlined2.style.marginTop = '5px'; - newlined2.style.display = 'none'; - newlined2.style.fontFamily = 'xinwei'; - newlined2.classList.add('pointernode'); - if (get.is.phoneLayout()) { - newlined2.style.fontSize = '32px'; - } - else { - newlined2.style.fontSize = '22px'; - } - newlined2.style.textAlign = 'center'; - node.appendChild(newlined2); - - packsource.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function () { - if (packsource.onlypack) return; - if (_status.dragged) return; - if (get.is.phoneLayout() && lib.config.filternode_button && filternode) { - _status.filterCharacter = true; - ui.window.classList.add('shortcutpaused'); - ui.window.appendChild(filternode); - ui.refresh(filternode); - filternode.classList.add('shown'); - var dh = filternode.offsetHeight - filternode.firstChild.offsetHeight; - if (dh > 0) { - filternode.firstChild.style.top = (dh / 2) + 'px'; - } - else { - filternode.firstChild.style.top = ''; - } - } - else { - if (newlined2.style.display == 'none') { - newlined2.style.display = 'block'; - } - else { - newlined2.style.display = 'none'; - } - } - }); - var packlist = []; - for (var i = 0; i < lib.config.all.characters.length; i++) { - if (!lib.config.characters.includes(lib.config.all.characters[i])) continue; - packlist.push(lib.config.all.characters[i]); - } - for (var i in lib.characterPack) { - if (!lib.config.all.characters.includes(i)) { - packlist.push(i); - } - } - for (var i = 0; i < packlist.length; i++) { - var span = document.createElement('div'); - span.style.display = 'inline-block'; - span.style.width = 'auto'; - span.style.margin = '5px'; - if (get.is.phoneLayout()) { - span.style.fontSize = '32px'; - } - else { - span.style.fontSize = '22px'; - } - span.innerHTML = lib.translate[packlist[i] + '_character_config']; - span.link = packlist[i]; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); - newlined2.appendChild(span); - if (filternode && !onlypack) { - span.touchlink = ui.create.div(filternode.firstChild, clickCaptNode, '.menubutton.large', span.innerHTML); - span.touchlink.link = span; - } - } - } - - var groupSort; - if (thisiscard) { - groupSort = function (name) { - var type = lib.card[name[2]].type; - if (lib.cardType[type]) { - return lib.cardType[type]; - } - switch (type) { - case 'basic': return 0; - case 'chess': return 1.5; - case 'trick': return 2; - case 'delay': return 3; - case 'equip': return 4; - case 'zhenfa': return 5; - default: return 6; - } - } - list.sort(function (a, b) { - var del = groupSort(a) - groupSort(b); - if (del != 0) return del; - var aa = a, bb = b; - if (a.includes('_')) { - a = a.slice(a.lastIndexOf('_') + 1); - } - if (b.includes('_')) { - b = b.slice(b.lastIndexOf('_') + 1); - } - if (a != b) { - return a > b ? 1 : -1; - } - return aa > bb ? 1 : -1; - }); - } - else { - list.sort(lib.sort.character); - } - dialog = ui.create.dialog('hidden'); - dialog.classList.add('noupdate'); - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('scroll3'); - dialog.addEventListener(lib.config.touchscreen ? 'touchend' : 'mouseup', function () { - _status.clicked2 = true; - }); - if (heightset) { - dialog.style.height = ((game.layout == 'long2' || game.layout == 'nova') ? 380 : 350) + 'px'; - dialog._scrollset = true; - } - dialog.getCurrentCapt = function (link, capt, noalph) { - var currentcapt = noalph ? this.currentcapt2 : this.currentcapt; - if (this.seperatelist && noalph) { - if (this.seperatelist[currentcapt].includes(link)) return capt; - return null; - } - if (lib.characterDialogGroup[currentcapt]) { - return lib.characterDialogGroup[currentcapt](link, capt); - } - if (lib.characterPack[currentcapt]) { - if (lib.characterPack[currentcapt][link]) { - return capt; - } - return null; - } - return this.currentcapt; - } - if (str) { - dialog.add(str); - } - dialog.add(node); - if (thisiscard) { - if (seperate) { - seperate = seperate(list); - dialog.seperate = []; - dialog.seperatelist = seperate.list; - if (dialog.seperatelist) { - newlined = document.createElement('div'); - newlined.style.marginTop = '5px'; - newlined.style.display = 'block'; - newlined.style.fontFamily = 'xinwei'; - if (get.is.phoneLayout()) { - newlined.style.fontSize = '32px'; - } - else { - newlined.style.fontSize = '22px'; - } - newlined.style.textAlign = 'center'; - node.appendChild(newlined); - for (var i in dialog.seperatelist) { - var span = document.createElement('span'); - span.style.margin = '3px'; - span.innerHTML = i; - span.link = i; - span.seperate = true; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); - newlined.appendChild(span); - } - } - for (var i in seperate) { - if (i == 'list') continue; - var link = ''; - var linkcontent = seperate[i]; - if (i.includes('_link:')) { - link = i.slice(i.indexOf('_link:') + 6); - i = i.slice(0, i.indexOf('_link:')); - } - var nodesep = dialog.add(i); - nodesep.link = link; - dialog.seperate.push(nodesep); - dialog.add([linkcontent, 'vcard'], noclick); - } - } - else { - dialog.add([list, 'vcard'], noclick); - } - } - else { - if (precharacter) { - dialog.add([list, 'precharacter'], noclick); - } - else if (characterx) { - dialog.add([list, 'characterx'], noclick); - } - else { - dialog.add([list, 'character'], noclick); - } - } - dialog.add(ui.create.div('.placeholder')); - for (i = 0; i < dialog.buttons.length; i++) { - if (thisiscard) { - dialog.buttons[i].capt = getCapt(dialog.buttons[i].link[2]); - } - else { - dialog.buttons[i].group = lib.character[dialog.buttons[i].link][1]; - dialog.buttons[i].capt = getCapt(dialog.buttons[i].link); - } - } - if (!expandall) { - if (!thisiscard && (lib.characterDialogGroup[lib.config.character_dialog_tool] || - lib.config.character_dialog_tool == '自创')) { - clickCapt.call(node[lib.config.character_dialog_tool]); - } - } - return dialog; - } - static dialog() { - let dialog = new lib.element.Dialog(...arguments); - if(!Array.from(arguments).includes('hidden')){ - dialog.open(); - } - return dialog; - } - static line2() { - var node = ui.create.line.apply(this, arguments); - node.classList.add('line2'); - return node; - } - static line() { - var two = false, func; - var node = ui.create.div('.config'); - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string' || typeof arguments[i] == 'number') { - if (two) ui.create.div('.toggle', node).innerHTML = arguments[i]; - else { - ui.create.div(node).innerHTML = arguments[i]; - two = true; - } - } - else if (typeof arguments[i] == 'function') func = arguments[i]; - } - if (func) { - for (var i = 0; i < node.childNodes.length; i++) node.childNodes[i].listen(func); - } - return node; - } - static switcher(name, current, current2) { - var func; - var node = ui.create.div('.config'); - ui.create.div(node).innerHTML = get.translation(name + '_config'); - var switcher = ui.create.div('.toggle.pointerdiv', node); - switcher.name = name; - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'function') { - func = arguments[i]; break; - } - } - if (typeof current == 'string') { - switcher.link = current; - switcher.innerHTML = get.translation(current); - switcher.contentEditable = true; - switcher.style.webkitUserSelect = 'text'; - switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.editor); - } - else if (typeof current == 'object') { - switcher.link = current2 || current[0]; - switcher.innerHTML = get.translation(switcher.link); - switcher.choice = current; - switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.switcher); - } - else { - if (current) { - switcher.classList.add('on'); - } - switcher.classList.add('onoff'); - ui.create.div(ui.create.div(switcher)); - switcher.link = current ? true : false; - switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.toggle); - } - if (func) switcher.additionalCommand = func; - return node; - } - static caption(str, position) { - var caption = ui.create.div('.caption', position); - caption.innerHTML = str; - return caption; - } - static control() { - return new lib.element.Control(...arguments); - } - static confirm(str, func) { - if (ui.confirm && ui.confirm.str == str) { - return; - } - if (str == 'o') { - if (ui.confirm) { - ui.confirm.replace('ok'); - } - else { - ui.confirm = ui.create.control('ok'); - } - } - else if (str == 'oc' || str == 'co') { - if (ui.confirm) { - ui.confirm.replace('ok', 'cancel'); - } - else { - ui.confirm = ui.create.control('ok', 'cancel'); - } - } - else if (str == 'c') { - if (ui.confirm) { - ui.confirm.replace('cancel'); - } - else { - ui.confirm = ui.create.control('cancel'); - } - } - else if (ui.confirm) { - ui.confirm.close(); - delete ui.confirm; - } - if (ui.confirm) { - ui.confirm.str = str; - if (func) ui.confirm.custom = func; - else delete ui.confirm.custom; - } - } - static skills(skills) { - var i, same; - if (ui.skills) { - if (ui.skills.skills.length == skills.length && ui.skills.style.display != 'none') { - same = true; - for (i = 0; i < skills.length; i++) { - if (ui.skills.skills.includes(skills[i]) == false) { - same = false; - break; - } - } - } - if (same) return; - ui.skills.close(); - delete ui.skills; - } - if (skills == undefined || skills.length == 0) return; - if (!_status.event.isMine()) { - _status.noupdatec = true; - } - ui.skills = ui.create.control(skills.concat([ui.click.skill])); - for (var i = 0; i < ui.skills.childNodes.length; i++) { - ui.skills.childNodes[i].innerHTML = get.skillTranslation(ui.skills.childNodes[i].link, _status.event.player); - } - if (!_status.event.isMine()) { - ui.skills.style.display = 'none'; - } - else { - ui.updatec(); - } - _status.noupdatec = false; - ui.skills.skills = skills; - return ui.skills; - } - static skills2(skills) { - var i, same; - if (ui.skills2) { - if (ui.skills2.skills.length == skills.length && ui.skills2.style.display != 'none') { - same = true; - for (i = 0; i < skills.length; i++) { - if (ui.skills2.skills.includes(skills[i]) == false) { - same = false; - break; - } - } - } - if (same) return; - ui.skills2.close(); - delete ui.skills2; - } - if (skills == undefined || skills.length == 0) return; - if (!_status.event.isMine()) { - _status.noupdatec = true; - } - ui.skills2 = ui.create.control(skills.concat([ui.click.skill])); - for (var i = 0; i < ui.skills2.childNodes.length; i++) { - ui.skills2.childNodes[i].innerHTML = get.skillTranslation(ui.skills2.childNodes[i].link, _status.event.player); - } - if (!_status.event.isMine()) { - ui.skills2.style.display = 'none'; - } - else { - ui.updatec(); - } - _status.noupdatec = false; - ui.skills2.skills = skills; - return ui.skills2; - } - static skills3(skills) { - var i, same; - if (ui.skills3) { - if (ui.skills3.skills.length == skills.length && ui.skills3.style.display != 'none') { - same = true; - for (i = 0; i < skills.length; i++) { - if (ui.skills3.skills.includes(skills[i]) == false) { - same = false; - break; - } - } - } - if (same) return; - ui.skills3.close(); - delete ui.skills3; - } - if (skills == undefined || skills.length == 0) return; - if (!_status.event.isMine()) { - _status.noupdatec = true; - } - ui.skills3 = ui.create.control(skills.concat([ui.click.skill])); - for (var i = 0; i < ui.skills3.childNodes.length; i++) { - ui.skills3.childNodes[i].innerHTML = get.skillTranslation(ui.skills3.childNodes[i].link, _status.event.player); - } - if (!_status.event.isMine()) { - ui.skills3.style.display = 'none'; - } - else { - ui.updatec(); - } - _status.noupdatec = false; - ui.skills3.skills = skills; - return ui.skills3; - } - static arena() { - var i, j; - ui.window = ui.create.div('#window.hidden', document.body); - ui.create.div('#statusbg', document.body); - ui.refresh(ui.window); - if (!localStorage.getItem(lib.configprefix + 'playback')) { - ui.window.show(); - } - else { - setTimeout(function () { - ui.window.show(); - }, 1000); - } - // lib.setPressure(ui.window,ui.click.pressurepause); - if (window.isNonameServer) { - ui.window.classList.add('server'); - var serverinfo = ui.create.div('.serverinfo', ui.window); - ui.create.div('', '服务器正在运行', serverinfo); - var serverinfotable = ui.create.table(2, 2, ui.create.div(serverinfo)); - serverinfotable.style.display = 'inline-block'; - serverinfotable.firstChild.firstChild.innerHTML = '房间人数:'; - serverinfotable.firstChild.lastChild.id = 'server_count'; - serverinfotable.firstChild.lastChild.innerHTML = '0'; - serverinfotable.lastChild.firstChild.innerHTML = '房间状态:'; - serverinfotable.lastChild.lastChild.id = 'server_status'; - serverinfotable.lastChild.lastChild.innerHTML = '空闲'; - ui.create.div('.menubutton.large', '关闭服务器', function () { - if (_status.gameStarted && !confirm('关闭服务器当前进行的游戏将终止且不可恢复,是否确定关闭?')) { - return; - } - localStorage.removeItem(lib.configprefix + 'asserver'); - game.reload(); - }, ui.create.div('', serverinfo)); - } - - ui.window.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.window); - ui.system = ui.create.div("#system.", ui.window); - ui.arena = ui.create.div('#arena.nome', ui.window); - if (lib.device == 'ios' && !get.is.phoneLayout()) { - ui.arena.classList.add('ipad'); - } - ui.arena.setNumber = function (num) { - this.dataset.number = num; - ui.updatePlayerPositions(); - // if(game.layout=='nova'&&parseInt(num)<7){ - // ui.arena.classList.add('player_autolong'); - // } - // else if(lib.config.player_height_nova!='long'){ - // ui.arena.classList.remove('player_autolong'); - // } - // if(game.layout=='long'&&parseInt(num)= 3600) { - var num1 = Math.floor(num / 3600); - var num2 = Math.floor((num - num1 * 3600) / 60); - if (num2 < 10) { - num2 = '0' + num2.toString(); - } - var num3 = num - num1 * 3600 - parseInt(num2) * 60; - if (num3 < 10) { - num3 = '0' + num3.toString(); - } - ui.time3.innerHTML = num1 + ':' + num2 + ':' + num3; - } - else { - var num1 = Math.floor(num / 60); - var num2 = num - num1 * 60; - if (num2 < 10) { - num2 = '0' + num2.toString(); - } - ui.time3.innerHTML = num1 + ':' + num2; - } - }, 1000); - } - if (get.is.nomenu()) { - if (!['menu', 'system'].includes(lib.config.round_menu_func)) { - lib.config.round_menu_func = 'system'; - } - } - else if (!lib.config.show_round_menu) { - ui.roundmenu.style.display = 'none'; - } - - var resetround = function (e) { - _status.draggingroundmenu = false; - ui.roundmenu.style.transform = ''; - ui.roundmenu._dragtransform = [0, 0]; - ui.roundmenu.style.transition = 'all 0.3s'; - delete ui.roundmenu._dragtouches; - delete ui.roundmenu._dragorigin; - delete ui.roundmenu._dragorigintransform; - setTimeout(function () { - ui.roundmenu.style.transition = ''; - }, 500); - game.saveConfig('roundmenu_transform', [0, 0]); - if (e) e.stopPropagation(); - return false; - }; - ui.click.resetround = resetround; - if (lib.config.touchscreen) { - ui.roundmenu.addEventListener('touchstart', function (e) { - _status.draggingroundmenu = true; - ui.roundmenu._dragorigin = { - clientX: e.touches[0].clientX, - clientY: e.touches[0].clientY, - }; - if (!ui.roundmenu._dragtransform) { - ui.roundmenu._dragtransform = [0, 0]; - } - ui.roundmenu._dragorigintransform = ui.roundmenu._dragtransform.slice(0); - ui.roundmenu._resetTimeout = setTimeout(function () { - resetround(); - delete ui.roundmenu._resetTimeout; - }, 1000); - }); - } - else { - ui.roundmenu.oncontextmenu = resetround; - } - if (!lib.config.remember_round_button) { - game.saveConfig('roundmenu_transform'); - } - if (lib.config.roundmenu_transform) { - var translate = lib.config.roundmenu_transform; - ui.roundmenu._dragtransform = translate; - ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; - ui.click.checkroundtranslate(); - } - if (get.is.phoneLayout()) { - ui.arena.classList.add('phone'); - } - - ui.sidebar = ui.create.div('#sidebar'); - ui.sidebar3 = ui.create.div('#sidebar3'); - ui.canvas = document.createElement('canvas'); - - ui.arena.appendChild(ui.canvas); - ui.canvas.id = 'canvas'; - ui.ctx = ui.canvas.getContext('2d'); - - ui.sidebar.ontouchstart = ui.click.touchStart; - ui.sidebar.ontouchmove = ui.click.touchScroll; - ui.sidebar.style.webkitOverflowScrolling = 'touch'; - - var zoom; - switch (lib.config.ui_zoom) { - case 'esmall': zoom = 0.8; break; - case 'vsmall': zoom = 0.9; break; - case 'small': zoom = 0.93; break; - case 'big': zoom = 1.05; break; - case 'vbig': zoom = 1.1; break; - case 'ebig': zoom = 1.2; break; - case 'eebig': zoom = 1.5; break; - case 'eeebig': zoom = 1.8; break; - case 'eeeebig': zoom = 2; break; - default: zoom = 1; - } - game.documentZoom = game.deviceZoom * zoom; - if (zoom != 1) { - ui.updatez(); - } - - ui.system1 = ui.create.div('#system1', ui.system); - ui.system2 = ui.create.div('#system2', ui.system); - - ui.replay = ui.create.system('重来', game.reload, true); - ui.replay.id = 'restartbutton'; - ui.config2 = ui.create.system('选项', ui.click.config); - ui.pause = ui.create.system('暂停', ui.click.pause); - ui.pause.id = 'pausebutton'; - if (!_status.video) { - ui.pause.hide(); - } - if (!lib.config.touchscreen) { - lib.setPopped(ui.pause, ui.click.pausehistory, 220, 400, null, true); - } - if (!lib.config.show_pause) { - ui.pause.style.display = 'none'; - } - ui.cardPileButton = ui.create.system('牌堆', null, true); - ui.cardPileButton.style.display = 'none'; - lib.setPopped(ui.cardPileButton, ui.click.cardPileButton, 220); - ui.wuxie = ui.create.system('不询问无懈', ui.click.wuxie, true); - if (!lib.config.touchscreen) { - lib.setPopped(ui.config2, ui.click.pauseconfig, 170); - } - ui.auto = ui.create.system('托管', ui.click.auto); - if (!game.syncMenu) { - ui.config2.classList.add('hidden'); - ui.config2.style.transition = 'all 0.5s'; - ui.roundmenu.classList.add('transparent2'); - - ui.auto.style.opacity = 0.5; - ui.auto.style.transition = 'all 0.5s'; - lib.onfree.push(function () { - ui.auto.style.opacity = ''; - setTimeout(function () { - ui.auto.style.transition = ''; - }, 500); - }); - } - ui.auto.id = 'autobutton'; - ui.autonode = ui.create.div('#autonode', '
      托管中...
      ', ui.arena); - ui.autonode.listen(ui.click.auto); - if (lib.config.mode == 'connect') { - ui.auto.hide(); - ui.pause.hide(); - } - - if (lib.forcehide) { - if (lib.forcehide.includes('replay')) ui.replay.classList.add('forcehide'); - if (lib.forcehide.includes('auto')) ui.auto.classList.add('forcehide'); - if (lib.forcehide.includes('pause')) ui.pause.classList.add('forcehide'); - if (lib.forcehide.includes('wuxie')) ui.wuxie.classList.add('forcehide'); - if (lib.forcehide.includes('cardPileButton')) ui.cardPileButton.classList.add('forcehide'); - } - ui.volumn = ui.create.system('♫'); - lib.setPopped(ui.volumn, ui.click.volumn, 200); - // if(lib.config.show_pause) ui.auto.style.marginLeft='10px'; - if (!lib.config.show_volumn) { - ui.volumn.style.display = 'none'; - } - if (!lib.config.show_auto) { - ui.auto.style.display = 'none'; - } - if (!lib.config.show_wuxie) { - ui.wuxie.style.display = 'none'; - } - // if(!lib.config.show_cardpile||_status.connectMode){ - // ui.cardPileButton.style.display='none'; - // } - - ui.sortCard = ui.create.system('整理手牌', function () { - if (!game.me) return; - var hs = game.me.getCards('h'); - if (!hs.length) return; - game.addVideo('lose', game.me, [get.cardsInfo(hs), [], [], []]); - for (var i = 0; i < hs.length; i++) { - hs[i].goto(ui.special); - } - if (game.me.hasSkillTag('sortCardByNum')) { - var getn = function (card) { - var num = get.number(card, game.me); - if (num < 3) return 13 + num; - return num; - } - hs.sort((a, b) => (getn(b) - getn(a))); - } - else hs.sort(function (b, a) { - if (a.name != b.name) return lib.sort.card(a.name, b.name); - else if (a.suit != b.suit) return lib.suit.indexOf(a) - lib.suit.indexOf(b); - else return a.number - b.number; - }); - game.me.directgain(hs, false); - }); - if (!lib.config.show_sortcard) { - ui.sortCard.style.display = 'none'; - } - ui.playerids = ui.create.system('显示身份', function () { - if (game.showIdentity) { - game.showIdentity(); - _status.identityShown = true; - } - }, true); - if (!lib.config.show_playerids || !game.showIdentity) { - ui.playerids.style.display = 'none'; - } - if (!lib.config.show_replay) { - ui.replay.style.display = 'none'; - } - ui.control = ui.create.div('#control', ui.arena).addTempClass('nozoom'); - ui.cardPile = ui.create.div('#cardPile'); - ui.discardPile = ui.create.div('#discardPile'); - ui.special = ui.create.div('#special'); - ui.ordering = ui.create.div('#ordering'); - ui.dialogs = []; - ui.controls = []; - ui.style = {}; - - ui.time = ui.create.div(ui.gameinfo); - var timeInterval = function () { - var date = new Date(); - var hours = date.getHours(); - var minutes = date.getMinutes(); - if (lib.config.watchface == 'simple') { - ui.roundmenu.childNodes[13].style.transform = 'rotate(' + get.round((hours + 9) * 30, 2) + 'deg)'; - } - else { - ui.roundmenu.childNodes[13].style.transform = 'rotate(' + get.round((hours + minutes / 60 + 9) * 30, 2) + 'deg)'; - } - ui.roundmenu.childNodes[12].style.transform = 'rotate(' + (minutes + 45) * 6 + 'deg)'; - if (minutes < 10) { - minutes = '0' + minutes.toString(); - } - ui.time.innerHTML = hours + ':' + minutes; - }; - _status.timeInterval = setInterval(timeInterval, 30000); - timeInterval(); - if (!lib.config.show_time) { - ui.time.style.display = 'none'; - } - - ui.timer = ui.create.div('.skillbar.shadowed.playerbg.hidden'); - ui.timer.id = 'timer'; - ui.create.div('.skillbarshadow', ui.timer); - ui.create.div('.skillbarfill', ui.timer); - ui.timer.fillnode = ui.create.div(ui.timer.lastChild); - ui.timer.popnode = ui.create.div('.skillbartext', ui.timer); - ui.timer.popnode.style.opacity = 1; - ui.timer.position = 4; - ui.timer.style.zIndex = 5; - ui.timer.set = function (text, percentage) { - if (typeof text == 'string' || typeof text == 'number') { - ui.timer.popnode.innerHTML = text; - } - ui.timer.fillnode.style.top = ((1 - percentage) * 100) + '%'; - } - var setTimerPosition = function (e) { - this.position++; - if (this.position > 4) { - this.position = 1; - } - var left1 = '180px'; - var left2 = 'calc(100% - 245px)'; - var top1 = '210px'; - var top2 = 'calc(100% - 245px)'; - if (game.layout == 'default') { - left1 = '265px'; - top1 = '160px'; - left2 = 'calc(100% - 330px)'; - top2 = 'calc(100% - 235px)'; - } - if (this.position == 1 || this.position == 2) { - this.style.top = top2; - } - else { - this.style.top = top1; - } - if (this.position == 1 || this.position == 4) { - this.style.left = left2; - } - else { - this.style.left = left1; - } - } - ui.timer.listen(setTimerPosition); - - ui.shortcut = ui.create.div('#shortcut.hidden', ui.window); - ui.shortcut.listen(ui.click.shortcut); - ui.create.div(ui.shortcut, function (e) { e.stopPropagation() }); - ui.create.div('.menubutton.round', '重来', ui.shortcut, game.reload).dataset.position = 1; - ui.create.div('.menubutton.round', '退出', ui.shortcut, game.exit).dataset.position = 3; - ui.create.div('.menubutton.round', '记录', ui.shortcut, ui.click.pause).dataset.position = 4; - ui.shortcut.autobutton = ui.create.div('.menubutton.round', '托管', ui.shortcut, ui.click.auto); - ui.shortcut.autobutton.dataset.position = 2; - ui.favmodelist = ui.create.div('.favmodelist', ui.shortcut); - ui.favmodelist.update = function () { - const favouriteMode = lib.config.favouriteMode; - let removed = false; - for (let index = 0; index < favouriteMode.length; index++) { - if (typeof favouriteMode[index] == 'string') continue; - favouriteMode.splice(index--, 1); - if (!removed) removed = true; - } - if (removed) game.saveConfigValue('favouriteMode'); - this.innerHTML = ''; - favouriteMode.slice(0, 6).forEach((value, index) => this.add(value, index)); - let mode = lib.config.mode; - const config = get.config(`${mode}_mode`); - if (typeof config == 'string') mode += `|${config}`; - if (favouriteMode.includes(mode)) ui.favmode.classList.add('glow'); - else ui.favmode.classList.remove('glow'); - }; - ui.favmodelist.add = function (name, index) { - const info = name.split('|'), mode = info[0], submode = info[1], node = ui.create.div('.menubutton.large', this), dataset = node.dataset; - dataset.type = Math.min(6, lib.config.favouriteMode.length) % 2 == 0 ? 'even' : 'odd'; - dataset.position = index; - let str = lib.translate[name] || lib.translate[mode] || ''; - if (str.length == 2) str += '模式'; - node.innerHTML = str; - node.listen(() => { - game.saveConfig('mode', mode); - if (submode) game.saveConfig(`${mode}_mode`, submode, mode); - game.reload(); - }); - }; - ui.favmode = ui.create.system('收藏', function () { - const mode = typeof _status.mode == 'string' ? `${lib.config.mode}|${_status.mode}` : lib.config.mode; - if (this.classList.contains('glow')) { - this.classList.remove('glow'); - lib.config.favouriteMode.remove(mode); - } - else { - this.classList.add('glow'); - lib.config.favouriteMode.add(mode); - } - game.saveConfig('favouriteMode', lib.config.favouriteMode); - ui.favmodelist.update(); - _status.clicked = true; - }); - ui.favmode.style.display = 'none'; - ui.favmodelist.update(); - // ui.create.div('.menubutton.round','菜单',ui.shortcut,ui.click.config).dataset.position=5; - - - if (_status.connectMode) { - ui.playerids.remove(); - ui.pause.innerHTML = '记录'; - } - setTimerPosition.call(ui.timer); - ui.arena.appendChild(ui.timer); - - if (!game.syncMenu) { - lib.onfree.push(function () { - ui.create.menu(); - ui.config2.classList.remove('hidden'); - ui.roundmenu.classList.remove('transparent2'); - setTimeout(function () { - ui.config2.style.transition = ''; - }, 500); - }); - } - else { - ui.create.menu(); - } - - lib.status.date = new Date(); - lib.status.dateDelayed = 0; - - while (lib.arenaReady.length) { - (lib.arenaReady.shift())(); - } - delete lib.arenaReady; - if (lib.config.auto_check_update) { - setTimeout(function () { - game.checkForUpdate(false); - }, 3000); - } - if (!lib.config.asset_version) { - lib.onfree.push(function () { - setTimeout(function () { - if (!game.download) { - game.saveConfig('asset_version', '无'); - } - else { - var func = function () { - if (confirm('是否下载图片和字体素材?(约175MB)')) { - if (!ui.arena.classList.contains('menupaused')) { - ui.click.configMenu(); - ui.click.menuTab('其它'); - } - setTimeout(game.checkForAssetUpdate, 500); - } - else { - game.saveConfig('asset_version', '无'); - } - } - if (_status.new_tutorial) { - _status.new_tutorial = func; - } - else { - func(); - } - } - }, 3000); - }); - } - if (localStorage.getItem(lib.configprefix + 'playback')) { - setTimeout(lib.init.onfree); - } - - if (lib.config.test_game) { - ui.window.classList.add('testing'); - lib.config.game_speed = 'vfast'; - lib.config.low_performance = true; - lib.config.animation = false; - _status.auto = true; - ui.auto.classList.add('glow'); - setTimeout(function () { - var node = ui.create.pause().addTempClass('start'); - node.appendChild(ui.sidebar); - node.firstChild.innerHTML = '正在测试'; - node.removeEventListener('click', ui.click.resume); - }, 500); - } - } - static system(str, func, right, before) { - var parent = right ? ui.system2 : ui.system1; - var node = ui.create.div(); - if (before) { - parent.insertBefore(node, parent.firstChild); - } - else { - parent.appendChild(node); - } - node.innerHTML = str; - if (func) { - node.listen(func); - } - if (lib.config.button_press) { - node.addEventListener(lib.config.touchscreen ? 'touchstart' : 'mousedown', function (e) { - if (!node.classList.contains('hidden')) node.classList.add('pressdown'); - }); - node.addEventListener(lib.config.touchscreen ? 'touchend' : 'mouseup', function (e) { - node.classList.remove('pressdown'); - }); - node.addEventListener(lib.config.touchscreen ? 'touchmove' : 'mousemove', function (e) { - node.classList.remove('pressdown'); - }); - } - return node; - } - static pause() { - if (_status.pausing) return; - ui.click.shortcut(false); - var node = ui.create.div(".pausedbg", ui.window); - _status.pausing = true; - setTimeout(function () { - _status.pausing = false; - }, 500); - if (lib.config.touchscreen) { - setTimeout(function () { - node.addEventListener('touchend', ui.click.resume); - }, 500); - } - else { - node.addEventListener('click', ui.click.resume); - } - if (!lib.config.touchscreen) { - node.oncontextmenu = ui.click.resume; - } - - var node2 = ui.create.div(node); - if (_status.connectMode) { - node2.innerHTML = ''; - } - else { - node2.innerHTML = '已暂停'; - } - - // node2.listen(function(){ - // _status.clicked=true; - // if(ui.sidebar.classList.contains('hidden')){ - // ui.sidebar.show(); - // ui.sidebar3.show(); - // } - // else{ - // ui.sidebar.hide(); - // ui.sidebar3.hide(); - // } - // }); - return node; - } - static prebutton(item, type, position, noclick) { - var node = ui.create.div(position); - node.style.display = 'none'; - node.link = item; - node.activate = function () { - ui.create.button(item, type, position, noclick, node); - delete node.activate; - } - _status.prebutton.push(node); - return node; - } - static buttonPresets = { - /** - * @returns { import("../library/index.js").Button } - */ - tdnodes: (item, type, position, noclick, node) => { - node = ui.create.div('.shadowed.reduce_radius.pointerdiv.tdnode.tdnodes', position); - if (Array.isArray(item)) { - node.innerHTML = '' + (item[1]) + ''; - node.link = item[0]; - } - else { - node.innerHTML = '' + (item) + ''; - node.link = item; - } - return node; - }, - /** - * @returns { import("../library/index.js").Button } - */ - blank: (item, type, position, noclick, node) => { - node = ui.create.div('.button.card', position); - node.link = item; - return node; - }, - /** - * @returns { import("../library/index.js").Button } - */ - card: (item, type, position, noclick, node) => { - if (typeof item.copy == 'function') { - node = item.copy(false); - } - else { - node = item.cloneNode(true); - } - node.classList.add('button'); - if (position) position.appendChild(node); - node.link = item; - if (item.style.backgroundImage) { - node.style.backgroundImage = item.style.backgroundImage; - node.style.backgroundSize = 'cover'; - } - if (item.style.color) { - node.style.color = item.style.color; - } - if (item.nature) { - let natures = get.natureList(item.nature); - natures.forEach(n => node.classList.add(n)); - } - if (!noclick) { - lib.setIntro(node); - } - if (get.position(item) == 'j' && item.viewAs && item.viewAs != item.name && lib.config.cardtempname != 'off') { - ui.create.cardTempName(item, node); - } - return node; - }, - /** - * @returns { import("../library/index.js").Button } - */ - vcard: (item, type, position, noclick, node) => { - if (typeof item == 'string') { - item = [get.type(item), '', item]; - } - node = ui.create.card(position, 'noclick', noclick); - node.classList.add('button'); - node.init(item); - node.link = item; - return node; - }, - /** - * @returns { import("../library/index.js").Button } - */ - character: (item, type, position, noclick, node) => { - if (node) { - node.classList.add('button'); - node.classList.add('character'); - node.style.display = ''; - } - else { - node = ui.create.div('.button.character', position); - } - node._link = item; - if (_status.noReplaceCharacter && type == 'characterx') type = 'character'; - if (type == 'characterx') { - if (lib.characterReplace[item] && lib.characterReplace[item].length) item = lib.characterReplace[item].randomGet(); - } - node.link = item; - - var double = get.is.double(node._link, true); - if (double) node._changeGroup = true; - if (type == 'characterx' && lib.characterReplace[node._link] && lib.characterReplace[node._link].length > 1) node._replaceButton = true; - var func = function (node, item) { - node.setBackground(item, 'character'); - if (node.node) { - node.node.name.remove(); - node.node.hp.remove(); - node.node.group.remove(); - node.node.intro.remove(); - if (node.node.replaceButton) node.node.replaceButton.remove(); - } - node.node = { - name: ui.create.div('.name', node), - hp: ui.create.div('.hp', node), - group: ui.create.div('.identity', node), - intro: ui.create.div('.intro', node), - }; - var infoitem = lib.character[item]; - if (!infoitem) { - for (var itemx in lib.characterPack) { - if (lib.characterPack[itemx][item]) { - infoitem = lib.characterPack[itemx][item]; break; - } - } - } - node.node.name.innerHTML = get.slimName(item); - if (lib.config.buttoncharacter_style == 'default' || lib.config.buttoncharacter_style == 'simple') { - if (lib.config.buttoncharacter_style == 'simple') { - node.node.group.style.display = 'none'; - } - node.classList.add('newstyle'); - node.node.name.dataset.nature = get.groupnature(get.bordergroup(infoitem)); - node.node.group.dataset.nature = get.groupnature(get.bordergroup(infoitem), 'raw'); - ui.create.div(node.node.hp); - var hp = get.infoHp(infoitem[2]), maxHp = get.infoMaxHp(infoitem[2]), hujia = get.infoHujia(infoitem[2]); - var str = get.numStr(hp); - if (hp != maxHp) { - str += '/'; - str += get.numStr(maxHp); - } - var textnode = ui.create.div('.text', str, node.node.hp); - if (infoitem[2] == 0) { - node.node.hp.hide(); - } - else if (get.infoHp(infoitem[2]) <= 3) { - node.node.hp.dataset.condition = 'mid'; - } - else { - node.node.hp.dataset.condition = 'high'; - } - if (hujia > 0) { - ui.create.div(node.node.hp, '.shield'); - ui.create.div('.text', get.numStr(hujia), node.node.hp); - } - } - else { - var hp = get.infoHp(infoitem[2]); - var maxHp = get.infoMaxHp(infoitem[2]); - var shield = get.infoHujia(infoitem[2]); - if (maxHp > 14) { - if (typeof infoitem[2] == 'string') node.node.hp.innerHTML = infoitem[2]; - else node.node.hp.innerHTML = get.numStr(infoitem[2]); - node.node.hp.classList.add('text'); - } - else { - for (var i = 0; i < maxHp; i++) { - var next = ui.create.div('', node.node.hp); - if (i >= hp) next.classList.add('exclude'); - } - for (var i = 0; i < shield; i++) { - ui.create.div(node.node.hp, '.shield'); - } - } - } - if (node.node.hp.childNodes.length == 0) { - node.node.name.style.top = '8px'; - } - if (node.node.name.querySelectorAll('br').length >= 4) { - node.node.name.classList.add('long'); - if (lib.config.buttoncharacter_style == 'old') { - node.addEventListener('mouseenter', ui.click.buttonnameenter); - node.addEventListener('mouseleave', ui.click.buttonnameleave); - } - } - node.node.intro.innerHTML = lib.config.intro; - if (!noclick) { - lib.setIntro(node); - } - if (infoitem[1]) { - if (double) { - node.node.group.innerHTML = double.reduce((previousValue, currentValue) => `${previousValue}
      ${get.translation(currentValue)}
      `, ''); - if (double.length > 4) if (new Set([5, 6, 9]).has(double.length)) node.node.group.style.height = '48px'; - else node.node.group.style.height = '64px'; - } - else node.node.group.innerHTML = `
      ${get.translation(infoitem[1])}
      `; - node.node.group.style.backgroundColor = get.translation(`${get.bordergroup(infoitem)}Color`); - } - else { - node.node.group.style.display = 'none'; - } - if (node._replaceButton) { - var intro = ui.create.div('.button.replaceButton', node); - node.node.replaceButton = intro; - intro.innerHTML = '切换'; - intro._node = node; - intro.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function () { - _status.tempNoButton = true; - var node = this._node; - var list = lib.characterReplace[node._link]; - var link = node.link; - var index = list.indexOf(link); - if (index == list.length - 1) index = 0; - else index++; - link = list[index]; - node.link = link; - node.refresh(node, link); - setTimeout(function () { - delete _status.tempNoButton; - }, 200); - }); - } - }; - node.refresh = func; - node.refresh(node, item); - - return node; - }, - /** - * @returns { import("../library/index.js").Button } - */ - characterx: (item, type, position, noclick, node) => { - return ui.create.buttonPresets.character(item, type, position, noclick, node); - }, - /** - * @returns { import("../library/index.js").Button } - */ - player: (item, type, position, noclick, node) => { - if (node) { - node.classList.add('button'); - node.classList.add('character'); - node.style.display = ''; - } - else { - node = ui.create.div('.button.character', position); - } - node._link = item; - node.link = item; - node.node = { - name: ui.create.div('.name', node), - intro: ui.create.div('.intro', node) - } - if (item.name && item.name.startsWith('unknown')) { - if (item.node && item.node.name_seat) { - node.classList.add('cardbg'); - ui.create.div('.avatar_name', node, get.translation(item.name)); - } - else { - node.setBackground(item.name1, 'character'); - } - } - else { - node.setBackground(item.name, 'character'); - } - return node; - } - } - static button(item, type, position, noClick, button) { return new lib.element.Button(item, type, position, noClick, button) } - static buttons(list, type, position, noclick, zoom) { - var buttons = []; - var pre = (typeof type == 'string' && type.slice(0, 3) == 'pre'); - if (pre) { - if (!_status.prebutton) { - _status.prebutton = []; - lib.onfree.push(function () { - for (var i = 0; i < _status.prebutton.length; i++) { - if (_status.prebutton[i].activate) { - _status.prebutton[i].activate(); - } - } - delete _status.prebutton; - }); - } - } - var fragment = document.createDocumentFragment(); - for (var i = 0; i < list.length; i++) { - if (pre) { - buttons.push(ui.create.prebutton(list[i], type.slice(3), fragment, noclick)); - } - else { - buttons.push(ui.create.button(list[i], type, fragment, noclick)); - } - } - if (position) position.appendChild(fragment); - return buttons; - } - static textbuttons(list, dialog, noclick) { - for (var item of list) { - var str, link; - if (Array.isArray(item)) { - str = item[1]; - link = item[0]; - } - else { - str = item; - link = item; - } - if (!str.startsWith(''; - var next = dialog.add(str); - if (!noclick) next.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.button); - next.firstChild.link = link; - Object.setPrototypeOf(next, lib.element.Button.prototype); - dialog.buttons.add(next.firstChild); - } - } - static player(position, noclick) { return new lib.element.Player(position).build(noclick); } - static connectPlayers(ip) { - ui.updateConnectPlayerPositions(); - game.connectPlayers = []; - const configOL = lib.configOL; - const numberOfPlayers = parseInt(configOL.player_number) || configOL.number; - for (let position = 0; position < numberOfPlayers; position++) { - const player = ui.create.player(ui.window); - player.dataset.position = position; - player.classList.add('connect'); - game.connectPlayers.push(player); - } - - var bar = ui.create.div(ui.window); - bar.style.height = '20px'; - bar.style.width = '80%'; - bar.style.left = '10%'; - bar.style.top = 'calc(200% / 7 - 120px + 5px)'; - bar.style.textAlign = 'center'; - var ipbar = ui.create.div('.shadowed', ip, bar); - ipbar.style.padding = '4px'; - ipbar.style.borderRadius = '2px'; - ipbar.style.position = 'relative'; - - var button = ui.create.div('.menubutton.large.highlight.connectbutton.connectbutton1.pointerdiv', game.online ? '退出联机' : '开始游戏', ui.window, function () { - if (button.clicked) return; - if (game.online) { - if (game.onlinezhu) { - game.send('startGame'); - } - else { - game.saveConfig('tmp_owner_roomId'); - game.saveConfig('tmp_user_roomId'); - game.saveConfig('reconnect_info'); - game.reload(); - } - } - else { - var num = 0; - for (var i of game.connectPlayers) { - if (!i.nickname && !i.classList.contains('unselectable2')) num++; - } - if (num >= lib.configOL.number - 1) { - alert('至少要有两名玩家才能开始游戏!'); - return; - } - game.resume(); - } - button.delete(); - bar.delete(); - shareButton.delete(); - delete ui.connectStartButton; - delete ui.connectStartBar; - delete ui.connectShareButton; - button.clicked = true; - }); - - var shareButton = ui.create.div('.menubutton.large.highlight.connectbutton.connectbutton2.pointerdiv', '分享房间', ui.window, function () { - var text = `无名杀-联机-${lib.translate[get.mode()]}-${game.connectPlayers.filter(p => p.avatar).length}/${game.connectPlayers.filter(p => !p.classList.contains('unselectable2')).length}\n${get.connectNickname()}邀请你加入${game.roomId}房间\n联机地址:${game.ip}\n请先通过游戏内菜单-开始-联机中启用“读取邀请链接”选项`; - window.focus(); - if (navigator.clipboard && lib.node) { - navigator.clipboard.writeText(text).then(() => { - game.alert(`分享内容复制成功`); - }).catch(e => { - game.alert(`分享内容复制失败${e || ''}`); - }); - } else { - var input = ui.create.node('textarea', ui.window, { opacity: '0' }); - input.value = text; - input.focus(); - input.select(); - var result = document.execCommand('copy'); - input.blur(); - ui.window.removeChild(input); - game.alert(`分享内容复制${result ? '成功' : '失败'}`); - } - }); - - ui.connectStartButton = button; - ui.connectStartBar = bar; - ui.connectShareButton = shareButton; - } - static players(numberOfPlayers) { - if (numberOfPlayers === 0) { - return; - } - if (numberOfPlayers == undefined) numberOfPlayers = lib.configOL.number; - if (numberOfPlayers == undefined) numberOfPlayers = get.playerNumber(); - if (typeof numberOfPlayers == 'string') { - numberOfPlayers = parseInt(numberOfPlayers); - } - if (!numberOfPlayers) numberOfPlayers = 5; - for (let ordinal = 0; ordinal < numberOfPlayers; ordinal++) { - const player = ui.create.player().addTempClass('start'); - game.players.push(player); - player.dataset.position = ordinal; - } - const players = game.players; - for (let ordinal = 0; ordinal < players.length; ordinal++) { - if (ordinal > 0) { - players[ordinal].previous = players[ordinal - 1]; - players[ordinal].previousSeat = players[ordinal - 1]; - } - if (ordinal < players.length - 1) { - players[ordinal].next = players[ordinal + 1]; - players[ordinal].nextSeat = players[ordinal + 1]; - } - } - players[0].previous = players[players.length - 1]; - players[0].previousSeat = players[players.length - 1]; - players[players.length - 1].next = players[0]; - players[players.length - 1].nextSeat = players[0]; - ui.arena.setNumber(numberOfPlayers); - players.forEach(player => ui.arena.appendChild(player)); - return players; - } - static me(hasme) { - ui.mebg = ui.create.div('#mebg', ui.arena); - ui.me = ui.create.div('#me', ui.arena).addTempClass('start'); - ui.handcards1Container = ui.create.div('#handcards1', ui.me); - ui.handcards2Container = ui.create.div('#handcards2', ui.me); - ui.arena.classList.remove('nome'); - if (lib.config.mousewheel && !lib.config.touchscreen) { - ui.handcards1Container.onmousewheel = ui.click.mousewheel; - ui.handcards2Container.onmousewheel = ui.click.mousewheel; - } - ui.handcards1Container.ontouchstart = ui.click.touchStart; - ui.handcards2Container.ontouchstart = ui.click.touchStart; - ui.handcards1Container.ontouchmove = ui.click.touchScroll; - ui.handcards2Container.ontouchmove = ui.click.touchScroll; - ui.handcards1Container.style.webkitOverflowScrolling = 'touch'; - ui.handcards2Container.style.webkitOverflowScrolling = 'touch'; - - if (hasme && game.me) { - ui.handcards1 = game.me.node.handcards1; - ui.handcards2 = game.me.node.handcards2; - ui.handcards1Container.appendChild(ui.handcards1); - ui.handcards2Container.appendChild(ui.handcards2); - // ui.updatehl(); - } - else if (game.players.length) { - game.me = game.players[0]; - ui.handcards1 = game.me.node.handcards1; - ui.handcards2 = game.me.node.handcards2; - ui.handcards1Container.appendChild(ui.handcards1); - ui.handcards2Container.appendChild(ui.handcards2); - // ui.updatehl(); - } - } - static card(position, info, noclick) { return new lib.element.Card(position).build(info, noclick);} - static cardsAsync() { - if (lib.onfree) { - _status.waitingForCards = Array.from(arguments); - lib.onfree.push(function () { - if (_status.waitingForCards) { - ui.create.cards.apply(ui.create, _status.waitingForCards); - delete _status.waitingForCards; - } - }); - } - else { - ui.create.cards.apply(ui.create, arguments); - } - } - static cards(ordered) { - if (_status.brawl) { - if (_status.brawl.cardPile) { - lib.card.list = _status.brawl.cardPile(lib.card.list); - } - if (_status.brawl.orderedPile) { - ordered = true; - } - } - if (!ordered) { - lib.card.list.randomSort(); - } - for (var i = 0; i < lib.card.list.length; i++) { - if (lib.card[lib.card.list[i][2]]) { - if (!lib.card.list[i]._replaced) { - if (!_status.connectMode) { - if (lib.config.bannedcards.includes(lib.card.list[i][2])) continue; - } - else { - if (lib.configOL.bannedcards.includes(lib.card.list[i][2])) continue; - } - if (game.bannedcards && game.bannedcards.includes(lib.card.list[i][2])) continue; - } - lib.inpile.add(lib.card.list[i][2]); - if (lib.card.list[i][2] == 'sha' && lib.card.list[i][3]) lib.inpile_nature.add(lib.card.list[i][3]); - ui.create.card(ui.cardPile).init(lib.card.list[i]); - } - } - lib.inpile.sort(lib.sort.card); - const natures = Array.from(lib.nature.keys()); - lib.inpile_nature.sort(function (a, b) { - return natures.indexOf(a) - natures.indexOf(b); - }) - for (var i in _status.cardtag) { - if (!_status.cardtag[i].length) delete _status.cardtag[i]; - } - game.broadcastAll(function (num, pile, top, cardtag, inpile2) { - if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = '0轮 剩余牌: ' + num; - lib.inpile = pile; - _status.pileTop = top; - _status.cardtag = cardtag; - lib.inpile_nature = inpile2; - }, ui.cardPile.childNodes.length, lib.inpile, ui.cardPile.firstChild, _status.cardtag, lib.inpile_nature); - } - -} - -class Click extends Uninstantable { - static identitycircle() { - var list = []; - this.classList.toggle('transparent'); - for (var i = 0; i < this.parentNode.childNodes.length; i++) { - if (!this.parentNode.childNodes[i].classList.contains('transparent')) { - list.add(this.parentNode.childNodes[i].link[2]); - } - } - var info = this.link; - if (list.length == 1) { - for (var i = 0; i < this.parentNode.childNodes.length; i++) { - if (!this.parentNode.childNodes[i].classList.contains('transparent')) { - var info2 = this.parentNode.childNodes[i].link; - info[0].firstChild.innerHTML = info2[1]; - info[0].dataset.color = info2[2]; - } - } - } - else { - info[0].firstChild.innerHTML = ''; - info[0].dataset.color = ''; - ui.create.identitycircle(list, info[0].firstChild); - } - this._source._guozhanguess = list; - } - static connectEvents() { - if (this.info) { - var button = this; - var layer = ui.create.div('.poplayer', ui.window); - var uiintro = ui.create.dialog('hidden', 'notouchscroll'); - this.classList.add('active'); - if (lib.config.touchscreen) { - lib.setScroll(uiintro.contentContainer); - } - layer.listen(function () { - if (this.clicked) { - this.clicked = false; - return; - } - button.classList.remove('active'); - uiintro.delete(); - this.delete(); - }); - uiintro.listen(function () { - _status.clicked = true; - }); - uiintro.style.zIndex = 21; - uiintro.classList.add('popped'); - uiintro.classList.add('static'); - uiintro.classList.add('onlineclient'); - uiintro.style.width = '180px'; - uiintro.style.height = '300px'; - uiintro.style.left = 'auto'; - uiintro.style.right = '20px'; - uiintro.style.top = 'auto'; - uiintro.style.bottom = '75px'; - - uiintro.refresh = function () { - if (button.focused) return; - uiintro.content.innerHTML = ''; - uiintro.addText('创建约战'); - button.textnode = uiintro.content.lastChild.lastChild; - uiintro.add(''); - uiintro.content.lastChild.style.paddingTop = 0; - button.input = uiintro.content.lastChild.lastChild; - button.input.onfocus = function () { - button.focused = true; - } - button.input.onblur = function () { - delete button.focused; - } - if (button.interval) { - button.input.disabled = true; - button.input.style.opacity = 0.6; - if (button.intervaltext) { - button.textnode.innerHTML = button.intervaltext; - } - } - var datenode = ui.create.div(uiintro.content); - datenode.style.marginTop = 0; - datenode.style.whiteSpace = 'nowrap'; - var date = new Date(); - var days = []; - var currentDay = date.getDay(); - if (currentDay == 0) currentDay = 7; - for (var i = 1; i <= 7; i++) { - if (i < currentDay) { - days.push([i.toString(), '下周' + get.cnNumber(i, true)]); - } - else if (i == 7) { - days.push([i.toString(), '周日']); - } - else if (i == currentDay) { - days.push([i.toString(), '今天']); - } - else { - days.push([i.toString(), '周' + get.cnNumber(i, true)]); - } - } - days = days.concat(days.splice(0, currentDay - 1)); - var initday = currentDay + 1; - if (initday > 7) { - initday -= 7; - } - var daysselect = ui.create.selectlist(days, initday.toString(), datenode); - daysselect.style.width = '55px'; - var hours = []; - for (var i = 0; i < 24; i++) { - hours.push([i.toString(), i.toString() + '点']); - } - var hoursselect = ui.create.selectlist(hours, date.getHours().toString(), datenode); - hoursselect.style.marginLeft = '5px'; - hoursselect.style.width = '55px'; - var timeconfirm = ui.create.node('button', '确定', datenode); - timeconfirm.style.marginLeft = '5px'; - timeconfirm.onclick = function () { - if (!button.input.value) { - alert('请填写约战标题'); - return; - } - var date2 = new Date(); - date2.setHours(parseInt(hoursselect.value)); - date2.setMinutes(0); - date2.setSeconds(0); - var deltaday = parseInt(daysselect.value) - currentDay; - if (deltaday < 0) { - deltaday += 7; - } - var utc = date2.getTime() + deltaday * 24 * 3600000; - if (utc < date.getTime()) { - alert('创建失败,时间已过'); - return; - } - if (get.is.banWords(button.input.value)) { - var eventnode = ui.create.div('.menubutton.videotext.onlineevent.pointerdiv', function () { - var that = this; - setTimeout(function () { - if (that.classList.contains('active')) { - if (confirm('确定要离开' + that.info.content + '?')) { - that.classList.remove('active'); - } - } - else { - if (confirm('确定要加入' + that.info.content + '?')) { - that.classList.add('active'); - } - } - }); - }, uiintro.content, 4); - var fakeinfo = { - utc: utc, - day: parseInt(daysselect.value), - hour: parseInt(hoursselect.value), - nickname: get.connectNickname(), - avatar: lib.config.connect_avatar, - content: button.input.value, - create: game.onlineKey, - members: [game.onlineKey], - }; - eventnode.info = fakeinfo; - ui.create.div('.title', fakeinfo.content, eventnode); - var str; - if (fakeinfo.day < currentDay) { - str = '下周'; - } - else { - str = '周'; - } - if (fakeinfo.day == 7) { - str += '日' - } - else { - str += get.cnNumber(fakeinfo.day, true); - } - str += ' '; - var hour = fakeinfo.hour; - if (hour <= 12) { - if (hour <= 5) { - str += '凌晨'; - } - else if (hour < 12) { - str += '上午'; - } - else { - str += '中午'; - } - str += fakeinfo.hour + '点'; - } - else { - if (hour <= 17) { - str += '下午'; - } - else { - str += '晚上'; - } - str += (fakeinfo.hour - 12) + '点'; - } - ui.create.div('', '已有' + (fakeinfo.members.length) + '人加入', eventnode); - ui.create.div('', '时间:' + str, eventnode); - if (fakeinfo.members.includes(game.onlineKey)) { - eventnode.classList.add('active'); - } - button.input.value = ''; - return; - } - game.send('server', 'events', { - utc: utc, - day: parseInt(daysselect.value), - hour: parseInt(hoursselect.value), - nickname: get.connectNickname(), - avatar: lib.config.connect_avatar, - content: button.input.value - }, game.onlineKey); - }; - - var num = 0; - for (var i = 0; i < button.info.length; i++) { - if (typeof button.info[i].creator == 'string' && button.info[i].creator != game.onlineKey && get.is.banWords(button.info[i].content)) continue; - if (button.info[i].creator == game.onlineKey) { - num++; - } - var eventnode = ui.create.div('.menubutton.videotext.onlineevent.pointerdiv', function () { - var that = this; - if (typeof that.info.creator != 'string') return; - setTimeout(function () { - if (that.classList.contains('active')) { - if (confirm('确定要离开' + that.info.content + '?')) { - game.send('server', 'events', that.info.id, game.onlineKey, 'leave'); - } - } - else { - if (confirm('确定要加入' + that.info.content + '?')) { - game.send('server', 'events', that.info.id, game.onlineKey, 'join'); - } - } - }); - }, uiintro.content); - eventnode.info = button.info[i]; - if (typeof button.info[i].creator == 'string') { - ui.create.div('.title', button.info[i].content, eventnode); - var str; - if (button.info[i].day < currentDay) { - str = '下周'; - } - else { - str = '周'; - } - if (button.info[i].day == 7) { - str += '日' - } - else { - str += get.cnNumber(button.info[i].day, true); - } - str += ' '; - var hour = button.info[i].hour; - if (hour <= 12) { - if (hour <= 5) { - str += '凌晨'; - } - else if (hour < 12) { - str += '上午'; - } - else { - str += '中午'; - } - str += button.info[i].hour + '点'; - } - else { - if (hour <= 17) { - str += '下午'; - } - else { - str += '晚上'; - } - str += (button.info[i].hour - 12) + '点'; - } - ui.create.div('', '创建者:' + (button.info[i].nickname), eventnode); - //ui.create.div('','创建者:'+(button.info[i].nickname)+'
      ID:'+button.info[i].creator,eventnode); - ui.create.div('', '已有' + (button.info[i].members.length) + '人加入', eventnode); - ui.create.div('', '时间:' + str, eventnode); - if (button.info[i].members.includes(game.onlineKey)) { - eventnode.classList.add('active'); - } - } - else { - ui.create.div('.title', button.info[i].title, eventnode); - ui.create.div('', button.info[i].content, eventnode); - ui.create.div('', '创建者:' + (button.info[i].nickname), eventnode); - } - } - if (num >= 3) { - button.input.disabled = true; - button.input.style.opacity = 0.6; - hoursselect.disabled = true; - daysselect.disabled = true; - timeconfirm.disabled = true; - } - } - uiintro.refresh(); - ui.window.appendChild(uiintro); - _status.connectEventsCallback = function () { - if (uiintro.parentNode == ui.window) { - uiintro.refresh(); - } - }; - } - } - static connectClients() { - if (this.info) { - var button = this; - var layer = ui.create.div('.poplayer', ui.window); - var uiintro = ui.create.dialog('hidden', 'notouchscroll'); - this.classList.add('active'); - if (lib.config.touchscreen) { - lib.setScroll(uiintro.contentContainer); - } - layer.listen(function () { - if (this.clicked) { - this.clicked = false; - return; - } - button.classList.remove('active'); - uiintro.delete(); - this.delete(); - }); - uiintro.listen(function () { - _status.clicked = true; - }); - uiintro.style.zIndex = 21; - uiintro.classList.add('popped'); - uiintro.classList.add('static'); - uiintro.classList.add('onlineclient'); - uiintro.style.width = '180px'; - uiintro.style.height = '300px'; - uiintro.style.left = 'auto'; - uiintro.style.right = '20px'; - uiintro.style.top = 'auto'; - uiintro.style.bottom = '75px'; - - uiintro.refresh = function () { - if (button.focused) return; - uiintro.content.innerHTML = ''; - uiintro.addText('发状态'); - button.textnode = uiintro.content.lastChild.lastChild; - uiintro.add(''); - uiintro.content.lastChild.style.paddingTop = 0; - button.input = uiintro.content.lastChild.lastChild; - button.input.onfocus = function () { - button.focused = true; - } - button.input.onblur = function () { - delete button.focused; - } - if (button.interval) { - button.input.disabled = true; - button.input.style.opacity = 0.6; - if (button.intervaltext) { - button.textnode.innerHTML = button.intervaltext; - } - } - button.input.onkeydown = function (e) { - if (e.keyCode == 13 && !this.disabled) { - game.send('server', 'status', this.value); - this.blur(); - this.disabled = true; - this.style.opacity = 0.6; - button.textnode.innerHTML = '发状态(10)'; - button.intervaltext = button.textnode.innerHTML; - var num = 10; - var that = this; - button.input.disabled = true; - button.input.style.opacity = 0.6; - this.value = ''; - button.interval = setInterval(function () { - num--; - if (num > 0) { - button.textnode.innerHTML = '发状态(' + num + ')'; - button.intervaltext = button.textnode.innerHTML; - } - else { - button.textnode.innerHTML = '发状态'; - button.input.disabled = false; - button.input.style.opacity = ''; - clearInterval(button.interval); - delete button.interval; - delete button.intervaltext; - } - }, 1000); - } - } - - for (var i = 0; i < button.info.length; i++) { - var node = ui.create.div('.menubutton.videonode.pointerdiv', uiintro.content); - ui.create.div('.menubutton.videoavatar', node).setBackground(button.info[i][1] || 'caocao', 'character'); - if (button.info[i][4] == game.wsid) { - ui.create.div('.name', '' + (button.info[i][0] || '无名玩家'), node); node.isme = true; - } - else if (button.info[i][2]) { - ui.create.div('.name', (button.info[i][0] || '无名玩家'), node); - } - else { - ui.create.div('.name', '' + (button.info[i][0] || '无名玩家'), node); - } - //show ID - //ui.create.div('.videostatus',node,button.info[i][5]); - //node.classList.add('videonodestatus'); - if (button.info[i][3]) { - ui.create.div('.videostatus', node, button.info[i][3].slice(0, 80)); - node.classList.add('videonodestatus') - } - } - }; - - uiintro.refresh(); - ui.window.appendChild(uiintro); - _status.connectClientsCallback = function () { - if (uiintro.parentNode == ui.window) { - uiintro.refresh(); - } - }; - } - } - static autoskin() { - if (!lib.config.change_skin) return; - var players = game.filterPlayer(); - var change = function (player, num, callback) { - if (num == '1') { - ui.click.skin(player.node.avatar, player.name, callback); - } - else { - ui.click.skin(player.node.avatar2, player.name2, callback); - } - }; - var finish = function () { - if (lib.config.change_skin_auto != 'off') { - _status.skintimeout = setTimeout(ui.click.autoskin, parseInt(lib.config.change_skin_auto)); - } - }; - var autoskin = function () { - if (players.length) { - var player = players.randomRemove(); - var list = []; - if (player.name && !player.isUnseen(0)) { - list.push('1'); - } - if (player.name2 && !player.isUnseen(1)) { - list.push('2'); - } - if (list.length) { - change(player, list.randomRemove(), function (bool) { - if (bool) { - finish(); - } - else if (list.length) { - change(player, list[0], function (bool) { - if (bool) { - finish(); - } - else { - autoskin(); - } - }); - } - else { - autoskin(); - } - }); - } - else { - autoskin(); - } - } - } - autoskin(); - } - static skin(avatar, name, callback) { - var num = 1; - if (name.startsWith('gz_')) { - name = name.slice(3); - } - if (lib.config.skin[name]) { - num = lib.config.skin[name] + 1; - } - var fakeavatar = avatar.cloneNode(true); - var finish = function (bool) { - var player = avatar.parentNode; - if (bool) { - fakeavatar.style.boxShadow = 'none'; - player.insertBefore(fakeavatar, avatar.nextSibling); - setTimeout(function () { - fakeavatar.delete(); - }, 100); - } - if (bool && lib.config.animation && !lib.config.low_performance) { - player.$rare(); - } - if (callback) { - callback(bool); - } - } - var img = new Image(); - img.onload = function () { - lib.config.skin[name] = num; - game.saveConfig('skin', lib.config.skin); - avatar.style.backgroundImage = 'url("' + img.src + '")'; - finish(true); - } - img.onerror = function () { - if (lib.config.skin[name]) { - finish(true); - } - else { - finish(false); - } - delete lib.config.skin[name]; - game.saveConfig('skin', lib.config.skin); - avatar.setBackground(name, 'character'); - } - img.src = lib.assetURL + 'image/skin/' + name + '/' + num + '.jpg'; - } - static touchpop(forced) { - if (lib.config.touchscreen || forced) { - _status.touchpopping = true; - clearTimeout(_status.touchpoppingtimeout); - _status.touchpoppingtimeout = setTimeout(function () { - _status.touchpopping = false; - }, 600); - } - } - static exit() { - if (game.servermode && lib.config.reconnect_info && _status.over) { - if (!_status.roomtimeout) { - lib.config.reconnect_info[2] = game.roomId; - game.saveConfig('reconnect_info', lib.config.reconnect_info); - } - game.reload(); - return; - } - else { - if (typeof game.roomId != 'string') { - game.saveConfig('reconnect_info'); - } - } - if (!ui.exit || !ui.exit.stay) { - if (lib.config.reconnect_info) { - lib.config.reconnect_info.length = 1; - game.saveConfig('reconnect_info', lib.config.reconnect_info); - } - game.saveConfig('tmp_user_roomId', undefined, false, function () { - game.reload(); - }); - } - else { - game.reload(); - } - } - static shortcut(show) { - if (show === false) { - ui.shortcut.classList.add('hidden'); - } - else { - ui.shortcut.classList.toggle('hidden'); - } - if (ui.shortcut.classList.contains('hidden')) { - ui.favmode.style.display = 'none'; - if (window.StatusBar && lib.config.show_statusbar_ios == 'auto') { - document.body.classList.remove('statusbar'); - window.StatusBar.hide(); - } - ui.window.classList.remove('shortcutpaused'); - } - else { - if (lib.config.show_favmode) { - ui.favmode.style.display = ''; - } - if (window.StatusBar && lib.config.show_statusbar_ios == 'auto') { - document.body.classList.add('statusbar'); - window.StatusBar.overlaysWebView(true); - window.StatusBar.backgroundColorByName('black'); - window.StatusBar.show(); - } - if (_status.auto) { - ui.shortcut.autobutton.classList.add('active'); - } - else { - ui.shortcut.autobutton.classList.remove('active'); - } - ui.window.classList.add('shortcutpaused'); - } - } - static favouriteCharacter(e) { - if (typeof this.link == 'string') { - if (this.innerHTML == '添加收藏') { - this.innerHTML = '移除收藏'; - lib.config.favouriteCharacter.add(this.link); - } - else { - this.innerHTML = '添加收藏'; - lib.config.favouriteCharacter.remove(this.link); - } - if (ui.favouriteCharacter) { - if (lib.config.favouriteCharacter.includes(this.link)) { - for (var i = 0; i < ui.favouriteCharacter.childElementCount; i++) { - if (ui.favouriteCharacter.childNodes[i].link == this.link) { - break; - } - } - if (i == ui.favouriteCharacter.childElementCount) { - ui.create.button(this.link, 'character', ui.favouriteCharacter).listen(function (e) { - this._banning = 'offline'; - ui.click.touchpop(); - ui.click.intro.call(this, e); - _status.clicked = false; - delete this._banning; - }).classList.add('noclick'); - } - } - else { - for (var i = 0; i < ui.favouriteCharacter.childElementCount; i++) { - if (ui.favouriteCharacter.childNodes[i].link == this.link) { - ui.favouriteCharacter.childNodes[i].remove(); - break; - } - } - } - var shownode = false; - for (var i = 0; i < lib.config.favouriteCharacter.length; i++) { - var favname = lib.config.favouriteCharacter[i]; - if (lib.character[favname]) { - shownode = true; break; - } - } - if (shownode) { - ui.favouriteCharacter.node.style.display = ''; - } - else { - ui.favouriteCharacter.node.style.display = 'none'; - } - } - game.saveConfig('favouriteCharacter', lib.config.favouriteCharacter); - } - e.stopPropagation(); - } - static buttonnameenter() { - if (this.buttonscrollinterval) { - clearInterval(this.buttonscrollinterval); - } - var node = this.node.name; - if (node.offsetHeight < node.scrollHeight) { - var that = this; - var num = 40; - that.buttonscrollinterval = setInterval(function () { - if (node.scrollTop + node.offsetHeight >= node.scrollHeight) { - clearInterval(that.buttonscrollinterval); - delete that.buttonscrollinterval; - } - else { - if (num > 0) { - num--; - } - else { - node.scrollTop += 2; - } - } - }, 16); - } - } - static buttonnameleave() { - if (this.buttonscrollinterval) { - clearInterval(this.buttonscrollinterval); - } - var node = this.node.name; - if (node.offsetHeight < node.scrollHeight) { - var that = this; - that.buttonscrollinterval = setInterval(function () { - if (node.scrollTop == 0) { - clearInterval(that.buttonscrollinterval); - delete that.buttonscrollinterval; - } - else { - node.scrollTop -= 2; - } - }, 16); - } - } - static dragtouchdialog(e) { - if (e.touches.length > 1 && - !this.classList.contains('popped') && - !this.classList.contains('fixed')) { - _status.draggingtouchdialog = this; - this._dragorigin = { - clientX: e.touches[0].clientX, - clientY: e.touches[0].clientY, - }; - if (!this._dragtransform) { - this._dragtransform = [0, 0]; - } - this._dragorigintransform = this._dragtransform.slice(0); - e.preventDefault(); - e.stopPropagation(); - } - } - static identity(e) { - if (_status.dragged) return; - _status.clicked = true; - if (!game.getIdentityList) return; - if (_status.video) return; - if (this.parentNode.forceShown) return; - if (!_status.connectMode && this.parentNode.ai.stratagem_camouflage && get.config('nei_auto_mark_camouflage') && game.me.identity == 'nei') return; - if (_status.clickingidentity) { - for (var i = 0; i < _status.clickingidentity[1].length; i++) { - _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform = ''; - } - if (_status.clickingidentity[0] == this.parentNode) { - delete _status.clickingidentity; - return; - } - } - var list = game.getIdentityList(this.parentNode); - if (!list) return; - if (lib.config.mark_identity_style == 'click') { - var list2 = []; - for (var i in list) { - list2.push(i); - } - list2.push(list2[0]); - for (var i = 0; i < list2.length; i++) { - if (this.firstChild.innerHTML == list[list2[i]]) { - this.firstChild.innerHTML = list[list2[i + 1]]; - this.dataset.color = list2[i + 1]; - break; - } - } - } - else { - if (get.mode() == 'guozhan') { - list = { wei: '魏', shu: '蜀', wu: '吴', qun: '群', jin: '晋' }; - if (_status.forceKey) list.key = '键'; - } - var list2 = get.copy(list); - if (game.getIdentityList2) { - game.getIdentityList2(list2); - } - var rect = this.parentNode.getBoundingClientRect(); - this._customintro = function (uiintro) { - if (get.mode() == 'guozhan') { - uiintro.clickintro = true; - } - else { - uiintro.touchclose = true; - } - // if(lib.config.theme!='woodden'){ - uiintro.classList.add('woodbg'); - // } - if (get.is.phoneLayout()) { - uiintro.style.width = '100px'; - } - else { - uiintro.style.width = '85px'; - } - var source = this.parentNode; - for (var i in list) { - var node = ui.create.div(); - node.classList.add('guessidentity'); - node.classList.add('pointerdiv'); - ui.create.div('.menubutton.large', list2[i], node); - if (!get.is.phoneLayout()) { - node.firstChild.style.fontSize = '24px'; - node.firstChild.style.lineHeight = '24px'; - } - if (get.mode() == 'guozhan') { - if (source._guozhanguess) { - if (!source._guozhanguess.includes(i)) { - node.classList.add('transparent'); - } - } - node._source = source; - node.listen(ui.click.identitycircle); - } - else { - node.listen(function () { - var info = this.link; - info[0].firstChild.innerHTML = info[1]; - info[0].dataset.color = info[2]; - _status.clicked = false; - }); - } - - node.link = [this, list[i], i]; - uiintro.add(node); - } - }; - ui.click.touchpop(); - ui.click.intro.call(this, { - clientX: (rect.left + rect.width), - clientY: (rect.top) - }); - // var nodes=[]; - // _status.clickingidentity=[this.parentNode,nodes]; - // var num=1; - // var dy=30; - // if(get.is.phoneLayout()){ - // dy=45; - // } - // for(var i in list){ - // if(this.firstChild.innerHTML!=list[i]){ - // var node=ui.create.div('.identity.hidden.pointerdiv',this.parentNode,ui.click.identity2); - // ui.create.div(node).innerHTML=list[i]; - // node.dataset.color=i; - // ui.refresh(node); - // node.show(); - // var transstr='translateY('+((num++)*dy)+'px)'; - // if(get.is.phoneLayout()){ - // transstr+=' scale(1.3)'; - // } - // if(get.is.newLayout()&&this.parentNode.classList.contains('linked')){ - // transstr+=' rotate(90deg)'; - // } - // node.style.transform=transstr; - // nodes.push(node); - // } - // } - } - } - static identity2() { - if (_status.clickingidentity) { - _status.clicked = true; - var player = _status.clickingidentity[0]; - var nodes = _status.clickingidentity[1]; - player.node.identity.dataset.color = this.dataset.color; - player.node.identity.firstChild.innerHTML = this.firstChild.innerHTML; - for (var i = 0; i < nodes.length; i++) { - nodes[i].delete(); - nodes[i].style.transform = ''; - } - delete _status.clickingidentity; - } - } - static roundmenu() { - game.closeConnectMenu(); - switch (lib.config.round_menu_func) { - case 'system': - game.closePopped(); - ui.system1.classList.add('shown'); - ui.system2.classList.add('shown'); - game.closeMenu(); - ui.click.shortcut(); - break; - case 'menu': - if (ui.click.configMenu) { - game.closePopped(); - game.pause2(); - ui.click.configMenu(); - ui.system1.classList.remove('shown'); - ui.system2.classList.remove('shown'); - } - break; - case 'pause': - ui.click.pause(); - break; - case 'auto': - ui.click.auto(); - break; - } - _status.clicked = true; - } - static pausehistory() { - if (!lib.config.auto_popped_history) return; - if (!ui.sidebar.childNodes.length) return; - var uiintro = ui.create.dialog('hidden'); - uiintro.style.maxHeight = '400px'; - uiintro.add(ui.sidebar); - return uiintro; - } - static pauseconfig() { - if (!lib.config.auto_popped_config) return; - if (get.is.phoneLayout()) return; - var uiintro = ui.create.dialog('hidden'); - uiintro.listen(function (e) { - e.stopPropagation(); - }); - - var rows = Math.floor(lib.config.all.mode.length / 3); - uiintro.type = 'config'; - var modes = lib.config.modeorder || lib.config.all.mode.slice(0); - for (var i = 0; i < modes.length; i++) { - if (!lib.config.all.mode.includes(modes[i])) { - modes.splice(i--, 1); - } - } - for (var k = 0; k < rows; k++) { - var node = ui.create.div('.newgame.pointernode'); - for (var i = 0; i < 3 && i + k * 3 < modes.length; i++) { - var thismode = modes[i + k * 3]; - var div = ui.create.div(thismode == (_status.sourcemode || lib.config.mode) ? '.underlinenode.on' : '.underlinenode', node); - div.innerHTML = lib.translate[thismode]; - div.link = thismode; - div.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function () { - game.saveConfig('mode', this.link); - localStorage.setItem(lib.configprefix + 'directstart', true); - game.reload(); - }); - } - uiintro.add(node); - } - - return uiintro; - } - static cardPileButton() { - var uiintro = ui.create.dialog('hidden'); - uiintro.listen(function (e) { - e.stopPropagation(); - }); - var num; - if (game.online) { - num = _status.cardPileNum || 0; - } - else { - num = ui.cardPile.childNodes.length; - } - uiintro.add('剩余 ' + num); - - if (_status.connectMode) return uiintro; - uiintro.add('
      轮数 ' + game.roundNumber + '    洗牌 ' + game.shuffleNumber + '
      '); - uiintro.add('
      弃牌堆
      '); - if (ui.discardPile.childNodes.length) { - var list = []; - for (var i = 0; i < ui.discardPile.childNodes.length; i++) { - list.unshift(ui.discardPile.childNodes[i]); - } - uiintro.addSmall([list, 'card']); - } - else { - uiintro.add('
      '); - } - return uiintro; - } - static chat() { - ui.system1.classList.add('shown'); - ui.system2.classList.add('shown'); - - var uiintro = ui.create.dialog('hidden'); - uiintro.listen(function (e) { - e.stopPropagation(); - }); - - var list = ui.create.div('.caption'); - if (get.is.phoneLayout()) { - list.style.maxHeight = '110px'; - } - else { - list.style.maxHeight = '220px'; - } - list.style.overflow = 'scroll'; - lib.setScroll(list); - uiintro.contentContainer.style.overflow = 'hidden'; - - var input; - var addEntry = function (info, clear) { - if (list._chatempty) { - list.innerHTML = ''; - delete list._chatempty; - } - var node = ui.create.div('.text.chat'); - node.innerHTML = info[0] + ': ' + info[1]; - list.appendChild(node); - list.scrollTop = list.scrollHeight; - uiintro.style.height = uiintro.content.scrollHeight + 'px'; - } - _status.addChatEntry = addEntry; - _status.addChatEntry._origin = uiintro; - if (lib.chatHistory.length) { - for (var i = 0; i < lib.chatHistory.length; i++) { - addEntry(lib.chatHistory[i]); - } - } - else { - list._chatempty = true; - list.appendChild(ui.create.div('.text.center', '无聊天记录')) - } - uiintro.add(list); - uiintro.style.height = uiintro.content.offsetHeight + 'px'; - list.scrollTop = list.scrollHeight; - - if (!_status.chatValue) _status.chatValue = ''; - var node = uiintro.add(''); - node.style.paddingTop = 0; - node.style.marginBottom = '16px'; - input = node.firstChild; - input.style.width = 'calc(100% - 20px)'; - input.onchange = function () { - _status.chatValue = input.value; - } - input.onkeydown = function (e) { - if (e.keyCode == 13 && input.value) { - var player = game.me; - var str = input.value; - if (!player) { - if (game.connectPlayers) { - if (game.online) { - for (var i = 0; i < game.connectPlayers.length; i++) { - if (game.connectPlayers[i].playerid == game.onlineID) { - player = game.connectPlayers[i]; break; - } - } - } - else { - player = game.connectPlayers[0]; - } - } - } - if (!player) return; - if (get.is.banWords(input.value)) { - player.say(input.value); - input.value = ''; - _status.chatValue = ''; - } - else { - if (game.online) { - game.send('chat', game.onlineID, str); - } - else { - player.chat(str); - } - input.value = ''; - _status.chatValue = ''; - } - } - e.stopPropagation(); - } - uiintro._onopen = function () { - input.focus(); - list.scrollTop = list.scrollHeight; - }; - uiintro._heightfixed = true; - var emotionTitle = ui.create.div('.text.center', '聊天表情', function () { - if (emotionTitle.innerHTML == '快捷语音') { - emotionTitle.innerHTML = '聊天表情'; - list2.remove(); - list3.remove(); - uiintro.add(list1); - while (list2.childNodes.length) { - list2.firstChild.remove(); - } - } - else { - emotionTitle.innerHTML = '快捷语音'; - list1.remove(); - list2.remove(); - uiintro.add(list3); - } - }); - uiintro.add(emotionTitle); - var list1 = ui.create.div(''); - if (get.is.phoneLayout()) { - list1.style.height = '110px'; - } - else { - list1.style.height = '150px'; - } - list1.style.overflow = 'scroll'; - lib.setScroll(list1); - uiintro.add(list1); - uiintro.style.height = uiintro.content.scrollHeight + 'px'; - var list2 = ui.create.div(''); - if (get.is.phoneLayout()) { - list2.style.height = '110px'; - } - else { - list2.style.height = '150px'; - } - list2.style.overflow = 'scroll'; - lib.setScroll(list2); - //uiintro.add(list2); - for (var i in lib.emotionList) { - var emotionPack = ui.create.div('.card.fullskin', '', function () { - emotionTitle.innerHTML = get.translation(this.pack); - for (var j = 1; j <= lib.emotionList[this.pack]; j++) { - var emotionButton = ui.create.div('.card.fullskin', '', function () { - var player = game.me; - if (!player) { - if (game.connectPlayers) { - if (game.online) { - for (var i = 0; i < game.connectPlayers.length; i++) { - if (game.connectPlayers[i].playerid == game.onlineID) { - player = game.connectPlayers[i]; break; - } - } - } - else { - player = game.connectPlayers[0]; - } - } - } - if (!player) return; - if (game.online) { - game.send('emotion', game.onlineID, this.pack, this.emotionID); - } - else { - player.emotion(this.pack, this.emotionID); - } - }); - emotionButton.emotionID = j; - emotionButton.pack = this.pack; - emotionButton.style.height = '50px'; - emotionButton.style.width = '50px'; - list2.appendChild(emotionButton); - } - list1.remove(); - uiintro.add(list2); - }); - emotionPack.pack = i; - emotionPack.style.height = '50px'; - emotionPack.style.width = '50px'; - list1.appendChild(emotionPack); - } - list1.scrollTop = list1.scrollHeight; - uiintro.style.height = uiintro.content.scrollHeight + 'px'; - var list3 = ui.create.div('.caption'); - if (get.is.phoneLayout()) { - list3.style.height = '110px'; - } - else { - list3.style.height = '150px'; - } - list3.style.overflow = 'scroll'; - lib.setScroll(list3); - for (var i = 0; i < lib.quickVoice.length; i++) { - var node = ui.create.div('.text.chat', function () { - var player = game.me; - var str = this.innerHTML; - if (!player) { - if (game.connectPlayers) { - if (game.online) { - for (var i = 0; i < game.connectPlayers.length; i++) { - if (game.connectPlayers[i].playerid == game.onlineID) { - player = game.connectPlayers[i]; break; - } - } - } - else { - player = game.connectPlayers[0]; - } - } - } - if (!player) return; - if (game.online) { - game.send('chat', game.onlineID, str); - } - else { - player.chat(str); - } - }); - node.innerHTML = lib.quickVoice[i]; - list3.appendChild(node); - } - list3.scrollTop = list1.scrollHeight; - return uiintro; - } - static volumn() { - var uiintro = ui.create.dialog('hidden'); - uiintro.listen(function (e) { - e.stopPropagation(); - }); - uiintro.add('背景音乐'); - var vol1 = ui.create.div('.volumn'); - uiintro.add(vol1); - for (var i = 0; i < 8; i++) { - var span = document.createElement('span'); - span.link = i + 1; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.volumn_background); - if (i < lib.config.volumn_background) { - span.innerHTML = '●'; - } - else { - span.innerHTML = '○'; - } - vol1.appendChild(span); - } - uiintro.add('游戏音效'); - - var vol2 = ui.create.div('.volumn'); - uiintro.add(vol2); - for (var i = 0; i < 8; i++) { - var span = document.createElement('span'); - span.link = i + 1; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.volumn_audio); - if (i < lib.config.volumn_audio) { - span.innerHTML = '●'; - } - else { - span.innerHTML = '○'; - } - vol2.appendChild(span); - } - uiintro.add(ui.create.div('.placeholder')); - return uiintro; - } - static volumn_background(e) { - if (_status.dragged) return; - var volume = this.link; - if (volume === 1 && lib.config.volumn_background === 1) { - volume = 0; - } - game.saveConfig('volumn_background', volume); - ui.backgroundMusic.volume = volume / 8; - for (var i = 0; i < 8; i++) { - if (i < lib.config.volumn_background) { - this.parentNode.childNodes[i].innerHTML = '●'; - } - else { - this.parentNode.childNodes[i].innerHTML = '○'; - } - } - e.stopPropagation(); - } - static volumn_audio(e) { - if (_status.dragged) return; - var volume = this.link; - if (volume === 1 && lib.config.volumn_audio === 1) { - volume = 0; - } - game.saveConfig('volumn_audio', volume); - for (var i = 0; i < 8; i++) { - if (i < lib.config.volumn_audio) { - this.parentNode.childNodes[i].innerHTML = '●'; - } - else { - this.parentNode.childNodes[i].innerHTML = '○'; - } - } - e.stopPropagation(); - } - static hoverpopped() { - if (this._uiintro) { - return; - } - if (!this._poppedfunc) { - return; - } - ui.click.touchpop(this.forceclick); - var uiintro = this._poppedfunc(); - if (!uiintro) return; - if (ui.currentpopped && ui.currentpopped._uiintro) { - ui.currentpopped._uiintro.delete(); - delete ui.currentpopped._uiintro; - } - ui.currentpopped = this; - uiintro.classList.add('popped'); - uiintro.classList.add('hoverdialog'); - uiintro.classList.add('static'); - this._uiintro = uiintro; - - ui.window.appendChild(uiintro); - var width = this._poppedwidth || 330; - uiintro.style.width = width + 'px'; - if (get.is.phoneLayout()) { - width *= 1.3; - } - - if (uiintro._heightfixed) { - uiintro.style.height = uiintro.content.scrollHeight + 'px'; - } - else { - var height = this._poppedheight || uiintro.content.scrollHeight; - var height2 = ui.window.offsetHeight - 260; - if (get.is.phoneLayout()) { - height2 = (ui.window.offsetHeight - 80) / 1.3; - } - uiintro.style.height = Math.min(height2, height) + 'px'; - } - if (get.is.phoneLayout()) { - uiintro.style.top = '70px'; - } - else { - uiintro.style.top = '50px'; - } - var left = this.parentNode.offsetLeft + this.offsetLeft + this.offsetWidth / 2 - width / 2; - if (left < 10) { - left = 10; - } - else if (left + width > ui.window.offsetWidth - 10) { - left = ui.window.offsetWidth - width - 10; - } - uiintro.style.left = left + 'px'; - uiintro._poppedorigin = this; - if (!lib.config.touchscreen) { - uiintro.addEventListener('mouseleave', ui.click.leavehoverpopped); - } - ui.click.shortcut(false); - if (uiintro._onopen) { - uiintro._onopen(); - } - if (this._paused2 && !lib.config.touchscreen) { - game.pause2(); - uiintro.classList.add('static'); - var layer = ui.create.div('.poplayer', ui.window); - var clicklayer = function (e) { - uiintro.delete(); - layer.remove(); - game.resume2(); - e.stopPropagation(); - return false; - } - uiintro.style.zIndex = 21; - layer.onclick = clicklayer; - layer.oncontextmenu = clicklayer; - uiintro.addEventListener('mouseleave', clicklayer); - uiintro.addEventListener('click', clicklayer); - } - } - static hoverpopped_leave() { - this._poppedalready = false; - } - static leavehoverpopped() { - if (_status.dragged) return; - if (this.classList.contains('noleave')) return; - this.delete(); - var button = this._poppedorigin; - - var uiintro = this; - setTimeout(function () { - if (button._uiintro == uiintro) { - delete button._uiintro; - } - }, 500); - - } - static dierevive() { - if (game.me.isDead()) { - game.me.revive(Math.max(1, game.me.maxHp)); - game.me.draw(2); - } - else { - if (ui.revive) { - ui.revive.close(); - delete ui.revive; - } - } - } - static dieswap() { - if (game.me.isDead()) { - _status.clicked = true; - var i, translation, intro, str; - if (ui.intro) { - ui.intro.close(); - if (ui.intro.source == 'dieswap') { - delete ui.intro; - ui.control.show(); - game.resume2(); - return; - } - } - game.pause2(); - ui.control.hide(); - ui.intro = ui.create.dialog(); - ui.intro.source = 'dieswap'; - - var players = []; - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isAlive()) { - players.push(game.players[i]); - } - } - ui.intro.add(players, true); - var buttons = ui.intro.querySelectorAll('.button'); - for (var i = 0; i < buttons.length; i++) { - buttons[i].addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.dieswap2); - } - } - else { - if (ui.swap) { - ui.swap.close(); - delete ui.swap; - } - } - } - static dieswap2() { - if (_status.dragged) return; - game.swapPlayer(this.link); - } - static touchconfirm() { - _status.touchconfirmed = true; - document.removeEventListener('touchstart', ui.click.touchconfirm); - } - static windowtouchstart(e) { - if (window.inSplash) return; - if (e.touches[0] && lib.config.swipe && e.touches.length < 2) { - _status._swipeorigin = { - clientX: e.touches[0].clientX, - clientY: e.touches[0].clientY, - time: get.utc() - } - } - // if(window.ForceTouch&&!_status.paused2&&!_status.forcetouchinterval&&lib.config.enable_pressure){ - // _status.forcetouchinterval=setInterval(ui.click.forcetouch,30); - // } - } - static windowtouchmove(e) { - e.preventDefault(); - if (window.inSplash) return; - if (_status.draggingroundmenu) { - delete _status._swipeorigin; - if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform && e.touches.length) { - var translate = ui.roundmenu._dragtransform.slice(0); - var dx = e.touches[0].clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; - var dy = e.touches[0].clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; - translate[0] += dx; - translate[1] += dy; - if (dx * dx + dy * dy > 100) { - if (ui.roundmenu._resetTimeout) { - clearTimeout(ui.roundmenu._resetTimeout); - delete ui.roundmenu._resetTimeout; - } - } - ui.roundmenu._dragtouches = e.touches[0]; - ui.click.checkroundtranslate(translate); - } - _status.clicked = true; - } - else if (_status.draggingtouchdialog) { - delete _status._swipeorigin; - if (_status.draggingtouchdialog._dragorigin && _status.draggingtouchdialog._dragtransform && e.touches.length) { - var translate = _status.draggingtouchdialog._dragtransform.slice(0); - var dx = e.touches[0].clientX / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientX / game.documentZoom; - var dy = e.touches[0].clientY / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientY / game.documentZoom; - translate[0] += dx; - translate[1] += dy; - _status.draggingtouchdialog._dragtouches = e.touches[0]; - ui.click.checkdialogtranslate(translate, _status.draggingtouchdialog); - } - _status.clicked = true; - } - else if (_status._swipeorigin && e.touches[0]) { - _status._swipeorigin.touches = e.touches[0]; - } - - if (_status.mousedragging && e.touches.length) { - e.preventDefault(); - var item = document.elementFromPoint(e.touches[0].clientX, e.touches[0].clientY); - if (game.chess && ui.selected.cards.length) { - var itemtype = get.itemtype(item); - if (itemtype != 'card' && itemtype != 'button') { - var ex = e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft; - var ey = e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop; - for (var i = 0; i < game.players.length; i++) { - var left = -ui.chessContainer.chessLeft + ui.chess.offsetLeft + game.players[i].getLeft(); - var top = -ui.chessContainer.chessTop + ui.chess.offsetTop + game.players[i].getTop(); - var width = game.players[i].offsetWidth; - var height = game.players[i].offsetHeight; - if (ex > left && ex < left + width && ey > top && ey < top + height) { - item = game.players[i]; - break; - } - } - } - } - while (item) { - if (lib.config.enable_touchdragline && _status.mouseleft && !game.chess) { - ui.canvas.width = ui.arena.offsetWidth; - ui.canvas.height = ui.arena.offsetHeight; - var ctx = ui.ctx; - ctx.shadowBlur = 5; - ctx.shadowColor = 'rgba(0,0,0,0.3)'; - ctx.strokeStyle = 'white'; - ctx.lineWidth = 3; - ctx.setLineDash([8, 2]); - - ctx.beginPath(); - - ctx.moveTo(_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop); - - if (_status.multitarget) { - for (var i = 0; i < _status.lastdragchange.length; i++) { - var exy = _status.lastdragchange[i]._lastdragchange; - ctx.lineTo(exy[0], exy[1]); - } - } - if (!_status.selectionfull) { - ctx.lineTo(e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft, e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop); - } - ctx.stroke(); - if (!_status.multitarget) { - for (var i = 0; i < _status.lastdragchange.length; i++) { - ctx.moveTo(_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop); - var exy = _status.lastdragchange[i]._lastdragchange; - ctx.lineTo(exy[0], exy[1]); - ctx.stroke(); - } - } - } - - if (item == _status.mousedragorigin) { - if (_status.mouseleft) { - _status.mousedragging = null; - _status.mousedragorigin = null; - _status.clicked = false; - game.uncheck(); - game.check(); - _status.clicked = true; - } - return; - } - var itemtype = get.itemtype(item); - if (itemtype == 'card' || itemtype == 'button' || itemtype == 'player') { - _status.mouseleft = true; - if (ui.selected.cards.length) { - ui.selected.cards[0].updateTransform(true, 100); - } - var ex = e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft; - var ey = e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop; - var exx = ex, eyy = ey; - if (game.chess) { - ex -= -ui.chessContainer.chessLeft + ui.chess.offsetLeft; - ey -= -ui.chessContainer.chessTop + ui.chess.offsetTop; - } - if (itemtype != 'player' || game.chess || (ex > item.offsetLeft && ex < item.offsetLeft + item.offsetWidth && - ey > item.offsetTop && ey < item.offsetTop + item.offsetHeight)) { - var targetfixed = false; - if (itemtype == 'player') { - if (get.select(_status.event.selectTarget)[1] <= -1) { - targetfixed = true; - } - } - if (!targetfixed && item.classList.contains('selectable') && _status.dragstatuschanged != item) { - _status.mouseleft = true; - _status.dragstatuschanged = item; - _status.clicked = false; - _status.dragged = false; - var notbefore = itemtype == 'player' && !item.classList.contains('selected'); - ui.click[itemtype].call(item); - if (item.classList.contains('selected')) { - if (notbefore) { - _status.lastdragchange.push(item); - item._lastdragchange = [exx, eyy]; - if (lib.falseitem) { - var from = [_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop]; - var to = [exx, eyy]; - var node = ui.create.div('.linexy.hidden'); - node.style.left = from[0] + 'px'; - node.style.top = from[1] + 'px'; - node.style.transitionDuration = '0.3s'; - node.style.backgroundColor = 'white'; - var dy = to[1] - from[1]; - var dx = to[0] - from[0]; - var deg = Math.atan(Math.abs(dy) / Math.abs(dx)) / Math.PI * 180; - if (dx >= 0) { - if (dy <= 0) { - deg += 90; - } - else { - deg = 90 - deg; - } - } - else { - if (dy <= 0) { - deg = 270 - deg; - } - else { - deg += 270; - } - } - node.style.transform = 'rotate(' + (-deg) + 'deg) scaleY(0)'; - node.style.height = get.xyDistance(from, to) + 'px'; - if (game.chess) { - ui.chess.appendChild(node); - } - else { - ui.arena.appendChild(node); - } - ui.refresh(node); - node.show(); - node.style.transform = 'rotate(' + (-deg) + 'deg) scaleY(1)'; - ui.touchlines.push(node); - node._origin = item; - } - } - } - else { - _status.lastdragchange.remove(item); - for (var i = 0; i < ui.touchlines.length; i++) { - if (ui.touchlines[i]._origin == item) { - ui.touchlines[i].delete(); - ui.touchlines.splice(i--, 1); - } - } - } - _status.selectionfull = true; - if (_status.event.filterButton && ui.selected.buttons.length < get.select(_status.event.selectButton)[1]) { - _status.selectionfull = false; - } - else if (_status.event.filterCard && ui.selected.cards.length < get.select(_status.event.selectCard)[1]) { - _status.selectionfull = false; - } - else if (_status.event.filterTarget && ui.selected.targets.length < get.select(_status.event.selectTarget)[1]) { - _status.selectionfull = false; - } - } - } - return; - } - item = item.parentNode; - } - _status.mouseleft = true; - _status.dragstatuschanged = null; - } - } - static windowtouchend(e) { - delete _status.force; - // if(_status.forcetouchinterval){ - // clearInterval(_status.forcetouchinterval); - // delete _status.forcetouchinterval; - // } - if (window.inSplash) return; - if (e.touches.length == 1 && !_status.dragged && !_status.draggingtouchdialog) { - ui.click.pause(); - } - if (_status.draggingroundmenu) { - delete _status._swipeorigin; - if (ui.roundmenu._resetTimeout) { - clearTimeout(ui.roundmenu._resetTimeout); - delete ui.roundmenu._resetTimeout; - } - var translate; - if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform && ui.roundmenu._dragtouches) { - var dx = ui.roundmenu._dragtouches.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; - var dy = ui.roundmenu._dragtouches.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; - if (dx * dx + dy * dy < 1000) { - ui.click.roundmenu(); - ui.roundmenu._dragtransform = ui.roundmenu._dragorigintransform; - translate = ui.roundmenu._dragtransform; - ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; - } - else { - translate = ui.roundmenu._dragtransform; - translate[0] += dx; - translate[1] += dy; - ui.click.checkroundtranslate(); - } - delete ui.roundmenu._dragorigin; - } - else { - ui.click.roundmenu(); - } - _status.clicked = false; - game.saveConfig('roundmenu_transform', translate); - delete _status.draggingroundmenu; - } - else if (_status.draggingtouchdialog) { - delete _status._swipeorigin; - var translate; - if (_status.draggingtouchdialog._dragorigin && _status.draggingtouchdialog._dragtransform && _status.draggingtouchdialog._dragtouches) { - var dx = _status.draggingtouchdialog._dragtouches.clientX / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientX / game.documentZoom; - var dy = _status.draggingtouchdialog._dragtouches.clientY / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientY / game.documentZoom; - translate = _status.draggingtouchdialog._dragtransform; - translate[0] += dx; - translate[1] += dy; - ui.click.checkdialogtranslate(null, _status.draggingtouchdialog); - - delete _status.draggingtouchdialog._dragorigin; - } - _status.clicked = false; - game.saveConfig('dialog_transform', translate); - delete _status.draggingtouchdialog; - _status.justdragged = true; - setTimeout(function () { - _status.justdragged = false; - }, 500); - } - else if (_status._swipeorigin && !_status.paused2 && !_status.mousedragging && _status._swipeorigin.touches && !_status.filterCharacter) { - if (get.utc() - _status._swipeorigin.time < 500) { - var dx = _status._swipeorigin.touches.clientX / game.documentZoom - _status._swipeorigin.clientX / game.documentZoom; - var dy = _status._swipeorigin.touches.clientY / game.documentZoom - _status._swipeorigin.clientY / game.documentZoom; - var goswipe = function (action) { - game.closeConnectMenu(); - switch (action) { - case 'system': - game.closePopped(); - ui.system1.classList.add('shown'); - ui.system2.classList.add('shown'); - game.closeMenu(); - ui.click.shortcut(); - break; - case 'menu': - if (ui.click.configMenu) { - game.closePopped(); - game.pause2(); - ui.click.configMenu(); - ui.system1.classList.remove('shown'); - ui.system2.classList.remove('shown'); - } - break; - case 'pause': - ui.click.pause(); - break; - case 'auto': - ui.click.auto(); - break; - case 'chat': - game.closeMenu(); - if (ui.chatButton) { - ui.click.hoverpopped.call(ui.chatButton); - } - break; - } - } - if (Math.abs(dx) < 100) { - if (dy < -200) { - goswipe(lib.config.swipe_up); - } - else if (dy > 200) { - goswipe(lib.config.swipe_down); - } - } - else if (Math.abs(dy) < 100) { - if (dx < -200) { - goswipe(lib.config.swipe_left); - } - else if (dx > 200) { - goswipe(lib.config.swipe_right); - } - } - } - } - var tmpflag = false; - _status.mousedown = false; - _status.clicked = false; - if (_status.mousedragging && _status.mouseleft) { - if (game.check()) { - if (ui.confirm) { - ui.confirm.close(); - } - var event = _status.event; - if (!event.filterOk || event.filterOk()) ui.click.ok(); - ui.canvas.width = ui.arena.offsetWidth; - ui.canvas.height = ui.arena.offsetHeight; - } - else { - game.uncheck(); - game.check(); - } - } - else if (_status.mousedragging && _status.mousedragorigin) { - tmpflag = _status.mousedragorigin; - } - _status.lastdragchange.length = 0; - _status.mousedragging = null; - _status.mouseleft = false; - _status.mousedragorigin = null; - _status.dragstatuschanged = false; - while (ui.touchlines.length) { - ui.touchlines.shift().delete(); - } - if (tmpflag) { - game.check(); - } - _status.dragged = false; - _status.clicked = false; - } - static checkroundtranslate(translate) { - var translate = translate || ui.roundmenu._dragtransform; - if (translate[1] + ui.roundmenu._position[1] + 50 + ui.arena.offsetTop > ui.window.offsetHeight) { - translate[1] = ui.window.offsetHeight - (ui.roundmenu._position[1] + 50) - ui.arena.offsetTop; - } - else if (translate[1] + ui.roundmenu._position[1] + ui.arena.offsetTop < 0) { - translate[1] = -ui.roundmenu._position[1] - ui.arena.offsetTop; - } - if (translate[0] + ui.roundmenu._position[0] + 50 + ui.arena.offsetLeft > ui.window.offsetWidth) { - translate[0] = ui.window.offsetWidth - (ui.roundmenu._position[0] + 50) - ui.arena.offsetLeft; - } - else if (translate[0] + ui.roundmenu._position[0] + ui.arena.offsetLeft < 0) { - translate[0] = -ui.roundmenu._position[0] - ui.arena.offsetLeft; - } - ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; - } - static checkdialogtranslate(translate, dialog) { - var translate = translate || dialog._dragtransform; - if (Math.sqrt(translate[0] * translate[0] + translate[1] * translate[1]) < 10) { - translate[0] = 0; - translate[1] = 0; - } - dialog.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; - } - static windowmousewheel(e) { - _status.tempunpopup = e; - } - static windowmousemove(e) { - if (window.inSplash) return; - if (_status.tempunpopup) { - if (get.evtDistance(_status.tempunpopup, e) > 5) { - delete _status.tempunpopup; - } - } - if (e.button == 2) return; - var dialogs = document.querySelectorAll('#window>.dialog.popped:not(.static)'); - for (var i = 0; i < dialogs.length; i++) { - dialogs[i].delete(); - } - var node = _status.currentmouseenter; - var sourceitem = document.elementFromPoint(e.clientX, e.clientY); - if (game.chess && ui.selected.cards.length) { - var itemtype = get.itemtype(sourceitem); - if (itemtype != 'card' && itemtype != 'button') { - for (var i = 0; i < game.players.length; i++) { - var ex = e.clientX / game.documentZoom - ui.arena.offsetLeft; - var ey = e.clientY / game.documentZoom - ui.arena.offsetTop; - var left = -ui.chessContainer.chessLeft + ui.chess.offsetLeft + game.players[i].getLeft(); - var top = -ui.chessContainer.chessTop + ui.chess.offsetTop + game.players[i].getTop(); - var width = game.players[i].offsetWidth; - var height = game.players[i].offsetHeight; - if (ex > left && ex < left + width && ey > top && ey < top + height) { - sourceitem = game.players[i]; - break; - } - } - } - } - var item = sourceitem; - if (_status.mousedragging) { - e.preventDefault(); - if (lib.config.enable_dragline) { - // var i=0; - // var startPoint0=[_status.mousedragging.clientX/game.documentZoom-ui.arena.offsetLeft,_status.mousedragging.clientY/game.documentZoom-ui.arena.offsetTop]; - // var startPoint=startPoint0; - // var endPoint; - // if(_status.multitarget){ - // for(;i<_status.lastdragchange.length;i++){ - // var exy=_status.lastdragchange[i]._lastdragchange; - // endPoint=[exy[0],exy[1]]; - // _status.dragline[i]=game.linexy(startPoint.concat(endPoint),'drag',_status.dragline[i]); - // startPoint=endPoint; - // } - // } - // if(!_status.selectionfull){ - // endPoint=[e.clientX/game.documentZoom-ui.arena.offsetLeft,e.clientY/game.documentZoom-ui.arena.offsetTop]; - // _status.dragline[i]=game.linexy(startPoint.concat(endPoint),'drag',_status.dragline[i]); - // startPoint=endPoint; - // i++; - // } - // if(!_status.multitarget){ - // for(var j=0;j<_status.lastdragchange.length;j++){ - // i+=j; - // var exy=_status.lastdragchange[j]._lastdragchange; - // _status.dragline[i]=game.linexy(startPoint0.concat([exy[0],exy[1]]),'drag',_status.dragline[i]); - // } - // } - // var remained=_status.dragline.splice(i+1); - // for(var j=0;j item.offsetLeft && ex < item.offsetLeft + item.offsetWidth && - ey > item.offsetTop && ey < item.offsetTop + item.offsetHeight)) { - var targetfixed = false; - if (itemtype == 'player') { - if (get.select(_status.event.selectTarget)[1] <= -1) { - targetfixed = true; - } - } - if (!targetfixed && item.classList.contains('selectable') && _status.dragstatuschanged != item) { - _status.mouseleft = true; - _status.dragstatuschanged = item; - _status.clicked = false; - var notbefore = itemtype == 'player' && !item.classList.contains('selected'); - ui.click[itemtype].call(item); - if (item.classList.contains('selected')) { - if (notbefore) { - _status.lastdragchange.push(item); - item._lastdragchange = [exx, eyy]; - } - } - else { - _status.lastdragchange.remove(item); - } - _status.selectionfull = true; - if (_status.event.filterButton && ui.selected.buttons.length < get.select(_status.event.selectButton)[1]) { - _status.selectionfull = false; - } - else if (_status.event.filterCard && ui.selected.cards.length < get.select(_status.event.selectCard)[1]) { - _status.selectionfull = false; - } - else if (_status.event.filterTarget && ui.selected.targets.length < get.select(_status.event.selectTarget)[1]) { - _status.selectionfull = false; - } - } - } - return; - } - item = item.parentNode; - } - if (!_status.mouseleft) { - _status.mouseleft = true; - game.check(); - for (var i = 0; i < ui.selected.cards.length; i++) { - ui.selected.cards[i].updateTransform(true); - } - } - _status.dragstatuschanged = null; - } - else { - while (item) { - if (item == node && !node._mouseentercreated) { - ui.click.mouseentercancel(); - var hoveration; - if (typeof node._hoveration == 'number') { - hoveration = node._hoveration; - } - else { - hoveration = parseInt(lib.config.hoveration); - if (node.classList.contains('button') || - (node.parentNode && node.parentNode.parentNode) == ui.me) { - hoveration += 500; - } - } - _status._mouseentertimeout = setTimeout(function () { - if (_status.currentmouseenter != node || node._mouseentercreated || _status.tempunpopup || - _status.mousedragging || _status.mousedown || !node.offsetWidth || !node.offsetHeight) { - return; - } - if (node._hoverfunc && !node._nopup) { - var dialog = node._hoverfunc.call(node, e); - if (dialog) { - dialog.classList.add('popped'); - ui.window.appendChild(dialog); - lib.placePoppedDialog(dialog, e); - if (node._hoverwidth) { - dialog.style.width = node._hoverwidth + 'px'; - dialog._hovercustomed = true; - } - node._mouseenterdialog = dialog; - node._mouseentercreated = true; - } - } - }, hoveration); - break; - } - item = item.parentNode; - } - if (_status.draggingdialog) { - var ddialog = _status.draggingdialog; - if (ddialog._dragorigin && ddialog._dragtransform) { - var translate = ddialog._dragtransform.slice(0); - translate[0] += e.clientX / game.documentZoom - ddialog._dragorigin.clientX / game.documentZoom; - translate[1] += e.clientY / game.documentZoom - ddialog._dragorigin.clientY / game.documentZoom; - ui.click.checkdialogtranslate(translate, ddialog); - } - _status.clicked = true; - } - if (_status.draggingroundmenu) { - if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform) { - var translate = ui.roundmenu._dragtransform.slice(0); - translate[0] += e.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; - translate[1] += e.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; - ui.click.checkroundtranslate(translate); - } - _status.clicked = true; - } - } - } - static windowmousedown(e) { - if (window.inSplash) return; - if (!ui.window) return; - if (e.button == 2) return; - _status.mousedown = true; - var dialogs = ui.window.querySelectorAll('#window>.dialog.popped:not(.static)'); - for (var i = 0; i < dialogs.length; i++) { - dialogs[i].delete(); - } - var sourceitem = document.elementFromPoint(e.clientX, e.clientY); - var item = sourceitem; - while (item) { - var itemtype = get.itemtype(item); - if (itemtype == 'button') break; - if (itemtype == 'dialog' && - !item.classList.contains('popped') && - !item.classList.contains('fixed')) { - var ddialog = item; - _status.draggingdialog = ddialog; - ddialog._dragorigin = e; - if (!ddialog._dragtransform) { - ddialog._dragtransform = [0, 0]; - } - return; - } - if (item == ui.roundmenu) { - _status.draggingroundmenu = true; - ui.roundmenu._dragorigin = e; - if (!ui.roundmenu._dragtransform) { - ui.roundmenu._dragtransform = [0, 0]; - } - return; - } - item = item.parentNode; - } - - var evt = _status.event; - if (!lib.config.enable_drag) return; - if (!ui.arena.classList.contains('selecting')) return; - if (!evt.isMine()) return; - - item = sourceitem; - while (item) { - var itemtype = get.itemtype(item); - if (itemtype == 'card' || itemtype == 'button' || itemtype == 'player') { - if (item.classList.contains('selectable') && - !item.classList.contains('selected') && - !item.classList.contains('noclick')) { - _status.clicked = false; - ui.click[itemtype].call(item); - if (item.classList.contains('selected')) { - _status.mousedragging = e; - _status.mousedragorigin = item; - _status.mouseleft = false; - _status.selectionfull = false; - _status.multitarget = false; - _status.lastmouseutc = get.utc(); - ui.arena.classList.add('dragging'); - } - } - return; - } - item = item.parentNode; - } - } - static cardtouchstart(e) { - if (e.touches.length != 1) return; - if (!lib.config.enable_drag) return; - if (!this.parentNode) return; - if (!this.parentNode.parentNode) return; - if (this.parentNode.parentNode.parentNode != ui.me) return; - if (this.parentNode.parentNode.classList.contains('scrollh')) return; - if (this.classList.contains('selectable') && - !this.classList.contains('selected') && - !this.classList.contains('noclick')) { - this._waitingfordrag = { - clientX: e.touches[0].clientX, - clientY: e.touches[0].clientY - }; - } - } - static cardtouchmove(e) { - ui.click.longpresscancel.call(this); - if (this._waitingfordrag) { - var drag = this._waitingfordrag; - _status.clicked = false; - _status.touchnocheck = true; - ui.click.card.call(this); - _status.touchnocheck = false; - if (this.classList.contains('selected')) { - _status.mousedragging = drag; - _status.mousedragorigin = this; - _status.mouseleft = false; - _status.selectionfull = false; - _status.multitarget = false; - } - delete this._waitingfordrag; - } - } - static windowmouseup(e) { - delete _status.force; - // if(_status.forcetouchinterval){ - // clearInterval(_status.forcetouchinterval); - // delete _status.forcetouchinterval; - // } - if (window.inSplash) return; - if (_status.draggingdialog) { - var ddialog = _status.draggingdialog; - var translate; - if (ddialog._dragorigin && ddialog._dragtransform) { - translate = ddialog._dragtransform; - translate[0] += e.clientX / game.documentZoom - ddialog._dragorigin.clientX / game.documentZoom; - translate[1] += e.clientY / game.documentZoom - ddialog._dragorigin.clientY / game.documentZoom; - ui.click.checkdialogtranslate(null, ddialog); - delete ddialog._dragorigin; - } - game.saveConfig('dialog_transform', translate); - delete _status.draggingdialog; - } - if (_status.draggingroundmenu) { - var translate; - if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform) { - var dx = e.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; - var dy = e.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; - if (dx * dx + dy * dy < 25) { - ui.click.roundmenu(); - } - translate = ui.roundmenu._dragtransform; - translate[0] += dx; - translate[1] += dy; - ui.click.checkroundtranslate(); - delete ui.roundmenu._dragorigin; - } - game.saveConfig('roundmenu_transform', translate); - delete _status.draggingroundmenu; - } - if (e.button == 2) { - if (_status.mousedragging) { - _status.mousedragging = null; - _status.mouseleft = false; - _status.mousedragorigin = null; - _status.dragstatuschanged = false; - game.uncheck(); - game.check(); - _status.noright = true; - } - } - else { - var tmpflag = false; - _status.mousedown = false; - for (var i = 0; i < ui.selected.cards.length; i++) { - ui.selected.cards[i].updateTransform(true); - } - if (_status.mousedragging && _status.mouseleft) { - if (game.check()) { - if (ui.confirm) { - ui.confirm.close(); - } - var event = _status.event; - if (!event.filterOk || event.filterOk()) ui.click.ok(); - } - else { - game.uncheck(); - game.check(); - } - } - else if (_status.mousedragging && _status.mousedragorigin) { - tmpflag = _status.mousedragorigin; - } - _status.lastdragchange.length = 0; - _status.mousedragging = null; - _status.mouseleft = false; - _status.mousedragorigin = null; - _status.dragstatuschanged = false; - if (ui.arena) { - ui.canvas.width = ui.arena.offsetWidth; - ui.canvas.height = ui.arena.offsetHeight; - } - if (tmpflag) { - ui.click[get.itemtype(tmpflag)].call(tmpflag); - game.check(); - } - // ui.updatehl(); - } - if (ui.arena) { - ui.arena.classList.remove('dragging'); - } - } - static mousemove() { - if (!lib.config.hover_handcard && this.parentNode && this.parentNode.parentNode == ui.me) { - return; - } - if (!_status.currentmouseenter) { - _status.currentmouseenter = this; - } - } - static mouseenter() { - if (!lib.config.hover_handcard && this.parentNode && this.parentNode.parentNode == ui.me) { - return; - } - _status.currentmouseenter = this; - } - static mouseleave() { - ui.click.mouseentercancel(); - if (_status.currentmouseenter == this) { - _status.currentmouseenter = null; - } - this._mouseentercreated = false; - } - static mousedown() { - ui.click.mouseentercancel(); - if (_status.currentmouseenter == this) { - _status.currentmouseenter = null; - } - this._mouseentercreated = true; - } - static mouseentercancel() { - if (_status._mouseentertimeout) { - clearTimeout(_status._mouseentertimeout); - delete _status._mouseentertimeout - } - } - static hoverplayer(e) { - var node = get.nodeintro(this, true); - if (node) node.style.zIndex = 21; - return node; - } - static longpressdown(e) { - if (_status.longpressed) return; - if (this._longpresstimeout) { - clearTimeout(this._longpresstimeout); - } - if (lib.config.longpress_info) { - this._longpresstimeout = setTimeout(ui.click.longpresscallback, 500); - } - this._longpressevent = e; - if (_status.longpressing && _status.longpressing != this) { - ui.click.longpresscancel.call(_status.longpressing); - } - // if(window.ForceTouch&&!_status.forcetouchinterval&&lib.config.enable_pressure){ - // _status.forcetouchinterval=setInterval(ui.click.forcetouch,30); - // } - _status.longpressing = this; - } - static longpresscallback() { - if (!_status.longpressing) return; - var node = _status.longpressing; - var func = node._longpresscallback; - var e = node._longpressevent; - if (!func || !e) return; - clearTimeout(node._longpresstimeout); - _status.force = true; - delete _status.longpressing; - delete node._longpresstimeout; - delete node._longpressevent; - if (_status.mousedragging && _status.mouseleft) return; - if (!_status.longpressed) { - _status.longpressed = true; - setTimeout(function () { - _status.longpressed = false; - }, 500); - func.call(node, e); - if (lib.config.touchscreen && lib.config.enable_drag && !node._waitingfordrag) { - _status.mousedragging = null; - _status.mousedragorigin = null; - _status.clicked = false; - game.uncheck(); - game.check(); - _status.clicked = true; - } - delete node._waitingfordrag; - ui.click.touchpop(); - } - } - static longpresscancel() { - if (this._longpresstimeout) { - clearTimeout(this._longpresstimeout); - delete this._longpresstimeout; - } - delete this._longpressevent; - if (_status.longpressing == this) { - delete _status.longpressing; - } - } - static window() { - var clicked = _status.clicked; - var dialogtouched = false; - if (_status.dialogtouched) { - _status.dialogtouched = false; - dialogtouched = true; - } - if (_status.dragged) return; - if (_status.touchpopping) return; - if (_status.reloading) return; - if (_status.clicked || _status.clicked2) { - _status.clicked = false; - _status.clicked2 = false; - } - else { - if (_status.clickingidentity) { - for (var i = 0; i < _status.clickingidentity[1].length; i++) { - _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform = ''; - } - delete _status.clickingidentity; - } - if (!_status.event.isMine) return; - if (ui.controls.length) { - ui.updatec(); - } - if (_status.editing) { - if (_status.editing.innerHTML.length) { - _status.editing.link = _status.editing.innerHTML; - } - _status.editing.innerHTML = get.translation(_status.editing.link); - delete _status.editing; - } - else if (_status.choosing) { - if (!_status.choosing.expand) { - _status.choosing.parentNode.style.height = ''; - _status.choosing.nextSibling.delete(); - _status.choosing.previousSibling.show(); - delete _status.choosing; - } - } - else if (ui.intro) { - ui.intro.close(); - delete ui.intro; - ui.control.show(); - game.resume2(); - } - else if ((_status.event.isMine() || _status.event.forceMine) && !dialogtouched) { - if (_status.event.custom && _status.event.custom.replace.window) { - _status.event.custom.replace.window(); - } - else { - if (_status.event.skill && _status.event.name == 'chooseToUse') { - ui.click.cancel(); - } - else if (_status.event._checked) { - game.uncheck(); - game.check(); - } - } - } - if (!ui.shortcut.classList.contains('hidden')) { - ui.click.shortcut(false); - } - if (get.is.phoneLayout() && ui.menuContainer && ui.menuContainer.classList.contains('hidden')) { - if (ui.system2.classList.contains('shown')) { - _status.removinground = true; - setTimeout(function () { - _status.removinground = false; - }, 200); - } - ui.arena.classList.remove('phonetop'); - ui.system1.classList.remove('shown'); - ui.system2.classList.remove('shown'); - // if(ui.chessinfo){ - // ui.chessinfo.classList.remove('zoomed'); - // } - } - } - if (_status.tempunpop) { - _status.tempunpop = false; - } - else { - game.closePopped(); - } - if (_status.event.custom && _status.event.custom.add.window) { - _status.event.custom.add.window(clicked); - } - } - static toggle() { - if (_status.dragged) return; - if (this.parentNode.classList.contains('disabled')) return; - _status.tempunpop = true; - if (this.link) { - this.link = false; - this.classList.remove('on'); - if (this.additionalCommand) this.additionalCommand(false, this.parentNode); - } - else { - this.link = true; - this.classList.add('on'); - if (this.additionalCommand) this.additionalCommand(true, this.parentNode); - } - } - static editor() { - if (_status.dragged) return; - if (_status.editing) return; - _status.clicked = true; - this.innerHTML = ''; - _status.editing = this; - if (this.additionalCommand) this.additionalCommand(this); - } - static switcher() { - if (_status.dragged) return; - if (this.parentNode.classList.contains('disabled')) return; - if (_status.choosing) return; - _status.clicked = true; - _status.tempunpop = true; - this.previousSibling.hide(); - var node = ui.create.div('.switcher', this.parentNode).addTempClass('start'); - for (var i = 0; i < this.choice.length; i++) { - var choice = ui.create.div('.pointerdiv', node); - choice.innerHTML = get.translation(this.choice[i]); - choice.link = this.choice[i]; - choice.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.choice); - } - // this.parentNode.style.height=(node.offsetHeight)+'px'; - _status.choosing = this; - if (!_status.choosing.expand) { - _status.choosing.expand = true; - setTimeout(function () { - _status.choosing.expand = false; - }, 500); - } - } - static choice() { - if (_status.dragged) return; - if (!_status.choosing) return; - _status.choosing.link = this.link; - _status.choosing.innerHTML = get.translation(this.link); - this.parentNode.parentNode.style.height = ''; - this.parentNode.delete(); - _status.choosing.previousSibling.show(); - delete _status.choosing; - if (this.parentNode.parentNode.querySelector('.toggle').additionalCommand) { - this.parentNode.parentNode.querySelector('.toggle').additionalCommand(this.link, this.parentNode.parentNode); - } - } - static button() { - if (_status.dragged) return; - if (_status.clicked) return; - if (_status.tempNoButton) return; - if (_status.draggingtouchdialog) return; - if (this.classList.contains('noclick')) return; - if (_status.justdragged) return; - _status.clicked = true; - var custom = _status.event.custom; - if (custom && custom.replace.button) { - custom.replace.button(this); - return; - } - if (!_status.event.isMine()) return; - if (this.classList.contains('selectable') == false) return; - if (this.classList.contains('selected')) { - ui.selected.buttons.remove(this); - this.classList.remove('selected'); - if (_status.multitarget || _status.event.complexSelect) { - game.uncheck(); - game.check(); - } - } - else { - this.classList.add('selected'); - ui.selected.buttons.add(this); - } - if (custom && custom.add && custom.add.button) { - custom.add.button(); - } - game.check(); - } - static touchintro() { - var rect = this.getBoundingClientRect(); - ui.click.touchpop(); - ui.click.intro.call(this, { - clientX: rect.left + 18, - clientY: rect.top + 12 - }); - _status.clicked = false; - } - static card() { - delete this._waitingfordrag; - if (_status.dragged) return; - if (_status.clicked) return; - if (ui.intro) return; - _status.clicked = true; - if (this.parentNode && (this.parentNode.classList.contains('judges') || this.parentNode.classList.contains('marks'))) { - var rect = this.getBoundingClientRect(); - ui.click.touchpop(); - ui.click.intro.call(this, { - clientX: rect.left + 18, - clientY: rect.top + 12 - }); - _status.clicked = false; - return; - } - var custom = _status.event.custom; - if (custom && custom.replace.card) { - custom.replace.card(this); - return; - } - if (this.classList.contains('selectable') == false) return; - if (this.classList.contains('selected')) { - ui.selected.cards.remove(this); - if (_status.multitarget || _status.event.complexSelect) { - game.uncheck(); - game.check(); - } - else { - this.classList.remove('selected'); - this.updateTransform(); - } - } - else { - ui.selected.cards.add(this); - this.classList.add('selected'); - this.updateTransform(true); - } - if (game.chess && get.config('show_range') && !_status.event.skill && this.classList.contains('selected') && - _status.event.isMine() && _status.event.name == 'chooseToUse') { - var player = _status.event.player; - var range = get.info(this).range; - if (range) { - if (typeof range.attack === 'number') { - player.createRangeShadow(Math.min(8, player.getAttackRange(true) + range.attack - 1)); - } - else if (typeof range.global === 'number') { - player.createRangeShadow(Math.min(8, player.getGlobalFrom() + range.global)); - } - } - } - if (custom.add.card) { - custom.add.card(); - } - game.check(); - - if (lib.config.popequip && get.is.phoneLayout() && - arguments[0] != 'popequip' && ui.arena && ui.arena.classList.contains('selecting') && - this.parentNode && this.parentNode.classList.contains('popequip')) { - var rect = this.getBoundingClientRect(); - ui.click.touchpop(); - ui.click.intro.call(this.parentNode, { - clientX: rect.left + 18, - clientY: rect.top + 12 - }); - } - } - static avatar() { - if (!lib.config.doubleclick_intro) return; - if (this.parentNode.isUnseen(0)) return; - if (!lib.character[this.parentNode.name]) return; - if (!ui.menuContainer) return; - var avatar = this; - var player = this.parentNode; - if (!game.players.includes(player) && !game.dead.includes(player)) return; - if (!this._doubleClicking) { - this._doubleClicking = true; - setTimeout(function () { - avatar._doubleClicking = false; - }, 500); - return; - } - // ui.click.skin(this,player.name); - game.pause2(); - ui.click.charactercard(player.name1 || player.name, null, null, true, this); - } - static avatar2() { - if (!lib.config.doubleclick_intro) return; - if (this.parentNode.classList.contains('unseen2')) return; - if (!lib.character[this.parentNode.name2]) return; - if (!ui.menuContainer) return; - var avatar = this; - var player = this.parentNode; - if (!game.players.includes(player) && !game.dead.includes(player)) return; - if (!this._doubleClicking) { - this._doubleClicking = true; - setTimeout(function () { - avatar._doubleClicking = false; - }, 500); - return; - } - // ui.click.skin(this,player.name2); - game.pause2(); - ui.click.charactercard(player.name2, null, null, true, this); - } - static connectroom(e) { - if (_status.dragged) return; - if (_status.clicked) return; - if (ui.intro) return; - if (this.roomfull) { - alert('房间已满'); - } - else if (this.roomgaming && !game.onlineID) { - if (this.config && this.config.observe) { - alert('房间暂时不可旁观'); - } - else { - alert('房间不允许旁观'); - } - } - else if (!this.roomempty && this.version != lib.versionOL) { - if (this.version > lib.versionOL) { - alert('加入失败:你的游戏版本过低'); - } - else { - alert('加入失败:房主的游戏版本过低'); - } - } - else { - if (!_status.enteringroom) { - _status.enteringroom = true; - _status.enteringroomserver = this.serving; - game.send('server', 'enter', this.key, get.connectNickname(), lib.config.connect_avatar); - } - } - } - static player() { - return ui.click.target.apply(this, arguments); - } - static target(e) { - if (_status.dragged) return; - if (_status.clicked) return; - if (ui.intro) return; - if (this.classList.contains('connect')) { - if (game.online) { - if (game.onlinezhu) { - if (!this.playerid && game.connectPlayers) { - if (lib.configOL.mode == 'versus' || lib.configOL.mode == 'doudizhu') return; - if (lib.configOL.mode == 'identity' && lib.configOL.identity_mode == 'zhong') return; - if (!this.classList.contains('unselectable2') && lib.configOL.number <= 2) return; - this.classList.toggle('unselectable2') - if (this.classList.contains('unselectable2')) { - lib.configOL.number--; - } - else { - lib.configOL.number++; - } - game.send('changeNumConfig', lib.configOL.number, - game.connectPlayers.indexOf(this), this.classList.contains('unselectable2')); - } - } - return; - } - if (this.playerid) { - if (this.ws) { - if (confirm('是否踢出' + this.nickname + '?')) { - var id = get.id(); - this.ws.send(function (id) { - if (game.ws) { - game.ws.close(); - game.saveConfig('reconnect_info'); - game.saveConfig('banned_info', id); - } - }, id); - lib.node.banned.push(id); - } - } - } - else { - if (lib.configOL.mode == 'versus' || lib.configOL.mode == 'doudizhu' || lib.configOL.mode == 'single') return; - if (lib.configOL.mode == 'identity' && (lib.configOL.identity_mode == 'zhong' || lib.configOL.identity_mode == 'purple')) return; - if (!this.classList.contains('unselectable2') && lib.configOL.number <= 2) return; - this.classList.toggle('unselectable2') - if (this.classList.contains('unselectable2')) { - lib.configOL.number--; - } - else { - lib.configOL.number++; - } - game.send('server', 'config', lib.configOL); - game.updateWaiting(); - } - return; - } - _status.clicked = true; - var custom = _status.event.custom; - if (custom && custom.replace.target) { - custom.replace.target(this, e); - return; - } - if (this.classList.contains('selectable') == false) return; - this.unprompt(); - if (this.classList.contains('selected')) { - ui.selected.targets.remove(this); - if (_status.multitarget || _status.event.complexSelect) { - game.uncheck(); - game.check(); - } - else { - this.classList.remove('selected'); - } - } - else { - ui.selected.targets.add(this); - if (_status.event.name == 'chooseTarget' || _status.event.name == 'chooseToUse' || _status.event.name == 'chooseCardTarget') { - var targetprompt = null; - if (_status.event.targetprompt) { - targetprompt = _status.event.targetprompt; - } - else if (_status.event.skill && !get.info(_status.event.skill).viewAs) { - targetprompt = get.info(_status.event.skill).targetprompt; - } - else if (_status.event.name == 'chooseToUse') { - var currentcard = get.card(); - if (currentcard) { - targetprompt = get.info(currentcard).targetprompt; - } - } - if (targetprompt) { - if (Array.isArray(targetprompt)) { - targetprompt = targetprompt[Math.min(targetprompt.length - 1, ui.selected.targets.indexOf(this))]; - } - else if (typeof targetprompt == 'function') { - targetprompt = targetprompt(this); - } - if (targetprompt && typeof targetprompt == 'string') { - this.prompt(targetprompt); - } - } - } - this.classList.add('selected'); - } - if (custom.add.target) { - custom.add.target(); - } - game.check(); - } - static control2() { - if (this.childNodes.length == 1 && !this._doubleclick) { - ui.click.control.call(this.firstChild); - } - } - static control() { - if (_status.dragged) return; - if (ui.control.classList.contains('hidden')) return; - var node = this.parentNode; - if (node) { - if (node._doubleclick) { - return; - } - else { - node._doubleclick = true; - setTimeout(function () { - node._doubleclick = false; - }, 500); - } - if (node.classList.contains('hidden')) return; - if (node.classList.contains('removing')) return; - if (node.classList.contains('disabled')) return; - } - if (ui.intro) { - ui.intro.close(); - delete ui.intro; - } - _status.clicked = true; - if (this.parentNode.custom) { - this.parentNode.custom(this.link, this); - return; - } - if (this.link == 'ok') { - ui.click.ok(this); - } - else if (this.link == 'cancel') { - ui.click.cancel(this); - } - else { - _status.event.result = { - buttons: ui.selected.buttons.slice(0), - cards: ui.selected.cards.slice(0), - targets: ui.selected.targets.slice(0), - control: this.link, - links: get.links(ui.selected.buttons) - }; - if (this.parentNode.close != false) { - game.uncheck(); - this.parentNode.close(); - } - game.resume(); - } - } - static dialogcontrol() { - _status.event.result = { - buttons: ui.selected.buttons.slice(0), - cards: ui.selected.cards.slice(0), - targets: ui.selected.targets.slice(0), - control: this.link, - links: get.links(ui.selected.buttons) - }; - game.resume(); - } - static skill(skill) { - var info = get.info(skill); - var event = _status.event; - event.backup(skill); - if (info.filterCard && info.discard != false && info.lose != false && !info.viewAs) { - var cards = event.player.getCards(event.position); - for (var i = 0; i < cards.length; i++) { - if (!lib.filter.cardDiscardable(cards[i], event.player)) { - cards[i].uncheck('useSkill'); - } - } - } - if (typeof event.skillDialog == 'object') { - event.skillDialog.close(); - } - if (event.isMine()) { - event.skillDialog = true; - } - game.uncheck(); - game.check(); - if (event.skillDialog === true) { - var str = get.translation(skill); - if (info.prompt) { - var str2; - if (typeof info.prompt == 'function') { - str2 = info.prompt(event); - } - else { - str2 = info.prompt; - } - event.skillDialog = ui.create.dialog(str, '
      ' + str2 + '
      '); - if (info.longprompt) { - event.skillDialog.forcebutton = true; - ui.update(); - } - } - else if (info.promptfunc) { - event.skillDialog = ui.create.dialog(str, '
      ' + info.promptfunc(event, event.player) + '
      '); - } - else if (lib.dynamicTranslate[skill]) { - event.skillDialog = ui.create.dialog(str, '
      ' + lib.dynamicTranslate[skill](event.player, skill) + '
      '); - } - else if (lib.translate[skill + '_info']) { - event.skillDialog = ui.create.dialog(str, '
      ' + lib.translate[skill + '_info'] + '
      '); - } - } - } - static ok(node) { - const gameEvent = get.event(), custom = gameEvent.custom, replaceConfirm = custom.replace.confirm; - if (replaceConfirm) { - replaceConfirm(true); - return; - } - const result = gameEvent.result = { - buttons: ui.selected.buttons.slice(), - cards: ui.selected.cards.slice(), - targets: ui.selected.targets.slice(), - confirm: 'ok', - bool: true, - links: get.links(ui.selected.buttons) - }; - if (node) node.parentNode.close(); - const skill = gameEvent.skill; - if (skill) { - result.skill = skill; - const info = get.info(skill); - if (info && info.direct && !info.clearTime) { - result._noHidingTimer = true; - } - const skillInformation = get.info(gameEvent.skill), viewAs = skillInformation.viewAs; - if (typeof viewAs == 'function') { - const viewedAs = viewAs(result.cards, gameEvent.player); - if (viewedAs) result.card = get.autoViewAs(viewedAs); - } - else if (viewAs) result.card = get.autoViewAs(viewAs); - const resultCard = result.card; - if (resultCard) { - const cards = result.cards; - if (cards.length == 1) { - const firstCard = cards[0]; - if (!resultCard.suit) resultCard.suit = get.suit(firstCard); - if (!resultCard.number) resultCard.number = get.number(firstCard); - } - } - const skillDialog = gameEvent.skillDialog; - if (skillDialog && get.objtype(skillDialog) == 'div') skillDialog.close(); - gameEvent.player.getCards('hej').forEach(card => card.recheck('useSkill')); - gameEvent.restore(); - } - else if (['chooseToUse', 'chooseToRespond'].includes(gameEvent.name)) result.card = get.autoViewAs(result.cards[0]); - if (ui.skills) ui.skills.close(); - if (ui.skills2) ui.skills2.close(); - if (ui.skills3) ui.skills3.close(); - game.uncheck(); - const addConfirm = custom.add.confirm; - if (addConfirm) addConfirm(true); - game.resume(); - } - static cancel(node) { - var event = _status.event; - if (event.custom.replace.confirm) { - event.custom.replace.confirm(false); return; - } - if (event.skill && !event.norestore) { - if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { - event.skillDialog.close(); - } - if (typeof event.dialog == 'string' && event.isMine()) { - event.dialog = ui.create.dialog(event.dialog); - } - if (_status.event.type == 'phase' && ui.confirm) { - ui.confirm.classList.add('removing'); - } - // ui.control.addTempClass('nozoom',100); - event.restore(); - var cards = event.player.getCards('hej'); - for (var i = 0; i < cards.length; i++) { - cards[i].recheck('useSkill'); - } - game.uncheck(); - game.check(); - return; - } - event.result = { - confirm: 'cancel', - bool: false - }; - if (node) { - node.parentNode.close(); - } - if (ui.skills) ui.skills.close(); - if (ui.skills2) ui.skills2.close(); - if (ui.skills3) ui.skills3.close(); - game.uncheck(); - if (event.custom.add.confirm) { - event.custom.add.confirm(true); - } - game.resume(); - } - static logv(e) { - if (_status.currentlogv) { - if (_status.currentlogv == this) return; - if (_status.logvtimeout) { - clearTimeout(_status.logvtimeout); - } - var that = this; - _status.logvtimeout = setTimeout(function () { - if (!_status.currentlogv) { - _status.currentlogv = that; - ui.click.intro.call(that, e); - } - }, 200); - this.logvtimeout = _status.logvtimeout; - } - else { - _status.currentlogv = this; - ui.click.intro.call(this, e); - } - } - static logvleave() { - if (_status.currentlogv == this) { - setTimeout(function () { - delete _status.currentlogv; - }, 150); - } - if (this.logvtimeout) { - clearTimeout(this.logvtimeout); - if (_status.logvtimeout == this.logvtimeout) { - delete _status.logvtimeout; - } - delete this.logvtimeout; - } - } - static charactercard(name, sourcenode, noedit, resume, avatar) { - if (_status.dragged) return; - if (lib.config.theme != 'simple') { - ui.window.classList.add('shortcutpaused'); - ui.menuContainer.classList.add('forceopaque'); - } - else { - ui.window.classList.add('systempaused'); - ui.menuContainer.classList.add('transparent2'); - } - if (lib.config.blur_ui) { - ui.arena.classList.add('blur'); - ui.system.classList.add('blur'); - ui.menuContainer.classList.add('blur'); - } - var layer = ui.create.div('.popup-container'); - var clicklayer = function (e) { - if (_status.touchpopping) return; - if (_status.dragged) return; - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); - ui.menuContainer.classList.remove('forceopaque'); - ui.menuContainer.classList.remove('transparent2'); - ui.arena.classList.remove('blur'); - ui.system.classList.remove('blur'); - ui.menuContainer.classList.remove('blur'); - this.delete(); - e.stopPropagation(); - if (resume) game.resume2(); - return false; - } - var uiintro = ui.create.div('.menubg.charactercard', layer); - var playerbg = ui.create.div('.menubutton.large.ava', uiintro); - var bg = ui.create.div('.avatar', playerbg, function () { - if (changeskinfunc) { - changeskinfunc(); - } - }).setBackground(name, 'character'); - var changeskinfunc = null; - var nameskin = name; - var nameskin2 = name; - var gzbool = false; - if (nameskin.startsWith('gz_shibing')) { - nameskin = nameskin.slice(3, 11); - } - else if (nameskin.startsWith('gz_')) { - nameskin = nameskin.slice(3); - gzbool = true; - } - var changeskin = function () { - var node = ui.create.div('.changeskin', '可换肤', playerbg); - var avatars = ui.create.div('.avatars', playerbg); - changeskinfunc = function () { - playerbg.classList.add('scroll'); - if (node._created) { - return; - } - node._created = true; - var createButtons = function (num) { - if (!num) return; - if (num >= 4) { - avatars.classList.add('scroll'); - if (lib.config.touchscreen) { - lib.setScroll(avatars); - } - } - for (var i = 0; i <= num; i++) { - var button = ui.create.div(avatars, function () { - playerbg.classList.remove('scroll'); - if (this._link) { - lib.config.skin[nameskin] = this._link; - bg.style.backgroundImage = this.style.backgroundImage; - if (sourcenode) sourcenode.style.backgroundImage = this.style.backgroundImage; - if (avatar) avatar.style.backgroundImage = this.style.backgroundImage; - game.saveConfig('skin', lib.config.skin); - } - else { - delete lib.config.skin[nameskin]; - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) { - bg.setBackground(nameskin2, 'character'); - if (sourcenode) sourcenode.setBackground(nameskin2, 'character'); - if (avatar) avatar.setBackground(nameskin2, 'character'); - } - else { - bg.setBackground(nameskin, 'character'); - if (sourcenode) sourcenode.setBackground(nameskin, 'character'); - if (avatar) avatar.setBackground(nameskin, 'character'); - } - game.saveConfig('skin', lib.config.skin); - } - }); - button._link = i; - if (i) { - button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); - } - else { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); - else button.setBackground(nameskin, 'character', 'noskin'); - } - } - }; - var num = 1; - var loadImage = function () { - var img = new Image(); - img.onload = function () { - num++; - loadImage(); - } - img.onerror = function () { - num--; - createButtons(num); - } - img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; - } - if (lib.config.change_skin) { - loadImage(); - } - else { - createButtons(lib.skin[nameskin]); - } - }; - }; - if (lib.config.change_skin) { - var img = new Image(); - img.onload = changeskin; - img.src = lib.assetURL + 'image/skin/' + nameskin + '/1.jpg'; - } - else if (lib.config.debug && lib.skin[nameskin]) { - changeskin(); - } - var ban = ui.create.div('.menubutton.large.ban.character', uiintro, '禁用', function (e) { - if (this.classList.contains('unselectable')) return; - if (typeof noedit == 'string') { - this.classList.toggle('active'); - var bannedname = noedit + '_banned'; - if (!lib.config[bannedname]) { - lib.config[bannedname] = []; - } - if (this.classList.contains('active')) { - lib.config[bannedname].add(name); - } - else { - lib.config[bannedname].remove(name); - } - game.saveConfig(bannedname, lib.config[bannedname]); - ban.updateBanned(); - } - else { - ui.click.touchpop(); - ui.click.intro.call(this, e); - _status.clicked = true; - } - }); - ban.link = name; - ban._banning = 'offline'; - ban.updateBanned = function () { - if (noedit === true) return; - if (lib.config[get.mode() + '_banned'] && lib.config[get.mode() + '_banned'].includes(name)) { - ban.classList.add('active'); - } - else { - ban.classList.remove('active'); - } - if (sourcenode && sourcenode.updateBanned) { - sourcenode.updateBanned(); - } - }; - ban.updateBanned(); - var fav = ui.create.div('.menubutton.large.fav', uiintro, '收藏', function () { - if (this.classList.contains('unselectable')) return; - this.classList.toggle('active'); - if (this.classList.contains('active')) { - lib.config.favouriteCharacter.add(name); - } - else { - lib.config.favouriteCharacter.remove(name); - } - game.saveConfig('favouriteCharacter', lib.config.favouriteCharacter); - }); - if (noedit === true) { - fav.classList.add('unselectable'); - ban.classList.add('unselectable'); - } - else if (lib.config.favouriteCharacter.includes(name)) { - fav.classList.add('active'); - } - - // 样式二 - if (lib.config.show_characternamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_characternamepinyin == 'showCodeIdentifier2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') { - var intro = ui.create.div('.characterintro', get.characterIntro(name), uiintro); - if (lib.config.show_characternamepinyin == 'showPinyin2' || lib.config.show_characternamepinyin == 'showCodeIdentifier2') { - var charactername = get.rawName2(name); - var characterpinyin = lib.config.show_characternamepinyin == 'showCodeIdentifier2' ? name : get.pinyin(charactername); - var nameinfo = get.character(name); - var charactersex = get.translation(nameinfo[0]); - const charactergroups = get.is.double(name, true); - let charactergroup; - if (charactergroups) charactergroup = charactergroups.map(i => get.translation(i)).join('/') - else charactergroup = get.translation(nameinfo[1]); - var characterhp = nameinfo[2]; - var characterintroinfo = get.characterIntro(name); - var spacemark = ' | '; - if (charactername.length > 3) spacemark = '' + ' ' + '' + '|' + '' + ' ' + ''; - intro.innerHTML = '' + charactername + '' + '' + '[' + characterpinyin + ']' + '' + spacemark + charactersex + spacemark + charactergroup + spacemark + characterhp + '' + '
      ' + characterintroinfo; - } - var intro2 = ui.create.div('.characterintro.intro2', uiintro); - var list = get.character(name, 3) || []; - var skills = ui.create.div('.characterskill', uiintro); - if (lib.config.touchscreen) { - lib.setScroll(intro); - lib.setScroll(intro2); - lib.setScroll(skills); - } - - if (lib.config.mousewheel) { - skills.onmousewheel = ui.click.mousewheel; - } - var clickSkill = function (e) { - while (intro2.firstChild) { - intro2.removeChild(intro2.lastChild); - } - var current = this.parentNode.querySelector('.active'); - if (current) { - current.classList.remove('active'); - } - this.classList.add('active'); - var skillname = get.translation(this.link); - var skilltranslationinfo = get.skillInfoTranslation(this.link); - if ((lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') && skillname != '阵亡') { - var skillpinyin = lib.config.show_skillnamepinyin == 'showCodeIdentifier2' ? this.link : get.pinyin(skillname); - intro2.innerHTML = '' + skillname + '' + '' + '[' + skillpinyin + ']' + '' + ' ' + skilltranslationinfo; - } else { - intro2.innerHTML = '' + skillname + '' + skilltranslationinfo; - } - var info = get.info(this.link); - var skill = this.link; - var playername = this.linkname; - var skillnode = this; - if (info.derivation) { - var derivation = info.derivation; - if (typeof derivation == 'string') { - derivation = [derivation]; - } - for (var i = 0; i < derivation.length; i++) { - var derivationname = get.translation(derivation[i]); - var derivationtranslationinfo = get.skillInfoTranslation(derivation[i]); - if ((lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') && derivationname.length <= 5 && derivation[i].indexOf('_faq') == -1) { - var derivationpinyin = lib.config.show_skillnamepinyin == 'showCodeIdentifier2' ? derivation[i] : get.pinyin(derivationname); - intro2.innerHTML += '

      ' + derivationname + '' + '' + '[' + derivationpinyin + ']' + '' + ' ' + derivationtranslationinfo; - } else { - intro2.innerHTML += '

      ' + derivationname + '' + derivationtranslationinfo; - } - } - } - if (info.alter) { - intro2.innerHTML += '

      '; - var skillversionnode = intro2.querySelector('.hrefnode.skillversion'); - if (lib.config.vintageSkills.includes(skill)) { - skillversionnode.innerHTML = '切换至新版'; - } - else { - skillversionnode.innerHTML = '切换至旧版'; - } - skillversionnode.listen(function () { - if (lib.config.vintageSkills.includes(skill)) { - lib.config.vintageSkills.remove(skill); - lib.translate[skill + '_info'] = lib.translate[skill + '_info_alter']; - } - else { - lib.config.vintageSkills.push(skill); - lib.translate[skill + '_info'] = lib.translate[skill + '_info_origin']; - } - game.saveConfig('vintageSkills', lib.config.vintageSkills); - clickSkill.call(skillnode, 'init'); - }); - } - // if(e!=='init') game.trySkillAudio(this.link,playername); - // 有bug,先用旧版 - if (lib.config.background_speak && e !== 'init') { - let audio, skillnode = this; - (function play() { - if (!skillnode.audioList || !skillnode.audioList.length) { - skillnode.audioList = game.parseSkillAudio(skillnode.link, playername); - if (!skillnode.audioList.length) return; - } - audio = skillnode.audioList.shift(); - game.playAudio(audio, play); - })(); - } - } - } - else { - // 样式一 - const introduction = ui.create.div('.characterintro', uiintro), showCharacterNamePinyin = lib.config.show_characternamepinyin; - if (showCharacterNamePinyin != 'doNotShow') { - const characterIntroTable = ui.create.div('.character-intro-table', introduction), span = document.createElement('span'); - span.style.fontWeight = 'bold'; - const nameInfo = get.character(name), exInfo = nameInfo[4], characterName = exInfo && exInfo.includes('ruby') ? lib.translate[name] : get.rawName2(name); - span.innerHTML = characterName; - const ruby = document.createElement('ruby'); - ruby.appendChild(span); - const leftParenthesisRP = document.createElement('rp'); - leftParenthesisRP.textContent = '('; - ruby.appendChild(leftParenthesisRP); - const rt = document.createElement('rt'); - rt.innerHTML = showCharacterNamePinyin == 'showCodeIdentifier' ? name : lib.translate[`${name}_rt`] || get.pinyin(characterName).join(' '); - ruby.appendChild(rt); - const rightParenthesisRP = document.createElement('rp'); - rightParenthesisRP.textContent = ')'; - ruby.appendChild(rightParenthesisRP); - characterIntroTable.appendChild(ruby); - const characterSexDiv = ui.create.div('.character-sex', characterIntroTable), exInfoSex = exInfo && exInfo.find(value => value.startsWith('sex:')), characterSex = exInfoSex ? exInfoSex.split(':').pop() : nameInfo[0]; - new Promise((resolve, reject) => { - const imageName = `sex_${characterSex}`, information = lib.card[imageName]; - if (!information) { - resolve(`${lib.assetURL}image/card/${imageName}.png`) - return; - } - const image = information.image; - if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); - else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); - else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); - else resolve(`${lib.assetURL}${image}`); - }).then(source => new Promise((resolve, reject) => { - const image = new Image(); - image.onload = () => resolve(image); - image.onerror = reject; - image.src = source; - })).then(image => characterSexDiv.appendChild(image)).catch(() => characterSexDiv.innerHTML = get.translation(characterSex)); - const characterGroupDiv = ui.create.div('.character-group', characterIntroTable), characterGroups = get.is.double(name, true); - if (characterGroups) Promise.all(characterGroups.map(characterGroup => new Promise((resolve, reject) => { - const imageName = `group_${characterGroup}`, information = lib.card[imageName]; - if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); - const image = information.image; - if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); - else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); - else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); - else resolve(`${lib.assetURL}${image}`); - }).then(source => new Promise((resolve, reject) => { - const image = new Image(); - image.onload = () => resolve(image); - image.onerror = reject; - image.src = source; - })))).then(images => { - let documentFragment = document.createDocumentFragment(); - images.forEach(documentFragment.appendChild, documentFragment); - characterGroupDiv.appendChild(documentFragment); - }).catch(() => characterGroupDiv.innerHTML = characterGroups.map(characterGroup => get.translation(characterGroup)).join('/')); - else { - const characterGroup = nameInfo[1]; - new Promise((resolve, reject) => { - const imageName = `group_${characterGroup}`, information = lib.card[imageName]; - if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); - const image = information.image; - if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); - else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); - else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); - else resolve(`${lib.assetURL}${image}`); - }).then(source => new Promise((resolve, reject) => { - const image = new Image(); - image.onload = () => resolve(image); - image.onerror = reject; - image.src = source; - })).then(image => characterGroupDiv.appendChild(image)).catch(() => characterGroupDiv.innerHTML = get.translation(characterGroup)); - } - const hpDiv = ui.create.div('.hp', characterIntroTable), nameInfoHP = nameInfo[2], infoHP = get.infoHp(nameInfoHP); - hpDiv.dataset.condition = infoHP < 4 ? 'mid' : 'high'; - ui.create.div(hpDiv); - const hpTextDiv = ui.create.div('.text', hpDiv), infoMaxHP = get.infoMaxHp(nameInfoHP); - hpTextDiv.innerHTML = infoHP == infoMaxHP ? `×${infoHP}` : `×${infoHP}/${infoMaxHP}`; - const infoShield = get.infoHujia(nameInfoHP); - if (infoShield) { - ui.create.div('.shield', hpDiv); - const shieldTextDiv = ui.create.div('.text', hpDiv); - shieldTextDiv.innerHTML = `×${infoShield}`; - } - introduction.appendChild(document.createElement('hr')); - } - const htmlParser = document.createElement('body'); - htmlParser.innerHTML = get.characterIntro(name); - Array.from(htmlParser.childNodes).forEach(value => introduction.appendChild(value)); - const introduction2 = ui.create.div('.characterintro.intro2', uiintro); - var list = get.character(name, 3) || []; - var skills = ui.create.div('.characterskill', uiintro); - if (lib.config.touchscreen) { - lib.setScroll(introduction); - lib.setScroll(introduction2); - lib.setScroll(skills); - } - - if (lib.config.mousewheel) { - skills.onmousewheel = ui.click.mousewheel; - } - var clickSkill = function (e) { - while (introduction2.firstChild) { - introduction2.removeChild(introduction2.lastChild); - } - var current = this.parentNode.querySelector('.active'); - if (current) { - current.classList.remove('active'); - } - this.classList.add('active'); - const skillNameSpan = document.createElement('span'), skillNameSpanStyle = skillNameSpan.style; - skillNameSpanStyle.fontWeight = 'bold'; - const link = this.link, skillName = get.translation(link); - skillNameSpan.innerHTML = skillName; - const showSkillNamePinyin = lib.config.show_skillnamepinyin; - if (showSkillNamePinyin != 'doNotShow' && skillName != '阵亡') { - const ruby = document.createElement('ruby'); - ruby.appendChild(skillNameSpan); - const leftParenthesisRP = document.createElement('rp'); - leftParenthesisRP.textContent = '('; - ruby.appendChild(leftParenthesisRP); - const rt = document.createElement('rt'); - rt.innerHTML = showSkillNamePinyin == 'showCodeIdentifier' ? link : lib.translate[`${link}_rt`] || get.pinyin(skillName).join(' '); - ruby.appendChild(rt); - const rightParenthesisRP = document.createElement('rp'); - rightParenthesisRP.textContent = ')'; - ruby.appendChild(rightParenthesisRP); - const div = ui.create.div(introduction2); - div.style.marginRight = '5px'; - div.appendChild(ruby); - } - else { - skillNameSpanStyle.marginRight = '5px'; - introduction2.appendChild(skillNameSpan); - } - htmlParser.innerHTML = get.skillInfoTranslation(this.link); - Array.from(htmlParser.childNodes).forEach(childNode => introduction2.appendChild(childNode)); - var info = get.info(this.link); - var skill = this.link; - var playername = this.linkname; - var skillnode = this; - let derivations = info.derivation; - if (derivations) { - if (typeof derivations == 'string') derivations = [derivations]; - derivations.forEach(derivation => { - introduction2.appendChild(document.createElement('br')); - introduction2.appendChild(document.createElement('br')); - const derivationNameSpan = document.createElement('span'), derivationNameSpanStyle = derivationNameSpan.style; - derivationNameSpanStyle.fontWeight = 'bold'; - const derivationName = get.translation(derivation); - derivationNameSpan.innerHTML = derivationName; - if (showSkillNamePinyin != 'doNotShow' && derivationName.length <= 5 && derivation.indexOf('_faq') == -1) { - const ruby = document.createElement('ruby'); - ruby.appendChild(derivationNameSpan); - const leftParenthesisRP = document.createElement('rp'); - leftParenthesisRP.textContent = '('; - ruby.appendChild(leftParenthesisRP); - const rt = document.createElement('rt'); - rt.innerHTML = showSkillNamePinyin == 'showCodeIdentifier' ? derivation : lib.translate[`${derivation}_rt`] || get.pinyin(derivationName).join(' '); - ruby.appendChild(rt); - const rightParenthesisRP = document.createElement('rp'); - rightParenthesisRP.textContent = ')'; - ruby.appendChild(rightParenthesisRP); - const div = ui.create.div(introduction2); - div.style.marginRight = '5px'; - div.appendChild(ruby); - } - else { - derivationNameSpanStyle.marginRight = '5px'; - introduction2.appendChild(derivationNameSpan); - } - htmlParser.innerHTML = get.skillInfoTranslation(derivation); - Array.from(htmlParser.childNodes).forEach(childNode => introduction2.appendChild(childNode)); - }); - } - if (info.alter) { - introduction2.appendChild(document.createElement('br')); - introduction2.appendChild(document.createElement('br')); - ui.create.div('.hrefnode.skillversion', introduction2); - var skillversionnode = introduction2.querySelector('.hrefnode.skillversion'); - if (lib.config.vintageSkills.includes(skill)) { - skillversionnode.innerHTML = '切换至新版'; - } - else { - skillversionnode.innerHTML = '切换至旧版'; - } - skillversionnode.listen(function () { - if (lib.config.vintageSkills.includes(skill)) { - lib.config.vintageSkills.remove(skill); - lib.translate[skill + '_info'] = lib.translate[skill + '_info_alter']; - } - else { - lib.config.vintageSkills.push(skill); - lib.translate[skill + '_info'] = lib.translate[skill + '_info_origin']; - } - game.saveConfig('vintageSkills', lib.config.vintageSkills); - clickSkill.call(skillnode, 'init'); - }); - } - // if(e!=='init') game.trySkillAudio(this.link,playername); - // 有bug,先用旧版 - if (lib.config.background_speak && e !== 'init') { - let audio, skillnode = this; - (function play() { - if (!skillnode.audioList || !skillnode.audioList.length) { - skillnode.audioList = game.parseSkillAudio(skillnode.link, playername); - if (!skillnode.audioList.length) return; - } - audio = skillnode.audioList.shift(); - game.playAudio(audio, play); - })(); - } - } - } - - var initskill = false; - for (var i = 0; i < list.length; i++) { - if (!get.info(list[i]) || get.info(list[i]).nopop) continue; - if (!lib.translate[list[i]] || !lib.translate[list[i] + '_info']) continue; - var skilltrans = get.translation(list[i]); - if (skilltrans.startsWith(' ')) { - skilltrans = skilltrans.slice(6); - } - var current = ui.create.div('.menubutton.large', skills, clickSkill, skilltrans); - current.link = list[i]; - current.linkname = name; - if (!initskill) { - initskill = true; - clickSkill.call(current, 'init'); - } - } - - uiintro.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.touchpop); - layer.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clicklayer); - ui.window.appendChild(layer); - } - static intro(e) { - if (_status.dragged) return; - _status.clicked = true; - if (this.classList.contains('player') && !this.name) { - return; - } - if (this.parentNode == ui.historybar) { - if (ui.historybar.style.zIndex == '22') { - if (_status.removePop) { - if (_status.removePop(this) == false) return; - } - else { - return; - } - } - ui.historybar.style.zIndex = 22; - } - var uiintro; - if (this.classList.contains('card') && this.parentNode && - this.parentNode.classList.contains('equips') && get.is.phoneLayout() && - !get.is.mobileMe(this.parentNode.parentNode)) { - uiintro = get.nodeintro(this.parentNode.parentNode, false, e); - } - uiintro = uiintro || get.nodeintro(this, false, e); - if (!uiintro) return; - uiintro.classList.add('popped'); - uiintro.classList.add('static'); - ui.window.appendChild(uiintro); - var layer = ui.create.div('.poplayer', ui.window); - var clicklayer = function (e) { - if (_status.touchpopping) return; - delete ui.throwEmotion; - delete _status.removePop; - uiintro.delete(); - this.remove(); - ui.historybar.style.zIndex = ''; - delete _status.currentlogv; - if (!ui.arena.classList.contains('menupaused') && !uiintro.noresume) game.resume2(); - if (e && e.stopPropagation) e.stopPropagation(); - if (uiintro._onclose) { - uiintro._onclose(); - } - return false; - } - layer.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clicklayer); - if (!lib.config.touchscreen) layer.oncontextmenu = clicklayer; - if (this.parentNode == ui.historybar && lib.config.touchscreen) { - var rect = this.getBoundingClientRect(); - e = { clientX: 0, clientY: rect.top + 30 }; - } - lib.placePoppedDialog(uiintro, e); - if (this.parentNode == ui.historybar) { - if (lib.config.show_history == 'right') { - uiintro.style.left = (ui.historybar.offsetLeft - 230) + 'px'; - } - else { - uiintro.style.left = (ui.historybar.offsetLeft + 60) + 'px'; - } - } - uiintro.style.zIndex = 21; - var clickintro = function () { - if (_status.touchpopping) return; - delete _status.removePop; - layer.remove(); - this.delete(); - ui.historybar.style.zIndex = ''; - delete _status.currentlogv; - if (!ui.arena.classList.contains('menupaused') && !uiintro.noresume) game.resume2(); - if (uiintro._onclose) { - uiintro._onclose(); - } - }; - var currentpop = this; - _status.removePop = function (node) { - if (node == currentpop) return false; - layer.remove(); - uiintro.delete(); - delete _status.removePop; - return true; - }; - if (uiintro.clickintro) { - uiintro.listen(function () { - _status.clicked = true; - }); - uiintro._clickintro = clicklayer; - } - else if (!lib.config.touchscreen) { - uiintro.addEventListener('mouseleave', clickintro); - uiintro.addEventListener('click', clickintro); - } - else if (uiintro.touchclose) { - uiintro.listen(clickintro); - } - uiintro._close = clicklayer; - - game.pause2(); - return uiintro; - } - static intro2() { - if (ui.intro) { - ui.intro.close(); - if (ui.intro.source == this) { - delete ui.intro; - ui.control.show(); - game.resume2(); - return; - } - } - } - static auto() { - if (!ui || !ui.auto || ui.auto.classList.contains('hidden') && arguments[0] !== 'forced') return; - if (_status.paused2) return; - ui.click.shortcut(false); - if (!_status.auto) { - _status.auto = true; - ui.auto.classList.add('glow'); - ui.arena.classList.add('auto'); - - if (_status.imchoosing && _status.paused) { - if (ui.confirm) ui.confirm.close(); - ui.control.hide(); - if (_status.event.switchToAuto) { - _status.event.switchToAuto(); - } - else { - if (_status.paused && _status.imchoosing) { - game.uncheck(); - _status.event.redo(); - } - } - game.resume(); - } - else if (_status.event.switchToAuto) { - _status.event.switchToAuto(); - } - if (game.online) { - game.send('auto'); - } - else if (_status.connectMode) { - game.broadcastAll(function (player) { - player.setNickname(player.nickname + ' - 托管'); - }, game.me); - } - } - else { - if (game.notMe) return; - ui.control.show(); - _status.auto = false; - ui.auto.classList.remove('glow'); - ui.arena.classList.remove('auto'); - - if (game.online) { - game.send('unauto'); - } - else if (_status.connectMode) { - game.broadcastAll(function (player) { - player.setNickname(player.nickname); - }, game.me); - } - } - } - static wuxie() { - if (this.classList.contains('hidden')) return; - this.classList.toggle('glow'); - if (this.classList.contains('glow') && _status.event.type == 'wuxie' && - _status.event.isMine() && ui.confirm && _status.imchoosing) { - ui.click.cancel(ui.confirm.lastChild); - } - } - static tempnowuxie() { - if (this.classList.contains('hidden')) return; - this.classList.toggle('glow'); - if (this.classList.contains('glow') && _status.event.type == 'wuxie' && - _status.event.isMine() && ui.confirm && _status.imchoosing) { - var triggerevent = _status.event.getTrigger(); - if (triggerevent && this._origin == triggerevent.parent.id) { - if (triggerevent.targets && triggerevent.num == triggerevent.targets.length - 1) { - this.close(); - } - } - ui.click.cancel(ui.confirm.lastChild); - } - } - static pause() { - if (_status.paused2 || _status.pausing || _status.nopause || !ui.pause) return; - if (!_status.video) { - if (ui.pause.classList.contains('hidden')) return; - if (!_status.gameStarted) return; - } - ui.system.hide(); - game.pause2(); - var node = ui.create.pause(); - if (!node) return; - node.addTempClass('start'); - ui.sidebar3.innerHTML = ''; - if (lib.config.show_discardpile) { - for (var i = 0; i < ui.discardPile.childNodes.length; i++) { - var div = ui.create.div(ui.sidebar3); - div.innerHTML = get.translation(ui.discardPile.childNodes[i]); - ui.sidebar3.insertBefore(div, ui.sidebar3.firstChild); - } - } - node.appendChild(ui.sidebar); - node.appendChild(ui.sidebar3); - ui.historybar.classList.add('paused'); - ui.arena.classList.add('paused'); - ui.window.classList.add('touchinfohidden'); - ui.time.hide(); - if (game.onpause) { - game.onpause(); - } - } - static resume(e) { - if (_status.pausing) return; - if (_status.dragged) return; - if (_status.clicked) return; - this.delete(); - ui.system.show(); - ui.time.show(); - ui.historybar.classList.remove('paused'); - ui.arena.classList.remove('paused'); - ui.window.classList.remove('touchinfohidden'); - game.resume2(); - e.stopPropagation(); - if (game.onresume) { - game.onresume(); - } - return false; - } - static config() { - if (!ui.click.configMenu) return; - if (_status.paused2) _status.config2 = false; - else _status.config2 = true; - - _status.clicked = true; - game.pause2(); - ui.click.configMenu(); - ui.system1.classList.remove('shown'); - ui.system2.classList.remove('shown'); - } - static swap() { - if (_status.dragged) return; - if (this.classList.contains('dead')) return; - if (_status.over) return; - if (ui.auto) ui.auto.show(); - if (ui.wuxie) ui.wuxie.show(); - game.swapPlayer(this); - } - static mousewheel(evt) { - if (this.firstChild && this.firstChild.classList.contains('handcards') && - !this.classList.contains('scrollh')) return; - var node = this; - var num = this._scrollnum || 6; - var speed = this._scrollspeed || 16; - clearInterval(node.interval); - if (evt.detail > 0 || evt.wheelDelta < 0) { - node.interval = setInterval(function () { - if (num-- && Math.abs(node.scrollLeft + node.clientWidth - node.scrollWidth) > 0) { - node.scrollLeft += speed; - } - else { - clearInterval(node.interval); - } - }, 16); - } - else { - node.interval = setInterval(function () { - if (num-- && node.scrollLeft > 0) { - node.scrollLeft -= speed; - } - else { - clearInterval(node.interval); - } - }, 16); - } - } - static touchStart(e) { - this.startX = e.touches[0].clientX / game.documentZoom; - this.startY = e.touches[0].clientY / game.documentZoom; - _status.dragged = false; - } - static dialogtouchStart(e) { - ui.click.touchStart.call(this, e); - _status.dialogtouched = true; - } - static touchScroll(e) { - if (_status.mousedragging) return; - if (_status.draggingtouchdialog) return; - if (!_status.dragged) { - if (Math.abs(e.touches[0].clientX / game.documentZoom - this.startX) > 10 || - Math.abs(e.touches[0].clientY / game.documentZoom - this.startY) > 10) { - _status.dragged = true; - } - } - if ((this == ui.handcards1Container || this == ui.handcards2Container) && !this.classList.contains('scrollh')) { - e.preventDefault(); - } - else if (lib.device == 'ios' && this.scrollHeight <= this.offsetHeight + 5 && this.scrollWidth <= this.offsetWidth + 5) { - e.preventDefault(); - } - else { - delete _status._swipeorigin; - e.stopPropagation(); - } - } - static autoskill(bool, node) { - var list = lib.config.autoskilllist; - if (bool) { - list.remove(node.link); - } - else { - list.add(node.link); - } - game.saveConfig('autoskilllist', list); - } - static skillbutton() { - this.func(this.link); - } - static autoskill2(e) { - this.classList.toggle('on'); - var list = []; - if (lib.skill[this.link].frequent) { - list.push(this.link); - } - if (lib.skill[this.link].subfrequent) { - for (var i = 0; i < lib.skill[this.link].subfrequent.length; i++) { - list.push(this.link + '_' + lib.skill[this.link].subfrequent[i]); - } - } - for (var i = 0; i < list.length; i++) { - if (this.classList.contains('on')) { - lib.config.autoskilllist.remove(list[i]); - } - else { - lib.config.autoskilllist.add(list[i]); - } - } - game.saveConfig('autoskilllist', lib.config.autoskilllist); - ui.click.touchpop(); - e.stopPropagation(); - } - static hiddenskill(e) { - this.classList.toggle('on'); - var hidden = lib.skill[this.link].preHidden; - if (Array.isArray(hidden)) { - if (this.classList.contains('on')) { - _status.prehidden_skills.removeArray(hidden); - } - else { - _status.prehidden_skills.addArray(hidden); - } - } - if (this.classList.contains('on')) { - _status.prehidden_skills.remove(this.link); - } - else { - _status.prehidden_skills.add(this.link); - } - ui.click.touchpop(); - e.stopPropagation(); - } - static rightplayer(e) { - if (this._nopup) return false; - if (_status.clickedplayer) { - return false; - } - - if (this._mouseenterdialog && this._mouseenterdialog.parentNode) { - this._mouseenterdialog.delete(); - } - else { - ui.click.intro.call(this, e); - } - _status.clickedplayer = true; - _status.clicked = false; - ui.click.longpresscancel.call(this); - return false; - } - static right(e) { - if (window.inSplash) return false; - if (lib.config.touchscreen) return; - if (_status.noright) { - _status.noright = false; - return false; - } - if (_status.clickedplayer) { - _status.clickedplayer = false; - return; - } - game.closePopped(); - switch (lib.config.right_click) { - case 'shortcut': ui.click.shortcut(); break; - case 'pause': ui.click.pause(); break; - case 'auto': ui.click.auto(); break; - case 'config': ui.click.config(); break; - } - e.preventDefault(); - return false; - } - -} - -export class UI extends Uninstantable { - static updates = []; - static thrown = []; - static touchlines = []; - static todiscard = {}; - /** - * @type { HTMLStyleElement[] } - */ - static playerPositions = []; - static create = Create; - static click = Click; - static selected = { - /** - * @type { Button[] } - */ - buttons: [], - /** - * @type { Card[] } - */ - cards: [], - /** - * @type { Player[] } - */ - targets: [] - } - /** - * @type { Dialog[] } - */ - static dialogs; - /** - * @type { Dialog } - */ - static dialog; - /** - * @type { HTMLDivElement } - */ - static arena; - /** - * @type { Control[] } - */ - static controls; - /** - * @type { Control } - */ - static control; - /** - * @type { Control | undefined } - */ - static confirm; - /** - * @type { Control | undefined } - */ - static skills; - /** - * @type { Control | undefined } - */ - static skills1; - /** - * @type { Control | undefined } - */ - static skills2; - /** - * @type { Control | undefined } - */ - static skills3; - static refresh(node) { - void window.getComputedStyle(node, null).getPropertyValue("opacity"); - } - static clear() { - game.addVideo('uiClear'); - var thrown = document.getElementsByClassName('thrown'); - var nodes = []; - var i; - for (i = 0; i < thrown.length; i++) { - nodes.push(thrown[i]); - } - for (i = 0; i < nodes.length; i++) { - if (!nodes[i].fixed) nodes[i].delete(); - } - } - static updatec() { - if (_status.noupdatec) return; - var length = 0, minoffset = -Infinity; - var controls = []; - var widths = []; - var leftwidths = []; - var add = function (node, first) { - var thiswidth = parseInt(node.style.width); - if (thiswidth) { - thiswidth += 8; - length += thiswidth; - if (first) { - leftwidths.push(thiswidth); - } - else { - widths.push(thiswidth); - } - } - else { - length += node.offsetWidth; - if (first) { - leftwidths.push(node.offsetWidth); - } - else { - widths.push(node.offsetWidth); - } - } - if (first) { - controls.unshift(node); - } - else { - controls.push(node); - } - } - widths = leftwidths.concat(widths); - var staylefts = []; - for (var i = 0; i < ui.control.childNodes.length; i++) { - if (ui.control.childNodes[i].classList.contains('removing')) continue; - if (lib.config.wuxie_right && ui.control.childNodes[i].stayleft) { - staylefts.push(ui.control.childNodes[i]); - } - else { - add(ui.control.childNodes[i]); - } - } - if (staylefts.length) { - var fullwidth = 0; - var fullright = (game.layout == 'long' || game.layout == 'long2' || game.chess || (game.layout != 'nova' && parseInt(ui.arena.dataset.number) <= 5)); - for (var i = 0; i < widths.length; i++) { - fullwidth += widths[i] + 6; - if (get.is.phoneLayout()) fullwidth += 6; - } - fullwidth /= 2; - var currentLeft = 0; - for (var stayleft of staylefts) { - stayleft.currentLeft = currentLeft; - fullwidth += stayleft.offsetWidth; - currentLeft += stayleft.offsetWidth; - if (get.is.phoneLayout()) { - fullwidth += 18; - currentLeft += 18; - } - else { - fullwidth += 12; - currentLeft += 12; - } - } - if (fullright) { - fullwidth += 124; - if ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.dataset.number == '8' && get.mode() != 'boss') { - fullwidth += game.me.getLeft(); - } - } - else { - fullwidth += 154; - } - for (var stayleft of staylefts) { - if (game.layout != 'default') { - var current_offset = stayleft._offset; - if (fullright) { - stayleft._offset = Math.ceil(-ui.arena.offsetWidth / 2) + 135; - if ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.dataset.number == '8' && get.mode() != 'boss') { - stayleft._offset += game.me.getLeft(); - } - } - else { - stayleft._offset = Math.ceil(-ui.arena.offsetWidth / 2) + 165; - } - stayleft._offset += stayleft.currentLeft; - - if (current_offset != stayleft._offset) { - stayleft.addTempClass('controlpressdownx', 500); - stayleft.style.transform = 'translateX(' + stayleft._offset + 'px)'; - } - } - else { - add(stayleft, true); - } - } - if (staylefts.length && controls.length) { - var last = staylefts[staylefts.length - 1]; - minoffset = last._offset + last.offsetWidth + (get.is.phoneLayout() ? 18 : 12); - } - } - if (!controls.length) return; - var offset = -length / 2; - if (minoffset > offset) offset = minoffset; - var control = controls.shift(); - if (control._offset != offset) { - control.addTempClass('controlpressdownx', 500); - control.style.transform = 'translateX(' + offset + 'px)'; - control._offset = offset; - } - while (controls.length) { - var control = controls.shift(); - var width = widths.shift(); - offset += width + 6; - if (get.is.phoneLayout()) { - offset += 6; - } - if (control._offset != offset) { - control.addTempClass('controlpressdownx', 500); - control.style.transform = 'translateX(' + offset + 'px)'; - control._offset = offset; - } - } - } - static updatex() { - ui.update.apply(this, arguments); - ui.updatehl(); - for (var i = 0; i < lib.onresize.length; i++) { - lib.onresize[i](); - } - var cfg = game.documentZoom / game.deviceZoom; - ui.updated(); - game.documentZoom = cfg * game.deviceZoom; - ui.updatez(); - delete ui._updatexr; - } - static updatexr() { - if (ui._updatexr) { - clearTimeout(ui._updatexr); - } - ui._updatexr = setTimeout(ui.updatex, 500); - } - static updatejm(player, nodes, start, inv) { - if (typeof start != 'number') { - start = 0; - } - var str; - if (get.is.mobileMe(player) || game.layout == 'default' || player.classList.contains('linked')) { - str = 'translateX('; - if (inv) { - str += '-'; - } - } - else { - str = 'translateY('; - } - var num = 0; - for (var i = 0; i < nodes.childElementCount; i++) { - var node = nodes.childNodes[i]; - if (i < start) { - node.style.transform = ''; - } - else if (node.classList.contains('removing')) { - start++; - } - else { - ui.refresh(node); - node.classList.remove('drawinghidden'); - node._transform = str + ((i - start) * 28) + 'px)'; - node.style.transform = node._transform; - } - } - } - static updatem(player) { - if (player) { - var start = 0; - if (!player.classList.contains('linked2') || !ui.arena.classList.contains('nolink')) { - start = 1; - } - ui.updatejm(player, player.node.marks, start, get.is.mobileMe(player)); - } - else { - for (var i = 0; i < game.players.length; i++) { - ui.updatem(game.players[i]); - } - } - } - static updatej(player) { - if (player) { - ui.updatejm(player, player.node.judges); - } - else { - for (var i = 0; i < game.players.length; i++) { - ui.updatej(game.players[i]); - } - } - } - static updatehl() { - if (!game.me) return; - if (!ui.handcards1Container || !ui.handcards2Container) return; - if (!ui.handcards1Container.childNodes.length) return; - var hs1 = [], hs2 = []; - for (var i = 0; i < ui.handcards1Container.firstChild.childElementCount; i++) { - if (!ui.handcards1Container.firstChild.childNodes[i].classList.contains('removing')) { - hs1.push(ui.handcards1Container.firstChild.childNodes[i]); - } - } - for (var i = 0; i < ui.handcards2Container.firstChild.childElementCount; i++) { - if (!ui.handcards2Container.firstChild.childNodes[i].classList.contains('removing')) { - hs2.push(ui.handcards2Container.firstChild.childNodes[i]); - } - } - var offset1, offset12 = 0; - if (!lib.config.fold_card) { - offset1 = 112; - ui.handcards1Container.classList.add('scrollh'); - } - else { - offset1 = Math.min(112, (ui.handcards1Container.offsetWidth - 128) / (hs1.length - 1)); - if (hs1.length > 1 && offset1 < 32) { - offset1 = 32; - ui.handcards1Container.classList.add('scrollh'); - } - else { - ui.handcards1Container.classList.remove('scrollh'); - } - } - if (offset1 < 100) { - offset12 = 100 - offset1; - } - for (var i = 0; i < hs1.length; i++) { - hs1[i].style.transform = 'translateX(' + (i * offset1) + 'px)'; - hs1[i]._transform = 'translateX(' + (i * offset1) + 'px)'; - ui.refresh(hs1[i]); - hs1[i].classList.remove('drawinghidden'); - if (offset12 > 40) { - offset12 = 90 - hs1[i].node.info.offsetWidth; - hs1[i].node.info.querySelector('span').style.display = 'none'; - if (hs1[i].node.name.classList.contains('long')) { - hs1[i].node.name.style.transform = 'translateY(16px) scale(0.85)'; - hs1[i].node.name.style.transformOrigin = 'top left'; - } - else { - hs1[i].node.name.style.transform = 'translateY(16px)'; - } - hs1[i].node.info.style.transform = 'translateX(-' + offset12 + 'px) translateY(-3px)'; - } - else { - hs1[i].node.info.querySelector('span').style.display = ''; - hs1[i].node.name.style.transform = ''; - hs1[i].node.name.style.transformOrigin = ''; - hs1[i].node.info.style.transform = 'translateX(-' + offset12 + 'px)'; - } - } - ui.handcards1Container.firstChild.style.width = (offset1 * (hs1.length - 1) + 118) + 'px'; - - var offset2, offset22 = 0; - if (!lib.config.fold_card) { - offset2 = 112; - ui.handcards2Container.classList.add('scrollh'); - } - else { - offset2 = Math.min(112, (ui.handcards2Container.offsetWidth - 128) / (hs2.length - 1)); - if (hs2.length > 1 && offset2 < 32) { - offset2 = 32; - ui.handcards2Container.classList.add('scrollh'); - } - else { - ui.handcards2Container.classList.remove('scrollh'); - } - } - if (offset2 < 100) { - offset22 = 100 - offset2; - } - for (var i = 0; i < hs2.length; i++) { - hs2[i].style.transform = 'translateX(' + (i * offset2) + 'px)'; - hs2[i]._transform = 'translateX(' + (i * offset2) + 'px)'; - ui.refresh(hs2[i]); - hs2[i].classList.remove('drawinghidden'); - if (offset22 > 40) { - offset22 = 90 - hs2[i].node.info.offsetWidth; - hs2[i].node.info.querySelector('span').style.display = 'none'; - if (hs2[i].node.name.classList.contains('long')) { - hs2[i].node.name.style.transform = 'translateY(16px) scale(0.85)'; - hs2[i].node.name.style.transformOrigin = 'top left'; - } - else { - hs2[i].node.name.style.transform = 'translateY(16px)'; - } - hs2[i].node.info.style.transform = 'translateX(-' + offset22 + 'px) translateY(-3px)'; - } - else { - hs2[i].node.info.querySelector('span').style.display = ''; - hs2[i].node.name.style.transform = ''; - hs2[i].node.name.style.transformOrigin = ''; - hs2[i].node.info.style.transform = 'translateX(-' + offset22 + 'px)'; - } - } - ui.handcards2Container.firstChild.style.width = (offset2 * (hs2.length - 1) + 118) + 'px'; - } - static updateh(compute) { - if (!game.me) return; - if (!ui.handcards1Container) return; - if (lib.config.low_performance) { - if (compute) { - ui.updatehl(); - setTimeout(ui.updatehl, 1000); - } - return; - } - if (compute) { - ui.handcards1Container._handcardsWidth = ui.handcards1Container.offsetWidth; - ui.handcards2Container._handcardsWidth = ui.handcards2Container.offsetWidth; - } - ui.updatehx(game.me.node.handcards1); - ui.updatehx(game.me.node.handcards2); - } - static updatehx(node) { - var width = node.parentNode._handcardsWidth; - var num = node.childElementCount - node.getElementsByClassName('removing').length; - node.classList.remove('fold0'); - node.classList.remove('fold1'); - node.classList.remove('fold2'); - node.classList.remove('fold3'); - if (num * 78 + 40 >= width) { - // node.dataset.fold=3; - node.classList.add('fold3'); - } - else if (num * 93 + 25 >= width) { - // node.dataset.fold=2; - node.classList.add('fold2'); - } - else if (num * 112 + 6 >= width) { - // node.dataset.fold=1; - node.classList.add('fold1'); - } - else { - // node.dataset.fold=0; - node.classList.add('fold0'); - } - } - static updated() { - if (document.documentElement.offsetWidth < 900 || document.documentElement.offsetHeight < 500) { - game.deviceZoom = Math.min( - Math.round(document.documentElement.offsetWidth / 98) / 10, - Math.round(document.documentElement.offsetHeight / 50) / 10 - ); - } - else { - game.deviceZoom = 1; - } - } - static updatez() { - var width = document.documentElement.offsetWidth; - var height = document.documentElement.offsetHeight; - var zoom = game.documentZoom; - if (zoom != 1) { - document.body.style.width = Math.round(width / zoom) + 'px'; - document.body.style.height = Math.round(height / zoom) + 'px'; - document.body.style.transform = 'scale(' + (Math.floor(zoom * 100) / 100) + ')'; - } - else { - document.body.style.width = width + 'px'; - document.body.style.height = height + 'px'; - document.body.style.transform = ''; - } - } - static update() { - for (var i = 0; i < ui.updates.length; i++) { - ui.updates[i](); - } - if (ui.dialog && !ui.dialog.classList.contains('noupdate')) { - if (game.chess) { - if (ui.dialog.content.scrollHeight < 240 && (!ui.dialog.buttons || !ui.dialog.buttons.length) && !ui.dialog.forcebutton) { - ui.dialog.style.height = ui.dialog.content.offsetHeight + 'px'; - ui.dialog.classList.add('slim'); - } - else { - ui.dialog.style.height = ''; - ui.dialog.classList.remove('slim'); - } - } - else { - if ((!ui.dialog.buttons || !ui.dialog.buttons.length) && !ui.dialog.forcebutton && ui.dialog.classList.contains('fullheight') == false && get.mode() != 'stone') { - ui.dialog.classList.add('nobutton'); - if (ui.dialog.content.offsetHeight < 240) { - if (!ui.dialog._heightset) { - ui.dialog._heightset = ui.dialog.style.height || true; - } - ui.dialog.style.height = ui.dialog.content.offsetHeight + 'px'; - if (lib.config.show_log != 'off') { - ui.dialog.classList.add('scroll1'); - ui.dialog.classList.add('scroll2'); - return; - } - } - else { - if (typeof ui.dialog._heightset == 'string') { - ui.dialog.style.height = ui.dialog._heightset; - } - else if (ui.dialog._heightset) { - ui.dialog.style.height = ''; - } - delete ui.dialog._heightset; - } - } - else { - if (typeof ui.dialog._heightset == 'string') { - ui.dialog.style.height = ui.dialog._heightset; - } - else if (ui.dialog._heightset) { - ui.dialog.style.height = ''; - } - delete ui.dialog._heightset; - ui.dialog.classList.remove('nobutton'); - } - } - var height1 = ui.dialog.content.offsetHeight; - var height2 = ui.dialog.contentContainer.offsetHeight; - if (game.chess) { - if (height1 < 240) { - ui.dialog.style.height = height1 + 'px'; - } - } - else { - if (!ui.dialog.forcebutton && !ui.dialog._scrollset && (height1 <= 190 || (height2 >= height1 && height2 >= 210))) { - ui.dialog.classList.remove('scroll1'); - ui.dialog.classList.remove('scroll2'); - } - else { - ui.dialog.classList.add('scroll1'); - ui.dialog.classList.add('scroll2'); - if (game.layout != 'default') { - ui.dialog.style.height = Math.min(height1, ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.classList.contains('choose-character')) ? 380 : 350) + 'px'; - ui.dialog._scrollset = true; - } - } - if (game.layout == 'long2' || game.layout == 'nova') { - if (height1 + 240 >= ui.arena.offsetHeight) { - ui.dialog.classList.add('scroll3'); - } - else { - ui.dialog.classList.remove('scroll3'); - } - } - } - } - } - static recycle(node, key) { - if (!ui._recycle) ui._recycle = {}; - if (typeof node == 'string') { - return ui._recycle[node] - } - ui._recycle[key] = node; - } - /** - * @author curpond - * @author Tipx-L - * @param {number} [numberOfPlayers] - */ - static updateConnectPlayerPositions(numberOfPlayers) { - if (typeof numberOfPlayers != 'number') { - const configOL = lib.configOL; - numberOfPlayers = parseInt(configOL.player_number) || configOL.number; - } - if (!numberOfPlayers) return; - const playerPositions = ui.playerPositions; - playerPositions.forEach((position) => { - game.dynamicStyle.remove(position); - }); - playerPositions.length = 0; - const temporaryPlayer = ui.create.div('.player.connect', ui.window).hide(); - const computedStyle = getComputedStyle(temporaryPlayer); - const halfWidth = parseFloat(computedStyle.width) / 2; - const halfHeight = parseFloat(computedStyle.height) / 2; - temporaryPlayer.remove(); - const halfNumberOfPlayers = Math.round(numberOfPlayers / 2); - const upperPercentage = 100 / (halfNumberOfPlayers + 1); - const scale = 10 / numberOfPlayers; - for (let ordinal = 0; ordinal < halfNumberOfPlayers; ordinal++) { - const selector = `#window>.player.connect[data-position='${ordinal}']`; - const css = { - left: `calc(${upperPercentage * (ordinal + 1)}% - ${halfWidth}px)`, - top: `calc(${100 / 3}% - ${halfHeight}px)` - }; - if (scale < 1) - css["transform"] = `scale(${scale})`; - - game.dynamicStyle.add(selector, css); - playerPositions.push(selector); - } - const lowerPercentage = 100 / (numberOfPlayers - halfNumberOfPlayers + 1); - for (let ordinal = halfNumberOfPlayers; ordinal < numberOfPlayers; ordinal++) { - const selector = `#window>.player.connect[data-position='${ordinal}']`; - const css = { - left: `calc(${lowerPercentage * (ordinal - halfNumberOfPlayers + 1)}% - ${halfWidth}px)`, - top: `calc(${100 * 2 / 3}% - ${halfHeight}px)` - }; - if (scale < 1) - css["transform"] = `scale(${scale})`; - - game.dynamicStyle.add(selector, css); - playerPositions.push(selector); - } - } - /** - * @author curpond - * @author Tipx-L - * @param {number} [numberOfPlayers] - */ - static updatePlayerPositions(numberOfPlayers) { - if (typeof numberOfPlayers != 'number') numberOfPlayers = ui.arena.dataset.number; - //当人数不超过8人时,还是用以前的布局 - if (!numberOfPlayers || numberOfPlayers <= 8) return; - const playerPositions = ui.playerPositions; - playerPositions.forEach((position) => { - game.dynamicStyle.remove(position); - }); - playerPositions.length = 0; - //单个人物的宽度,这里要设置玩家的实际的宽度 - const temporaryPlayer = ui.create.div('.player', ui.arena).hide(); - const computedStyle = getComputedStyle(temporaryPlayer); - const scale = 6 / numberOfPlayers; - //玩家顶部距离父容器上边缘的距离偏移的单位距离 - const quarterHeight = parseFloat(computedStyle.height) / 4 * scale; - const halfWidth = parseFloat(computedStyle.width) / 2; - temporaryPlayer.remove(); - //列数,即假如8人场,除去自己后,上面7个人占7列 - const columnCount = numberOfPlayers - 1; - const percentage = 90 / (columnCount - 1); - //仅当游戏人数大于8人,且玩家的座位号大于0时,设置玩家的位置;因为0号位是game.me在最下方,无需设置 - for (let ordinal = 1; ordinal < numberOfPlayers; ordinal++) { - const reversedOrdinal = columnCount - ordinal; - //动态计算玩家的top属性,实现拱桥的效果;只让两边的各两个人向下偏移一些 - const top = Math.max(0, Math.round(numberOfPlayers / 5) - Math.min(Math.abs(ordinal - 1), Math.abs(reversedOrdinal))) * quarterHeight; - const selector = `#arena[data-number='${numberOfPlayers}']>.player[data-position='${ordinal}']`; - game.dynamicStyle.add(selector, { - left: `calc(${percentage * reversedOrdinal + 5}% - ${halfWidth}px)`, - top: `${top}px`, - transform: `scale(${scale})` - }); - playerPositions.push(selector); - } - } - static updateRoundNumber(roundNumber, cardPileNumber) { - if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = `${roundNumber}轮 剩余牌: ${cardPileNumber}`; - } -}; - -export const ui = UI; +import { Uninstantable } from "../util/index.js"; +import { Library as lib } from '../library/index.js'; +import { Game as game } from "../game/index.js"; +import { Get as get } from "../get/index.js"; +import { _status } from "../status/index.js"; +import { GNC as gnc } from '../gnc/index.js'; +import { AI as ai } from "../ai/index.js"; + +class Create extends Uninstantable { + /** + * 创建身份牌实例 + */ + static identityCard(identity, position, noclick) { + const card = ui.create.card(position, 'noclick', noclick); + card.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.card); + card.classList.add('button'); + card._customintro = uiintro => uiintro.add(`${get.translation(`${identity}${2}`)}的身份牌`); + const fileName = `image/card/identity_${identity}.jpg`; + new Promise((resolve, reject) => { + const image = new Image(); + image.onload = resolve; + image.onerror = reject; + image.src = `${lib.assetURL}${fileName}`; + }).then(() => { + card.classList.add('fullskin'); + card.node.image.setBackgroundImage(fileName); + }, () => card.node.background.innerHTML = get.translation(identity)[0]); + return card; + } + /** + * 让卡牌旋转 + */ + static cardSpinning(card) { + if (lib.config.cardback_style != 'default') { + card.style.transitionProperty = 'none'; + ui.refresh(card); + card.classList.add('infohidden'); + ui.refresh(card); + card.style.transitionProperty = ''; + } + else { + card.classList.add('infohidden'); + } + card.style.transition = 'all 0s'; + card.style.transform = 'perspective(600px) rotateY(180deg) translateX(0)'; + const onEnd01 = function () { + setTimeout(function () { + card.style.transition = 'all ease-in 0.3s'; + card.style.transform = 'perspective(600px) rotateY(270deg) translateX(52px)'; + var onEnd = function () { + card.classList.remove('infohidden'); + card.style.transition = 'all 0s'; + ui.refresh(card); + card.style.transform = 'perspective(600px) rotateY(-90deg) translateX(52px)'; + ui.refresh(card); + card.style.transition = ''; + ui.refresh(card); + card.style.transform = ''; + }; + card.listenTransition(onEnd); + }, 300); + }; + onEnd01(); + } + /** + * 旋转的身份牌! + */ + static spinningIdentityCard(identity, dialog) { + const card = ui.create.identityCard(identity); + const buttons = ui.create.div('.buttons', dialog.content); + setTimeout(() => { + buttons.appendChild(card); + dialog.open(); + ui.create.cardSpinning(card); + }, 50); + } + /** + * 创建codemirror编辑器 + * @param {HTMLDivElement} container + * @param {Function} saveInput + */ + static editor(container, saveInput) { + const createList = []; + const containerDelete = container.delete; + const editorpage = ui.create.div(container); + //删除container的时候,删除创建的ul列表 + container.delete = function () { + for (let i = createList.length - 1; i >= 0; i--) { + createList[i].parentNode && createList[i].parentNode.removeChild(createList[i]); + } + Array.from(editorpage.children).forEach(v => { v.style.background = ''; }); + containerDelete.apply(this, arguments); + }; + //创建ul列表 + const createMenu = function (pos, self, List, click) { + if (!self || self == window) return; + const parent = self.parentNode; + if (parent) { + for (let i = 0; i < parent.childElementCount; i++) { + const node = parent.childNodes[i]; + if (node != self && node.ul) closeMenu.call(node); + } + } + if (self.ul) { + self.style.background = '#08f'; + createList.add(self.ul); + ui.window.appendChild(self.ul); + return self.ul; + } + const editor = container.editor; + if (!editor) return false; + self.style.background = '#08f'; + const ul = document.createElement('ul'); + container.css.call(ul, { + position: 'absolute', + top: pos.bottom / game.documentZoom + 'px', + left: pos.left / game.documentZoom + 'px', + height: '20em', + width: pos.width * 4 / game.documentZoom + 'px', + //'font-family':'shousha', + 'font-size': (lib.config.codeMirror_fontSize ? lib.config.codeMirror_fontSize.slice(0, -2) : 16) / game.documentZoom + 'px', + + }); + const theme = editor.options.theme; + lib.setScroll(ul); + lib.setMousewheel(ul); + ul.className = "CodeMirror-hints " + theme; + const getActive = () => { + let i = 0; + while (i < ul.childElementCount) { + if (ul.childNodes[i].classList.contains('CodeMirror-hint-active')) break; + else i++; + } + return i; + }; + const setActive = i => { + ul.childNodes[getActive()].classList.remove('CodeMirror-hint-active'); + ul.childNodes[i].classList.add('CodeMirror-hint-active'); + return i; + }; + if (List && List.length && click) { + for (let i = 0; i < List.length; ++i) { + const elt = ul.appendChild(document.createElement("li")); + elt.style.color = 'black'; + elt.style.boxShadow = 'none'; + const cur = List[i]; + if (cur instanceof HTMLElement) { + elt.appendChild(cur); + } else { + elt.innerHTML = cur; + } + let className = "CodeMirror-hint" + (i != 0 ? "" : " " + "CodeMirror-hint-active"); + if (cur.className != null) className = cur.className + " " + className; + elt.className = className; + elt.hintId = i; + ui.window.listen.call(elt, function () { + setActive(this.hintId); + this.focus(); + click.call(this); + }); + elt.onmousemove = elt.ontouchstart = () => { + setActive(i); + }; + } + } + createList.add(ul); + ui.window.appendChild(ul); + return ul; + }; + //关闭ul列表 + const closeMenu = function () { + const ul = this.ul; + if (!ul) return false; + if (ul.parentNode) ul.parentNode.removeChild(ul); + this.style.background = ''; + //创建后不用删除了,除非以后要动态加载。 + //delete this.ul; + createList.remove(ul); + return ul; + }; + const discardConfig = ui.create.div('.editbutton', '取消', editorpage, function () { + ui.window.classList.remove('shortcutpaused'); + ui.window.classList.remove('systempaused'); + container.delete(null); + delete window.saveNonameInput; + }); + const saveConfig = ui.create.div('.editbutton', '保存', editorpage, saveInput); + const theme = ui.create.div('.editbutton', '主题', editorpage, function () { + if (!this || this == window) return; + if (this.ul && this.ul.parentNode) { + return closeMenu.call(this); + } + //this + const self = this; + if (!this.ul) { + //主题列表 + const list = ['mdn-like', 'mbo']; + //正在使用的主题 + const active = container.editor.options.theme; + //排个序 + list.remove(active).splice(0, 0, active); + //元素位置 + const pos = self.getBoundingClientRect(); + //点击事件 + const click = function (e) { + const theme = this.innerHTML; + container.editor.setOption("theme", theme); + setTimeout(() => container.editor.refresh(), 0); + game.saveConfig('codeMirror_theme', theme); + closeMenu.call(self); + }; + const ul = createMenu(pos, self, list, click); + self.ul = ul; + } else { + createMenu(null, self); + } + }); + const edit = ui.create.div('.editbutton', '编辑', editorpage, function () { + if (!this || this == window) return; + if (this.ul && this.ul.parentNode) { + return closeMenu.call(this); + } + const self = this; + if (!this.ul) { + const pos = this.getBoundingClientRect(); + const list = ['撤销 Ctrl+Z', '恢复撤销 Ctrl+Y']; + const click = function (e) { + const num = this.innerHTML.indexOf("Ctrl"); + const inner = this.innerHTML.slice(num).replace("+", "-"); + container.editor.execCommand(container.editor.options.extraKeys[inner]); + setTimeout(() => container.editor.refresh(), 0); + closeMenu.call(self); + }; + const ul = createMenu(pos, self, list, click); + this.ul = ul; + } else { + createMenu(null, self); + } + }); + const fontSize = ui.create.div('.editbutton', '字号', editorpage, function () { + if (!this || this == window) return; + if (this.ul && this.ul.parentNode) { + return closeMenu.call(this); + } + const self = this; + if (!this.ul) { + const pos = this.getBoundingClientRect(); + const list = ['16px', '18px', '20px', '22px', '24px', '26px']; + const click = function (e) { + const size = this.innerHTML; + container.style.fontSize = size.slice(0, -2) / game.documentZoom + 'px'; + Array.from(self.parentElement.children).map(v => v.ul).filter(Boolean).forEach(v => { v.style.fontSize = size.slice(0, -2) / game.documentZoom + 'px'; }); + setTimeout(() => container.editor.refresh(), 0); + game.saveConfig('codeMirror_fontSize', size); + closeMenu.call(self); + }; + const ul = createMenu(pos, self, list, click); + this.ul = ul; + } else { + createMenu(null, self); + } + }); + const editor = ui.create.div(editorpage); + return editor; + } + static cardTempName(card, applyNode) { + let getApplyNode = applyNode || card; + let cardName = get.name(card); + let cardNature = get.nature(card); + let tempname = get.translation(cardName); + let cardTempNameConfig = lib.config.cardtempname; + let node = getApplyNode._tempName || ui.create.div('.tempname', getApplyNode); + let datasetNature = ''; + getApplyNode._tempName = node; + if (cardTempNameConfig != 'image') { + //清空,避免和下面的image部分有冲突 + node.innerHTML = ''; + datasetNature = 'fire'; + if (get.position(card) == 'j' && card.viewAs && card.viewAs != card.name) { + datasetNature = 'wood'; + tempname = get.translation(card.viewAs); + } else { + if (cardName == 'sha') { + if (cardNature) tempname = get.translation(cardNature) + tempname; + if (cardNature == 'thunder') datasetNature = 'thunder'; + if (cardNature == 'kami') datasetNature = 'kami'; + if (cardNature == 'ice') datasetNature = 'ice'; + } + } + if (cardTempNameConfig == 'default') getApplyNode._tempName.classList.add('vertical'); + if (datasetNature.length > 0) { + node.dataset.nature = datasetNature; + } else { + delete node.dataset.nature; + node.classList.add(datasetNature); + } + } else { + if (get.position(card) == 'j' && card.viewAs && card.viewAs != card.name) { + cardName = card.viewAs; + tempname = get.translation(card.viewAs); + } + if (cardName == 'sha') { + if (cardNature) tempname = get.translation(cardNature) + tempname; + if (cardNature == 'fire') datasetNature = 'fire'; + if (cardNature == 'thunder') datasetNature = 'thunder'; + if (cardNature == 'kami') datasetNature = 'kami'; + if (cardNature == 'ice') datasetNature = 'ice'; + } + let bg = node.querySelector('div'); + if (bg) { + Array.from(node.childNodes).filter(v => v != bg).forEach(v => node.removeChild(v)); + } + else bg = ui.create.div(node); + node.classList.add('tempimage'); + let img = lib.card[cardName].image; + if (img) { + if (img.startsWith('db:')) { + img = img.slice(3); + } + else if (!img.startsWith('ext:')) { + img = null; + } + } + if (lib.card[cardName].fullskin) { + if (img) { + if (img.startsWith('ext:')) { + bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); + } + else { + bg.setBackgroundDB(img); + } + } + else { + if (lib.card[cardName].modeimage) { + bg.setBackgroundImage('image/mode/' + lib.card[cardName].modeimage + '/card/' + cardName + '.png'); + } + else { + if (cardName == 'sha' && cardNature == 'stab') bg.setBackgroundImage('image/card/cisha.png'); + else bg.setBackgroundImage('image/card/' + cardName + '.png'); + } + } + } + else if (lib.card[cardName].image == 'background') { + if (cardNature) bg.setBackground(cardName + '_' + cardNature, 'card'); + else bg.setBackground(cardName, 'card'); + } + else if (lib.card[cardName].fullimage) { + if (img) { + if (img.startsWith('ext:')) { + bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); + bg.style.backgroundSize = 'cover'; + } + else { + bg.setBackgroundDB(img); + } + } + else if (lib.card[cardName].image) { + if (lib.card[cardName].image.startsWith('character:')) { + bg.setBackground(lib.card[cardName].image.slice(10), 'character'); + } + else { + bg.setBackground(lib.card[cardName].image); + } + } + else { + let cardPack = lib.cardPack['mode_' + get.mode()]; + if (Array.isArray(cardPack) && cardPack.includes(cardName)) { + bg.setBackground('mode/' + get.mode() + '/card/' + cardName); + } + else { + bg.setBackground('card/' + cardName); + } + } + } + else if (lib.card[cardName].image == 'card') { + if (cardNature) bg.setBackground(cardName + '_' + cardNature, 'card'); + else bg.setBackground(cardName, 'card'); + } + else if (typeof lib.card[cardName].image == 'string' && !lib.card[cardName].fullskin) { + if (img) { + if (img.startsWith('ext:')) { + bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); + bg.style.backgroundSize = 'cover'; + } + else { + bg.setBackgroundDB(img); + } + } + else { + bg.setBackground(lib.card[cardName].image); + } + } + else { + console.warn('卡牌图片解析失败'); + } + if (datasetNature.length > 0) { + node.classList.add(datasetNature); + } + delete node.dataset.nature; + } + node.innerHTML += `${cardTempNameConfig == 'default' ? get.verticalStr(tempname) : tempname}`; + node.tempname = tempname; + return node; + } + static connectRooms(list) { + ui.rooms = []; + ui.roombase = ui.create.dialog(); + ui.roombase.classList.add('fullwidth'); + ui.roombase.classList.add('fullheight'); + ui.roombase.classList.add('fixed'); + ui.roombase.classList.add('scroll1'); + ui.roombase.classList.add('scroll2'); + ui.roombase.classList.add('noupdate'); + for (var i = 0; i < list.length; i++) { + var player = ui.roombase.add(''); + player.roomindex = i; + player.initRoom = lib.element.Player.prototype.initRoom; + player.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.connectroom); + player.initRoom(list[i]); + ui.rooms.push(player); + } + } + static rarity(button) { + var rarity = game.getRarity(button.link); + if (rarity != 'common' && lib.config.show_rarity) { + var intro = button.node.intro; + intro.classList.add('showintro'); + intro.style.fontFamily = 'yuanli'; + intro.style.fontSize = '16px'; + intro.style.bottom = '6px'; + intro.style.left = '6px'; + switch (rarity) { + case 'rare': intro.dataset.nature = 'thunderm'; break; + case 'epic': intro.dataset.nature = 'metalm'; break; + case 'legend': intro.dataset.nature = 'orangem'; break; + case 'junk': intro.dataset.nature = 'woodm'; break; + } + intro.innerHTML = get.translation(rarity); + } + /*if((button.link=='xushu'||button.link=='xin_xushu'||button.link=='jsrg_guanyu')&&button.node&&button.node.name&&button.node.group){ + if(button.classList.contains('newstyle')){ + button.node.name.dataset.nature='watermm'; + button.node.group.dataset.nature='water'; + } + else button.node.group.style.backgroundColor=get.translation('weiColor'); + }*/ + } + static div() { + var str, innerHTML, position, position2, style, divposition, listen; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == 'string') { + if (typeof str == 'string') { + innerHTML = arguments[i]; + } + else { + str = arguments[i]; + } + } + else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; + else if (typeof arguments[i] == 'number') position2 = arguments[i]; + else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; + else if (typeof arguments[i] == 'object') style = arguments[i]; + else if (typeof arguments[i] == 'function') listen = arguments[i]; + } + if (str == undefined) str = ''; + var node = document.createElement('div'); + for (var i = 0; i < str.length; i++) { + if (str[i] == '.') { + if (node.className.length != 0) { + node.className += ' '; + } + while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + node.className += str[i + 1]; + i++; + } + } + else if (str[i] == '#') { + while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + node.id += str[i + 1]; + i++; + } + } + } + if (position) { + if (typeof position2 == 'number' && position.childNodes.length > position2) { + position.insertBefore(node, position.childNodes[position2]); + } + else { + position.appendChild(node); + } + } + if (style) node.css(style); + if (divposition) node.setPosition(divposition); + if (innerHTML) node.innerHTML = innerHTML; + if (listen) node.listen(listen); + return node; + } + static filediv() { + var args = Array.from(arguments); + var func = null; + for (var i = 0; i < args.length; i++) { + if (typeof args[i] == 'function') { + func = args[i]; + args.splice(i, 1); + break; + } + } + var div = ui.create.div.apply(this, args); + var input = ui.create.node('input.fileinput'); + input.type = 'file'; + input.onchange = function (e) { + func.call(this, this.files[0], e); + }; + div.appendChild(input); + div.inputNode = input; + return div; + } + static node() { + var tagName, str, innerHTML, position, position2, style, divposition, listen; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == 'string') { + if (typeof tagName == 'string') { + innerHTML = arguments[i]; + } + else { + tagName = arguments[i]; + } + } + else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; + else if (typeof arguments[i] == 'number') position2 = arguments[i]; + else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; + else if (typeof arguments[i] == 'object') style = arguments[i]; + else if (typeof arguments[i] == 'function') listen = arguments[i]; + } + if (tagName == undefined) { + tagName = 'div'; + } + else { + var i1 = tagName.indexOf('.'); + var i2 = tagName.indexOf('#'); + if (i1 != -1 || i2 != -1) { + if (i2 != -1 && i2 < i1) { + i1 = i2; + } + str = tagName.slice(i1); + tagName = tagName.slice(0, i1); + } + } + var node = document.createElement(tagName); + if (str) { + for (var i = 0; i < str.length; i++) { + if (str[i] == '.') { + if (node.className.length != 0) { + node.className += ' '; + } + while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + node.className += str[i + 1]; + i++; + } + } + else if (str[i] == '#') { + while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + node.id += str[i + 1]; + i++; + } + } + } + } + if (position) { + if (typeof position2 == 'number' && position.childNodes.length > position2) { + position.insertBefore(node, position.childNodes[position2]); + } + else { + position.appendChild(node); + } + } + if (style) HTMLDivElement.prototype.css.call(node, style); + if (divposition) HTMLDivElement.prototype.setPosition.call(node, divposition); + if (innerHTML) node.innerHTML = innerHTML; + if (listen) node.onclick = listen; + return node; + } + static iframe(src) { + var layer = document.createElement('div'); + layer.classList.add('poplayer'); + layer.style.zIndex = '100'; + layer.listen(function () { + this.remove(); + }); + layer.style.background = 'white'; + + var webview = document.createElement('iframe'); + webview.src = src; + webview.style.width = '100%'; + webview.style.height = '100%'; + webview.style.left = '0px'; + webview.style.top = '0px'; + webview.style.position = 'absolute'; + webview.style.border = 'none'; + layer.appendChild(webview); + + var backbutton = ui.create.div('.menubutton.round', '返', layer, function () { + layer.remove(); + }); + backbutton.style.bottom = '10px'; + backbutton.style.right = '10px'; + backbutton.style.background = 'rgba(0,0,0,0.4)'; + backbutton.style.color = 'white'; + backbutton.style.textShadow = 'rgba(0,0,0,0.5) 0px 0px 2px'; + backbutton.style.boxShadow = 'rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 3px 10px'; + backbutton.style.position = 'fixed'; + + ui.window.appendChild(layer); + } + static identitycircle(list, target) { + var container = ui.create.div('.identitycircle.menubg', target); + var circle = ui.create.div(container); + container.dataset.num = list.length; + for (var i = 0; i < list.length; i++) { + var sec1 = ui.create.div(circle); + sec1.dataset.color = list[i]; + var sec2 = ui.create.div(circle); + sec2.dataset.color = list[i]; + var deg1 = 360 / list.length * i; + var deg2 = 0; + if (list.length == 2) { + deg2 = 90; + } + else if (list.length == 3) { + deg2 = 30; + } + sec1.style.transform = 'rotate(' + deg1 + 'deg)'; + sec2.style.transform = 'rotate(' + (deg1 + deg2) + 'deg)'; + } + } + static chat() { + var chat = ui.create.system('聊天', null, true); + ui.chatButton = chat; + lib.setPopped(chat, ui.click.chat, 220); + } + static exit() { + if (!ui.exit) { + ui.exit = ui.create.control('退出房间', ui.click.exit); + } + } + static connecting(bool) { + if (bool) { + ui.window.classList.remove('connecting'); + if (ui.connecting) { + ui.connecting.delete(); + delete ui.connecting; + } + } + else { + ui.window.classList.add('connecting'); + ui.connecting = ui.create.div('.fullsize.connectlayer'); + document.body.appendChild(ui.connecting); + ui.create.div('', '正在重连...', ui.connecting); + ui.connecting.splashtimeout = setTimeout(function () { + if (ui.connecting) { + delete ui.connecting.splashtimeout; + } + }, 300); + // setTimeout(function(){ + // if(ui.connecting){ + // ui.connecting.firstChild.show(); + // } + // },1000); + } + } + static roomInfo() { + var chat = ui.create.system(game.online ? '房间信息' : '房间设置', function () { + if (!game.online || game.onlinezhu) { + ui.click.connectMenu(); + } + }, true); + ui.roomInfo = chat; + lib.setPopped(chat, function () { + if (game.getRoomInfo) { + var uiintro = ui.create.dialog('hidden'); + game.getRoomInfo(uiintro); + return uiintro; + } + }, 180); + } + static templayer(time) { + if (typeof time != 'number' || isNaN(time) || time == Infinity) { + time = 500; + } + var templayer = ui.create.div('.popup-container', ui.window); + setTimeout(function () { + templayer.remove(); + }, time); + } + static selectlist(list, init, position, onchange) { + var select = document.createElement('select'); + for (var i = 0; i < list.length; i++) { + var option = document.createElement('option'); + if (Array.isArray(list[i])) { + option.value = list[i][0]; + option.innerHTML = list[i][1]; + } + else { + option.value = list[i]; + option.innerHTML = list[i]; + } + if (init == option.value) { + option.selected = 'selected'; + } + select.appendChild(option); + } + if (position) { + position.appendChild(select); + } + if (onchange) { + select.onchange = onchange; + } + return select; + } + static menu(connectMenu) { + var menuTimeout = null; + if (!connectMenu && !game.syncMenu) { + menuTimeout = setTimeout(lib.init.reset, 1000); + } + var menu, menuContainer; + var startButton; + var popupContainer; + var closeMenu = function () { + if (popupContainer.noclose) { + popupContainer.noclose = false; + return; + } + popupContainer.classList.add('hidden'); + if (popupContainer.onclose) { + popupContainer.onclose(); + } + }; + popupContainer = ui.create.div('.popup-container.hidden', ui.window, closeMenu); + + var openMenu = function (node, e, onclose) { + popupContainer.innerHTML = ''; + var left = Math.round(e.clientX / game.documentZoom); + var zoom = get.is.phoneLayout() ? 1.3 : 1; + popupContainer.appendChild(node); + // var rect=node.getBoundingClientRect(); + if (node.classList.contains('visual')) { + // var num=node.querySelectorAll('.menu.visual>div').length; + // node.style.top=(e.y-node.offsetHeight/2+30)+'px'; + for (var i = 0; i < node.childElementCount; i++) { + if (node.childNodes[i].update) { + node.childNodes[i].update(); + } + } + // if(node.offsetTop<10){ + // node.style.top='10px'; + // } + } + // else if(get.is.phoneLayout()&&rect.top*1.3+rect.height*1.3+20>ui.window.offsetHeight){ + // node.style.top=(ui.winheightdow.offsetHeight-20-rect.height*1.3)/1.3+'px'; + // } + // if(e){ + var height = node.offsetHeight; + var idealtop = e.clientY / game.documentZoom; + if (idealtop < 10) { + idealtop = 10; + } + else if ((idealtop + height) * zoom + 10 > ui.window.offsetHeight) { + idealtop = (ui.window.offsetHeight - 10) / zoom - height; + } + node.style.top = idealtop + 'px'; + node.style.left = left + 'px'; + // } + + popupContainer.classList.remove('hidden'); + popupContainer.onclose = onclose; + }; + var clickToggle = function () { + if (this.classList.contains('disabled')) return; + this.classList.toggle('on'); + var config = this._link.config; + if (config.onclick) { + if (config.onclick.call(this, this.classList.contains('on')) === false) { + this.classList.toggle('on'); + } + } + if (config.update) { + config.update(); + } + }; + var clickSwitcher = function () { + if (this.classList.contains('disabled')) return; + var node = this; + this.classList.add('on'); + if (this._link.menu) { + var pos1 = this.lastChild.getBoundingClientRect(); + var pos2 = ui.window.getBoundingClientRect(); + if (this._link.menu.classList.contains('visual')) { + openMenu(this._link.menu, { + clientX: pos1.left + pos1.width + 5 - pos2.left, + clientY: pos1.top - pos2.top + }, function () { + node.classList.remove('on'); + }); + } + else if (this._link.menu.childElementCount > 10) { + openMenu(this._link.menu, { + clientX: pos1.left + pos1.width + 5 - pos2.left, + clientY: Math.min((ui.window.offsetHeight - 400) / 2, pos1.top - pos2.top) + }, function () { + node.classList.remove('on'); + }); + lib.setScroll(this._link.menu); + } + else { + openMenu(this._link.menu, { + clientX: pos1.left + pos1.width + 5 - pos2.left, + clientY: pos1.top - pos2.top + }, function () { + node.classList.remove('on'); + }); + } + } + }; + var clickContainer = function () { + menuContainer.classList.add('hidden'); + if (connectMenu) { + if (_status.enteringroom) { + _status.enteringroom = false; + } + if (_status.creatingroom) { + _status.creatingroom = false; + } + ui.window.classList.remove('shortcutpaused'); + } + else { + game.resume2(); + if (game.onresume2) { + game.onresume2(); + } + ui.arena.classList.remove('menupaused'); + ui.historybar.classList.remove('menupaused'); + ui.window.classList.remove('touchinfohidden'); + ui.config2.classList.remove('pressdown2'); + } + }; + var clickMenuItem = function () { + var node = this.parentNode._link; + var config = node._link.config; + node._link.current = this.link; + var tmpName = node.lastChild.innerHTML; + node.lastChild.innerHTML = config.item[this._link]; + if (config.onclick) { + if (config.onclick.call(node, this._link, this) === false) { + node.lastChild.innerHTML = tmpName; + } + } + if (config.update) { + config.update(); + } + }; + var createMenu = function (tabs, config) { + var createPage = function (position) { + var node = ui.create.div(position); + lib.setScroll(ui.create.div('.left.pane', node)); + lib.setScroll(ui.create.div('.right.pane', node)); + return node; + }; + var menu = ui.create.div('.main.menu.dialog.popped.static', config.position, function (e) { + e.stopPropagation(); + }); + if (connectMenu) { + menu.classList.add('center'); + menuContainer.classList.add('centermenu'); + } + var menuTab = ui.create.div('.menu-tab', menu); + var menuTabBar = ui.create.div('.menu-tab-bar', menu); + menuTabBar.style.left = (config.bar || 0) + 'px'; + if (Math.round(2 * game.documentZoom) < 2) { + menuTabBar.style.height = '3px'; + } + var menuContent = ui.create.div('.menu-content', menu); + var clickTab = function () { + if (this.classList.contains('disabled')) return; + var active = this.parentNode.querySelector('.active'); + if (active) { + active.classList.remove('active'); + active._link.remove(); + } + this.classList.add('active'); + menuTabBar.style.transform = 'translateX(' + (this.getBoundingClientRect().left - this.parentNode.firstChild.getBoundingClientRect().left) / game.documentZoom + 'px)'; + menuContent.appendChild(this._link); + }; + ui.click.menuTab = function (tab) { + for (var i = 0; i < menuTab.childNodes.length; i++) { + if (menuTab.childNodes[i].innerHTML == tab) { + clickTab.call(menuTab.childNodes[i]); + return; + } + } + }; + var pages = []; + for (var i = 0; i < tabs.length; i++) { + var active = (i === (config.init || 0)); + pages[i] = createPage(active ? menuContent : null); + ui.create.div(active ? '.active' : '', tabs[i], menuTab, clickTab)._link = pages[i]; + } + return { + menu: menu, + pages: pages + }; + }; + var createConfig = function (config, position) { + var node = ui.create.div('.config', config.name); + node._link = { config: config }; + if (!config.clear) { + if (config.name != '开启') { + if (config.name == '屏蔽弱将') { + config.intro = '强度过低的武将(孙策除外)不会出现在选将框,也不会被AI选择'; + } + else if (config.name == '屏蔽强将') { + config.intro = '强度过高的武将不会出现在选将框,也不会被AI选择'; + } + else if (!config.intro) { + config.intro = '设置' + config.name; + } + lib.setIntro(node, function (uiintro) { + if (lib.config.touchscreen) _status.dragged = true; + uiintro.style.width = '170px'; + var str = config.intro; + if (typeof str == 'function') { + str = str(); + } + uiintro._place_text = uiintro.add('
      ' + str + '
      '); + }); + } + } + else { + node.innerHTML = '' + config.name + ''; + if (!config.nopointer) { + node.classList.add('pointerspan'); + } + } + if (config.item) { + if (typeof config.item == 'function') { + config.item = config.item(); + } + if (Array.isArray(config.init)) { + void 0; + } + else { + node.classList.add('switcher'); + node.listen(clickSwitcher); + node._link.choosing = ui.create.div('', config.item[config.init], node); + node._link.menu = ui.create.div('.menu'); + if (config.visualMenu) { + node._link.menu.classList.add('visual'); + var updateVisual = function () { + config.visualMenu(this, this._link, config.item[this._link], config); + }; + var createNode = function (i, before) { + var visualMenu = ui.create.div(); + if (config.visualBar) { + if (before) { + node._link.menu.insertBefore(visualMenu, before); + } + else { + node._link.menu.insertBefore(visualMenu, node._link.menu.lastChild); + } + } + else { + node._link.menu.appendChild(visualMenu); + } + ui.create.div('.name', get.verticalStr(config.item[i]), visualMenu); + visualMenu._link = i; + if (config.visualMenu(visualMenu, i, config.item[i], config) !== false) { + visualMenu.listen(clickMenuItem); + } + visualMenu.update = updateVisual; + }; + if (config.visualBar) { + var visualBar = ui.create.div(node._link.menu, function () { + this.parentNode.parentNode.noclose = true; + }); + node._link.menu.classList.add('withbar'); + config.visualBar(visualBar, config.item, createNode, node); + visualBar.update = function () { + config.visualBar(visualBar, config.item, createNode, node); + }; + } + for (var i in config.item) { + createNode(i); + } + lib.setScroll(node._link.menu); + node._link.menu.updateBr = function () { + var br = Array.from(this.querySelectorAll('.menu.visual>br')); + while (br.length) { + br.shift().remove(); + } + var split = []; + for (var i = 1; i < this.childElementCount; i++) { + if (i % 3 == 0) { + split.push(this.childNodes[i]); + } + } + for (var i = 0; i < split.length; i++) { + this.insertBefore(ui.create.node('br'), split[i]); + } + }; + node._link.menu.updateBr(); + } + else { + for (var i in config.item) { + var textMenu = ui.create.div('', config.item[i], node._link.menu, clickMenuItem); + textMenu._link = i; + if (config.textMenu) { + config.textMenu(textMenu, i, config.item[i], config); + } + lib.setScroll(node._link.menu); + } + } + node._link.menu._link = node; + node._link.current = config.init; + } + } + else if (config.range) { + void 0; + } + else if (config.clear) { + if (node.innerHTML.length >= 15) node.style.height = 'auto'; + node.listen(clickToggle); + } + else if (config.input) { + node.classList.add('switcher'); + var input = ui.create.div(node); + if (!config.fixed) { + input.contentEditable = true; + input.style.webkitUserSelect = 'text'; + } + input.style.minWidth = '10px'; + input.style.maxWidth = '60%'; + input.style.overflow = 'hidden'; + input.style.whiteSpace = 'nowrap'; + input.onkeydown = function (e) { + if (e.keyCode == 13) { + e.preventDefault(); + e.stopPropagation(); + input.blur(); + } + }; + if (config.name == '联机昵称') { + input.innerHTML = config.init || '无名玩家'; + input.onblur = function () { + input.innerHTML = input.innerHTML.replace(/
      /g, ''); + if (!input.innerHTML || get.is.banWords(input.innerHTML)) { + input.innerHTML = '无名玩家'; + } + input.innerHTML = input.innerHTML.slice(0, 12); + game.saveConfig('connect_nickname', input.innerHTML); + game.saveConfig('connect_nickname', input.innerHTML, 'connect'); + }; + } + else if (config.name == '联机大厅') { + input.innerHTML = config.init || lib.hallURL; + input.onblur = function () { + if (!input.innerHTML) { + input.innerHTML = lib.hallURL; + } + input.innerHTML = input.innerHTML.replace(/
      /g, ''); + game.saveConfig('hall_ip', input.innerHTML, 'connect'); + }; + } + else { + input.innerHTML = config.init; + input.onblur = config.onblur; + } + } + else { + node.classList.add('toggle'); + node.listen(clickToggle); + ui.create.div(ui.create.div(node)); + if (config.init == true) { + node.classList.add('on'); + } + } + if (position) { + position.appendChild(node); + } + return node; + }; + var updateActive, updateActiveCard; + var menuUpdates = []; + menuContainer = ui.create.div('.menu-container.hidden', ui.window, clickContainer); + var menux; + if (!connectMenu) { + ui.menuContainer = menuContainer; + ui.click.configMenu = function () { + ui.click.shortcut(false); + if (menuContainer.classList.contains('hidden')) { + ui.config2.classList.add('pressdown2'); + ui.arena.classList.add('menupaused'); + ui.historybar.classList.add('menupaused'); + ui.window.classList.add('touchinfohidden'); + menuContainer.classList.remove('hidden'); + for (var i = 0; i < menuUpdates.length; i++) { + menuUpdates[i](); + } + } + else { + clickContainer.call(menuContainer); + } + }; + menux = createMenu(['开始', '选项', '武将', '卡牌', '扩展', '其它'], { + position: menuContainer, bar: 40 + }); + } + else { + ui.connectMenuContainer = menuContainer; + ui.click.connectMenu = function () { + if (menuContainer.classList.contains('hidden')) { + if (_status.waitingForPlayer) { + startButton.innerHTML = '设'; + var start = menux.pages[0].firstChild; + for (var i = 0; i < start.childNodes.length; i++) { + if (start.childNodes[i].mode != lib.configOL.mode) { + start.childNodes[i].classList.add('unselectable'); + start.childNodes[i].classList.remove('active'); + if (start.childNodes[i].link) start.childNodes[i].link.remove(); + } + else { + start.childNodes[i].classList.add('active'); + if (start.childNodes[i].link) start.nextSibling.appendChild(start.childNodes[i].link); + else console.log(start.nextSibling, start.childNodes[i]); + } + } + } + ui.window.classList.add('shortcutpaused'); + menuContainer.classList.remove('hidden'); + for (var i = 0; i < menuUpdates.length; i++) { + menuUpdates[i](); + } + } + else { + clickContainer.call(menuContainer); + } + }; + + menux = createMenu(['模式', '武将', '卡牌'], { + position: menuContainer, bar: 123 + }); + menu = menux.menu; + } + var menuxpages = menux.pages.slice(0); + + var copyObj = get.copy; + + (function () { + var start = menuxpages.shift(); + var rightPane = start.lastChild; + + startButton = ui.create.div('.menubutton.round.highlight', '启', start, function () { + if (this.animating || this.classList.contains('dim')) { + return; + } + var active = this.parentNode.querySelector('.active'); + if (active) { + if (connectMenu) { + if (_status.waitingForPlayer) { + var config = {}; + for (var i in lib.mode[lib.configOL.mode].connect) { + if (i == 'update') continue; + config[i.slice(8)] = get.config(i, lib.configOL.mode); + } + config.zhinang_tricks = lib.config.connect_zhinang_tricks; + if (game.online) { + if (game.onlinezhu) { + game.send('changeRoomConfig', config); + } + } + else { + game.broadcastAll(function (config) { + for (var i in config) { + lib.configOL[i] = config[i]; + } + }, config); + if (lib.configOL.mode == 'identity' && lib.configOL.identity_mode == 'zhong' && game.connectPlayers) { + for (var i = 0; i < game.connectPlayers.length; i++) { + game.connectPlayers[i].classList.remove('unselectable2'); + } + lib.configOL.number = 8; + game.updateWaiting(); + } + if (game.onlineroom) { + game.send('server', 'config', lib.configOL); + } + game.connectPlayers[0].chat('房间设置已更改'); + } + } + else if (_status.enteringroom || _status.creatingroom) { + lib.configOL.mode = active.mode; + if (_status.enteringroomserver) { + game.saveConfig('connect_mode', lib.configOL.mode); + + var config = {}; + for (var i in lib.mode[lib.configOL.mode].connect) { + if (i == 'update') continue; + config[i.slice(8)] = get.config(i, lib.configOL.mode); + } + config.zhinang_tricks = lib.config.connect_zhinang_tricks; + + config.characterPack = lib.connectCharacterPack.slice(0); + config.cardPack = lib.connectCardPack.slice(0); + for (var i = 0; i < lib.config.connect_characters.length; i++) { + config.characterPack.remove(lib.config.connect_characters[i]); + } + for (var i = 0; i < lib.config.connect_cards.length; i++) { + config.cardPack.remove(lib.config.connect_cards[i]); + } + config.banned = lib.config['connect_' + active.mode + '_banned']; + config.bannedcards = lib.config['connect_' + active.mode + '_bannedcards']; + game.send('server', 'create', game.onlineKey, get.connectNickname(), lib.config.connect_avatar, config, active.mode); + } + else { + game.send('server', 'create', game.onlineKey, get.connectNickname(), lib.config.connect_avatar); + } + } + else { + localStorage.setItem(lib.configprefix + 'directstart', true); + game.saveConfig('directstartmode', active.mode); + game.saveConfig('mode', 'connect'); + ui.exitroom = ui.create.system('退出房间', function () { + game.saveConfig('directstartmode'); + game.reload(); + }, true); + game.switchMode(active.mode); + } + clickContainer.call(menuContainer); + } + else { + game.saveConfig('mode', active.mode); + localStorage.setItem(lib.configprefix + 'directstart', true); + game.reload(); + } + } + }); + + var clickMode = function () { + if (this.classList.contains('unselectable')) return; + var active = this.parentNode.querySelector('.active'); + if (active === this) { + return; + } + active.classList.remove('active'); + active.link.remove(); + active = this; + this.classList.add('active'); + if (this.link) rightPane.appendChild(this.link); + else { + this._initLink(); + rightPane.appendChild(this.link); + } + if (connectMenu) { + if (updateActive) updateActive(); + if (updateActiveCard) updateActiveCard(); + } + }; + + var createModeConfig = function (mode, position) { + var info = lib.mode[mode]; + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', info.name, position, clickMode); + node.mode = mode; + var connectDisplayMap = { + connect_player_number: null, + connect_versus_mode: null, + }; + var updateConnectDisplayMap = function () { + if (_status.waitingForPlayer) { + if (connectDisplayMap.connect_player_number) { + connectDisplayMap.connect_player_number.style.display = 'none'; + } + if (connectDisplayMap.connect_versus_mode) { + connectDisplayMap.connect_versus_mode.style.display = 'none'; + } + } + }; + if (connectMenu) { + menuUpdates.push(updateConnectDisplayMap); + if (mode == lib.config.connect_mode) { + node.classList.add('active'); + } + } + else { + if (mode == lib.config.mode) { + node.classList.add('active'); + } + } + node._initLink = function () { + node.link = page; + //“更多”下的内容 + var map = {}; + var infoconfig = connectMenu ? info.connect : info.config; + if (infoconfig) { + var hiddenNodes = []; + var config = lib.config.mode_config[mode] || {}; + if (connectMenu) { + infoconfig.connect_choose_timeout = { + name: '出牌时限', + init: '30', + item: { + '10': '10秒', + '15': '15秒', + '30': '30秒', + '60': '60秒', + '90': '90秒', + }, + connect: true, + frequent: true + }; + infoconfig.connect_observe = { + name: '允许旁观', + init: true, + connect: true + }; + infoconfig.connect_observe_handcard = { + name: '允许观看手牌', + init: false, + connect: true + }; + infoconfig.connect_mount_combine = { + name: '合并坐骑栏', + init: false, + connect: true + }; + } + for (var j in infoconfig) { + if (j === 'update') { + continue; + } + var cfg = copyObj(infoconfig[j]); + cfg._name = j; + cfg.mode = mode; + if (j in config) { + cfg.init = config[j]; + } + else { + game.saveConfig(j, cfg.init, mode); + } + if (!cfg.onclick) { + cfg.onclick = function (result) { + var cfg = this._link.config; + game.saveConfig(cfg._name, result, mode); + if (cfg.onsave) { + cfg.onsave.call(this, result); + } + if (!_status.connectMode || game.online) { + if (typeof cfg.restart == 'function') { + if (cfg.restart()) { + startButton.classList.add('glowing'); + } + } + else if (cfg.restart) { + startButton.classList.add('glowing'); + } + } + }; + } + if (infoconfig.update) { + cfg.update = function () { + infoconfig.update(config, map); + }; + } + var cfgnode = createConfig(cfg); + map[j] = cfgnode; + if (cfg.frequent) { + page.appendChild(cfgnode); + } + else { + cfgnode.classList.add('auto-hide'); + hiddenNodes.push(cfgnode); + } + } + if (!connectMenu) { + var move = ui.create.div('.auto-hide.config', '
      上移↑
      下移↓
      '); + move.firstChild.listen(function () { + if (node.previousSibling) { + node.parentNode.insertBefore(node, node.previousSibling); + var order = []; + for (var i = 0; i < node.parentNode.childNodes.length; i++) { + order.push(node.parentNode.childNodes[i].mode); + } + game.saveConfig('modeorder', order); + } + }); + move.lastChild.listen(function () { + if (node.nextSibling) { + if (node.nextSibling.nextSibling) { + node.parentNode.insertBefore(node, node.nextSibling.nextSibling); + } + else { + node.parentNode.insertBefore(node.nextSibling, node); + } + var order = []; + for (var i = 0; i < node.parentNode.childNodes.length; i++) { + order.push(node.parentNode.childNodes[i].mode); + } + game.saveConfig('modeorder', order); + } + }); + hiddenNodes.push(move); + } + var expanded = false; + var hasexpand = true; + if (hiddenNodes.length) { + if (lib.config.fold_mode) { + var clickmore = function (type) { + if (type === 'expand' && expanded) return; + if (type === 'unexpand' && !expanded) return; + if (expanded) { + this.classList.remove('on'); + this.parentNode.classList.remove('expanded'); + } + else { + this.classList.add('on'); + this.parentNode.classList.add('expanded'); + } + expanded = !expanded; + }; + var morenodes = ui.create.div('.config.more', '更多
      >
      ', page); + morenodes.listen(clickmore); + morenodes._onclick = clickmore; + page.morenodes = morenodes; + } + else { + page.classList.add('expanded'); + if (!connectMenu) { + page.classList.add('expanded2'); + } + } + for (var k = 0; k < hiddenNodes.length; k++) { + page.appendChild(hiddenNodes[k]); + } + } + else { + hasexpand = false; + } + if (!connectMenu) { + var hidemode = ui.create.div('.config.pointerspan', '隐藏此模式', page, function () { + if (this.firstChild.innerHTML == '隐藏此模式') { + this.firstChild.innerHTML = '此模式将在重启后隐藏'; + lib.config.hiddenModePack.add(mode); + if (!lib.config.prompt_hidepack) { + alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); + game.saveConfig('prompt_hidepack', true); + } + } + else { + this.firstChild.innerHTML = '隐藏此模式'; + lib.config.hiddenModePack.remove(mode); + } + game.saveConfig('hiddenModePack', lib.config.hiddenModePack); + }); + if (hasexpand) { + hidemode.classList.add('auto-hide'); + } + } + if (infoconfig.update) { + infoconfig.update(config, map); + node.update = function () { + infoconfig.update(config, map); + }; + } + } + if (connectMenu) { + connectDisplayMap.connect_player_number = map.connect_player_number; + connectDisplayMap.connect_versus_mode = map.connect_versus_mode; + updateConnectDisplayMap(); + } + }; + if (!get.config('menu_loadondemand')) node._initLink(); + return node; + }; + var modeorder = lib.config.modeorder || []; + for (var i in lib.mode) { + modeorder.add(i); + } + for (var i = 0; i < modeorder.length; i++) { + if (connectMenu) { + if (!lib.mode[modeorder[i]].connect) continue; + if (!lib.config['connect_' + modeorder[i] + '_banned']) { + lib.config['connect_' + modeorder[i] + '_banned'] = []; + } + if (!lib.config['connect_' + modeorder[i] + '_bannedcards']) { + lib.config['connect_' + modeorder[i] + '_bannedcards'] = []; + } + } + if (lib.config.all.mode.includes(modeorder[i])) { + createModeConfig(modeorder[i], start.firstChild); + } + } + var active = start.firstChild.querySelector('.active'); + if (!active) { + active = start.firstChild.firstChild; + active.classList.add('active'); + } + if (!active.link) active._initLink(); + rightPane.appendChild(active.link); + if (lib.config.fold_mode) { + rightPane.addEventListener('mousewheel', function (e) { + var morenodes = this.firstChild.morenodes; + if (morenodes) { + if (e.wheelDelta < 0) { + morenodes._onclick.call(morenodes, 'expand'); + } + else if (this.scrollTop == 0) { + morenodes._onclick.call(morenodes, 'unexpand'); + } + } + }, { passive: true }); + } + }()); + + (function () { + if (connectMenu) return; + var start = menuxpages.shift(); + var rightPane = start.lastChild; + + var clickMode = function () { + var active = this.parentNode.querySelector('.active'); + if (active === this) { + return; + } + active.classList.remove('active'); + active.link.remove(); + active = this; + active.classList.add('active'); + if (this.link) rightPane.appendChild(this.link); + else { + this._initLink(); + rightPane.appendChild(this.link); + } + }; + + var clickAutoSkill = function (bool) { + var name = this._link.config._name; + var list = lib.config.autoskilllist; + if (bool) { + list.remove(name); + } + else { + list.add(name); + } + game.saveConfig('autoskilllist', list); + }; + var skilllistexpanded = game.expandSkills(lib.skilllist); + for (var i in lib.skill) { + if (!skilllistexpanded.includes(i)) continue; + if (lib.skill[i].frequent && lib.translate[i]) { + lib.configMenu.skill.config[i] = { + name: lib.translate[i + '_noconf'] || lib.translate[i], + init: true, + type: 'autoskill', + onclick: clickAutoSkill, + intro: lib.translate[i + '_info'] + }; + } + } + var clickBanSkill = function (bool) { + var name = this._link.config._name; + var list = lib.config.forbidlist; + if (bool) { + list.remove(name); + } + else { + list.add(name); + } + game.saveConfig('forbidlist', list); + }; + var forbid = lib.config.forbid; + if (!lib.config.forbidlist) { + game.saveConfig('forbidlist', []); + } + for (var i = 0; i < forbid.length; i++) { + var skip = false; + var str = ''; + var str2 = ''; + var str3 = ''; + for (var j = 0; j < forbid[i].length; j++) { + if (!lib.skilllist.includes(forbid[i][j])) { + skip = true; + break; + } + str += get.translation(forbid[i][j]) + '+'; + str2 += forbid[i][j] + '+'; + str3 += get.translation(forbid[i][j]) + ':' + lib.translate[forbid[i][j] + '_info']; + if (j < forbid[i].length - 1) { + str3 += '
      '; + } + } + if (skip) continue; + str = str.slice(0, str.length - 1); + str2 = str2.slice(0, str2.length - 1); + + lib.configMenu.skill.config[str2] = { + name: str, + init: true, + type: 'banskill', + onclick: clickBanSkill, + intro: str3 + }; + } + + var updateView = null; + var updateAppearence = null; + var createModeConfig = function (mode, position) { + var info = lib.configMenu[mode]; + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', info.name, position, clickMode); + node.mode = mode; + // node._initLink=function(){ + node.link = page; + var map = {}; + if (info.config) { + var hiddenNodes = []; + var autoskillNodes = []; + var banskillNodes = []; + var custombanskillNodes = []; + var banskill; + + if (mode == 'skill') { + var autoskillexpanded = false; + var banskillexpanded = false; + ui.create.div('.config.more', '自动发动
      >
      ', page, function () { + if (autoskillexpanded) { + this.classList.remove('on'); + for (var k = 0; k < autoskillNodes.length; k++) { + autoskillNodes[k].style.display = 'none'; + } + } + else { + this.classList.add('on'); + for (var k = 0; k < autoskillNodes.length; k++) { + autoskillNodes[k].style.display = ''; + } + } + autoskillexpanded = !autoskillexpanded; + }); + banskill = ui.create.div('.config.more', '双将禁配
      >
      ', page, function () { + if (banskillexpanded) { + this.classList.remove('on'); + for (var k = 0; k < banskillNodes.length; k++) { + banskillNodes[k].style.display = 'none'; + } + } + else { + this.classList.add('on'); + for (var k = 0; k < banskillNodes.length; k++) { + banskillNodes[k].style.display = ''; + } + } + banskillexpanded = !banskillexpanded; + }); + + var banskilladd = ui.create.div('.config.indent', '添加...', page, function () { + this.nextSibling.classList.toggle('hidden'); + }); + banskilladd.style.display = 'none'; + banskillNodes.push(banskilladd); + + var banskilladdNode = ui.create.div('.config.indent.hidden.banskilladd', page); + banskilladdNode.style.display = 'none'; + banskillNodes.push(banskilladdNode); + + var matchBanSkill = function (skills1, skills2) { + if (skills1.length != skills2.length) return false; + for (var i = 0; i < skills1.length; i++) { + if (!skills2.includes(skills1[i])) return false; + } + return true; + }; + var deleteCustomBanSkill = function () { + for (var i = 0; i < lib.config.customforbid.length; i++) { + if (matchBanSkill(lib.config.customforbid[i], this.parentNode.link)) { + lib.config.customforbid.splice(i--, 1); + break; + } + } + game.saveConfig('customforbid', lib.config.customforbid); + this.parentNode.remove(); + }; + var createCustomBanSkill = function (skills) { + var node = ui.create.div('.config.indent.toggle'); + node.style.display = 'none'; + node.link = skills; + banskillNodes.push(node); + custombanskillNodes.push(node); + var str = get.translation(skills[0]); + for (var i = 1; i < skills.length; i++) { + str += '+' + get.translation(skills[i]); + } + node.innerHTML = str; + var span = document.createElement('span'); + span.classList.add('cardpiledelete'); + span.innerHTML = '删除'; + span.onclick = deleteCustomBanSkill; + node.appendChild(span); + page.insertBefore(node, banskilladdNode.nextSibling); + return node; + }; + for (var i = 0; i < lib.config.customforbid.length; i++) { + createCustomBanSkill(lib.config.customforbid[i]); + } + (function () { + var list = []; + for (var i in lib.character) { + if (lib.character[i][3].length) + list.push([i, lib.translate[i]]); + } + + list.sort(function (a, b) { + a = a[0]; b = b[0]; + var aa = a, bb = b; + if (aa.includes('_')) { + aa = aa.slice(aa.indexOf('_') + 1); + } + if (bb.includes('_')) { + bb = bb.slice(bb.indexOf('_') + 1); + } + if (aa != bb) { + return aa > bb ? 1 : -1; + } + return a > b ? 1 : -1; + }); + + var list2 = []; + var skills = lib.character[list[0][0]][3]; + for (var i = 0; i < skills.length; i++) { + list2.push([skills[i], lib.translate[skills[i]]]); + } + + var selectname = ui.create.selectlist(list, list[0], banskilladdNode); + selectname.onchange = function () { + var skills = lib.character[this.value][3]; + skillopt.innerHTML = ''; + for (var i = 0; i < skills.length; i++) { + var option = document.createElement('option'); + option.value = skills[i]; + option.innerHTML = lib.translate[skills[i]]; + skillopt.appendChild(option); + } + }; + selectname.style.maxWidth = '85px'; + var skillopt = ui.create.selectlist(list2, list2[0], banskilladdNode); + + var span = document.createElement('span'); + span.innerHTML = '+'; + banskilladdNode.appendChild(span); + var br = document.createElement('br'); + banskilladdNode.appendChild(br); + + var selectname2 = ui.create.selectlist(list, list[0], banskilladdNode); + selectname2.onchange = function () { + var skills = lib.character[this.value][3]; + skillopt2.innerHTML = ''; + for (var i = 0; i < skills.length; i++) { + var option = document.createElement('option'); + option.value = skills[i]; + option.innerHTML = lib.translate[skills[i]]; + skillopt2.appendChild(option); + } + }; + selectname2.style.maxWidth = '85px'; + var skillopt2 = ui.create.selectlist(list2, list2[0], banskilladdNode); + var confirmbutton = document.createElement('button'); + confirmbutton.innerHTML = '确定'; + banskilladdNode.appendChild(confirmbutton); + + confirmbutton.onclick = function () { + var skills = [skillopt.value, skillopt2.value]; + if (skills[0] == skills[1]) { + skills.shift(); + } + if (!lib.config.customforbid) return; + for (var i = 0; i < lib.config.customforbid.length; i++) { + if (matchBanSkill(lib.config.customforbid[i], skills)) return; + } + lib.config.customforbid.push(skills); + game.saveConfig('customforbid', lib.config.customforbid); + createCustomBanSkill(skills).style.display = ''; + }; + }()); + page.style.paddingBottom = '10px'; + } + var config = lib.config; + if (mode == 'appearence') { + updateAppearence = function () { + info.config.update(config, map); + }; + } + else if (mode == 'view') { + updateView = function () { + info.config.update(config, map); + }; + } + for (var j in info.config) { + if (j === 'update') { + continue; + } + var cfg = copyObj(info.config[j]); + cfg._name = j; + if (j in config) { + cfg.init = config[j]; + } + else if (cfg.type != 'autoskill' && cfg.type != 'banskill') { + game.saveConfig(j, cfg.init); + } + if (!cfg.onclick) { + cfg.onclick = function (result) { + var cfg = this._link.config; + game.saveConfig(cfg._name, result); + if (cfg.onsave) { + cfg.onsave.call(this, result); + } + }; + } + if (info.config.update) { + if (mode == 'appearence' || mode == 'view') { + cfg.update = function () { + if (updateAppearence) { + updateAppearence(); + } + if (updateView) { + updateView(); + } + }; + } + else { + cfg.update = function () { + info.config.update(config, map); + }; + } + } + var cfgnode = createConfig(cfg); + if (cfg.type == 'autoskill') { + autoskillNodes.push(cfgnode); + // cfgnode.style.transition='all 0s'; + cfgnode.classList.add('indent'); + // cfgnode.hide(); + cfgnode.style.display = 'none'; + } + else if (cfg.type == 'banskill') { + banskillNodes.push(cfgnode); + // cfgnode.style.transition='all 0s'; + cfgnode.classList.add('indent'); + // cfgnode.hide(); + cfgnode.style.display = 'none'; + } + if (j == 'import_data_button') { + ui.import_data_button = cfgnode; + cfgnode.hide(); + cfgnode.querySelector('button').onclick = function () { + var fileToLoad = this.previousSibling.files[0]; + if (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (fileLoadedEvent) { + var data = fileLoadedEvent.target.result; + if (!data) return; + try { + data = JSON.parse(lib.init.decode(data)); + if (!data || typeof data != 'object') { + throw ('err'); + } + if (lib.db && (!data.config || !data.data)) { + throw ('err'); + } + } + catch (e) { + console.log(e); + alert('导入失败'); + return; + } + alert('导入成功'); + if (!lib.db) { + var noname_inited = localStorage.getItem('noname_inited'); + var onlineKey = localStorage.getItem(lib.configprefix + 'key'); + localStorage.clear(); + if (noname_inited) { + localStorage.setItem('noname_inited', noname_inited); + } + if (onlineKey) { + localStorage.setItem(lib.configprefix + 'key', onlineKey); + } + for (var i in data) { + localStorage.setItem(i, data[i]); + } + } + else { + for (var i in data.config) { + game.putDB('config', i, data.config[i]); + lib.config[i] = data.config[i]; + } + for (var i in data.data) { + game.putDB('data', i, data.data[i]); + } + } + lib.init.background(); + game.reload(); + }; + fileReader.readAsText(fileToLoad, "UTF-8"); + } + }; + } + else if (j == 'import_music') { + cfgnode.querySelector('button').onclick = function () { + if (_status.music_importing) return; + _status.music_importing = true; + var fileToLoad = this.previousSibling.files[0]; + if (fileToLoad) { + if (!lib.config.customBackgroundMusic) lib.config.customBackgroundMusic = {}; + var name = fileToLoad.name; + if (name.includes('.')) { + name = name.slice(0, name.indexOf('.')); + } + var link = (game.writeFile ? 'cdv_' : 'custom_') + name; + if (lib.config.customBackgroundMusic[link]) { + if (!confirm('已经存在文件名称相同的背景音乐,是否仍然要继续导入?')) { _status.music_importing = false; return; } + for (var i = 1; i < 1000; i++) { + if (!lib.config.customBackgroundMusic[link + '_' + i]) { + link = link + '_' + i; break; + } + } + } + var callback = function () { + var nodexx = ui.background_music_setting; + var nodeyy = nodexx._link.menu; + var nodezz = nodexx._link.config; + var musicname = link.slice(link.indexOf('_') + 1); + game.prompt('###请输入音乐的名称###' + musicname, true, function (str) { + if (str) musicname = str; + lib.config.customBackgroundMusic[link] = musicname; + lib.config.background_music = link; + lib.config.all.background_music.add(link); + game.saveConfig('background_music', link); + game.saveConfig('customBackgroundMusic', lib.config.customBackgroundMusic); + nodezz.item[link] = lib.config.customBackgroundMusic[link]; + var textMenu = ui.create.div('', lib.config.customBackgroundMusic[link], nodeyy, clickMenuItem, nodeyy.childElementCount - 2); + textMenu._link = link; + nodezz.updatex.call(nodexx, []); + _status.music_importing = false; + if (!_status._aozhan) game.playBackgroundMusic(); + }); + }; + if (game.writeFile) { + game.writeFile(fileToLoad, 'audio/background', link + '.mp3', callback); + } + else { + game.putDB('audio', link, fileToLoad, callback); + } + } + }; + } + else if (j == 'extension_source') { + ui.extension_source = cfgnode; + cfgnode.updateInner = function () { + this._link.choosing.innerHTML = lib.config.extension_source; + }; + } + map[j] = cfgnode; + if (!cfg.unfrequent) { + if (cfg.type == 'autoskill') { + page.insertBefore(cfgnode, banskill); + } + else { + page.appendChild(cfgnode); + } + } + else { + // cfgnode.classList.add('auto-hide'); + hiddenNodes.push(cfgnode); + } + } + var expanded = false; + if (hiddenNodes.length) { + // ui.create.div('.config.more','更多
      >
      ',page,function(){ + // if(expanded){ + // this.classList.remove('on'); + // this.parentNode.classList.remove('expanded'); + // } + // else{ + // this.classList.add('on'); + // this.parentNode.classList.add('expanded'); + // } + // expanded=!expanded; + // }); + page.classList.add('morenodes'); + for (var k = 0; k < hiddenNodes.length; k++) { + page.appendChild(hiddenNodes[k]); + } + } + if (info.config.update) { + info.config.update(config, map); + } + } + // }; + // if(!get.config('menu_loadondemand')) node._initLink(); + return node; + }; + + for (var i in lib.configMenu) { + if (i != 'others') createModeConfig(i, start.firstChild); + } + (function () { + if (!game.download && !lib.device) return; + var page = ui.create.div('#create-extension'); + var node = ui.create.div('.menubutton.large', '文件', start.firstChild, clickMode); + node.mode = 'create'; + node._initLink = function () { + node.link = page; + var pageboard = ui.create.div(page); + + var importextensionexpanded = false; + var importExtension; + var extensionnode = ui.create.div('.config.more', '导入素材包
      >
      ', pageboard, function () { + if (importextensionexpanded) { + this.classList.remove('on'); + importExtension.style.display = 'none'; + } + else { + this.classList.add('on'); + importExtension.style.display = ''; + } + importextensionexpanded = !importextensionexpanded; + }); + extensionnode.style.padding = '13px 33px 4px'; + extensionnode.style.left = '0px'; + importExtension = ui.create.div('.new_character.export.import', pageboard); + importExtension.style.padding = '0px 33px 10px'; + importExtension.style.display = 'none'; + importExtension.style.width = '100%'; + importExtension.style.textAlign = 'left'; + ui.create.div('', '', importExtension); + var promptnode = ui.create.div('', '
      ', importExtension); + promptnode.style.display = 'none'; + importExtension.firstChild.lastChild.onclick = function () { + if (promptnode.style.display != 'none') return; + var fileToLoad = this.previousSibling.files[0]; + if (fileToLoad) { + promptnode.style.display = ''; + promptnode.firstChild.innerHTML = '正在解压...'; + var fileReader = new FileReader(); + fileReader.onload = function (fileLoadedEvent) { + var data = fileLoadedEvent.target.result; + var loadData = function () { + var zip = new JSZip(); + zip.load(data); + var images = [], audios = [], fonts = [], directories = {}, directoryList = []; + Object.keys(zip.files).forEach(file => { + const parsedPath = lib.path.parse(file), directory = parsedPath.dir, fileExtension = parsedPath.ext.toLowerCase(); + if (directory.startsWith('audio') && (fileExtension == '.mp3' || fileExtension == '.ogg')) audios.push(file); + else if (directory.startsWith('font') && fileExtension == '.woff2') fonts.push(file); + else if (directory.startsWith('image') && (fileExtension == '.jpg' || fileExtension == '.png')) images.push(file); + else return; + if (!directories[directory]) { + directories[directory] = []; + directoryList.push(directory); + } + directories[directory].push(parsedPath.base); + }); + if (audios.length || fonts.length || images.length) { + var str = ''; + if (audios.length) { + str += audios.length + '个音频文件'; + } + if (fonts.length) { + if (str.length) str += '、'; + str += fonts.length + '个字体文件'; + } + if (images.length) { + if (str.length) str += '、'; + str += images.length + '个图片文件'; + } + var filelist = audios.concat(fonts).concat(images); + if (filelist.length > 200) { + str += ',导入时间可能较长'; + } + var assetLoaded = function () { + promptnode.firstChild.innerHTML = '导入成功。重新启动×'; + promptnode.firstChild.querySelectorAll('span')[0].onclick = game.reload; + promptnode.firstChild.querySelectorAll('span')[1].onclick = function () { + promptnode.style.display = 'none'; + }; + }; + if (confirm('本次将导入' + str + ',是否继续?')) { + promptnode.firstChild.innerHTML = '正在导入... 详细信息'; + promptnode.firstChild.querySelector('span.hrefnode').onclick = ui.click.consoleMenu; + if (lib.node && lib.node.fs) { + var writeFile = function () { + if (filelist.length) { + var str = filelist.shift(); + game.print(str.slice(str.lastIndexOf('/') + 1)); + lib.node.fs.writeFile(__dirname + '/' + str, zip.files[str].asNodeBuffer(), null, writeFile); + } + else { + assetLoaded(); + } + }; + game.ensureDirectory(directoryList, writeFile); + + } + else { + var getDirectory = function () { + if (directoryList.length) { + var dir = directoryList.shift(); + var filelist = directories[dir]; + window.resolveLocalFileSystemURL(lib.assetURL + dir, function (entry) { + var writeFile = function () { + if (filelist.length) { + var filename = filelist.shift(); + game.print(filename); + entry.getFile(filename, { create: true }, function (fileEntry) { + fileEntry.createWriter(function (fileWriter) { + fileWriter.onwriteend = writeFile; + fileWriter.onerror = function (e) { + game.print('Write failed: ' + e.toString()); + }; + fileWriter.write(zip.files[dir + '/' + filename].asArrayBuffer()); + }); + }); + } + else { + getDirectory(); + } + }; + writeFile(); + }); + } + else { + assetLoaded(); + } + }; + game.ensureDirectory(directoryList, getDirectory); + } + } + else { + promptnode.style.display = 'none'; + } + } + else { + alert('没有检测到素材'); + } + }; + if (!window.JSZip) { + lib.init.js(lib.assetURL + 'game', 'jszip', loadData); + } + else { + loadData(); + } + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + } + }; + + var dashboard = ui.create.div(pageboard); + var clickDash = function () { + ui.create.templayer(); + pageboard.hide(); + this.link.show(); + if (this.link.init) { + this.link.init(); + } + }; + var createDash = function (str1, str2, node) { + var dash = ui.create.div('.menubutton.large.dashboard'); + dashboard.appendChild(dash); + page.appendChild(node); + dash.link = node; + node.link = dash; + dash.listen(clickDash); + lib.setScroll(node); + ui.create.div('', str1, dash); + ui.create.div('', str2, dash); + }; + var createDash2 = function (str1, str2, path, page) { + var dash = ui.create.div('.menubutton.large.dashboard.dashboard2'); + page.appendChild(dash); + dash.listen(function () { + page.path = path; + enterDirectory(page, path); + }); + ui.create.div('', str1, dash); + ui.create.div('', str2, dash); + }; + var removeFile = function (selected, page) { + if (lib.node && lib.node.fs) { + var unlink = function () { + if (selected.length) { + lib.node.fs.unlink(__dirname + '/' + selected.shift().path, unlink); + } + else { + enterDirectory(page, page.currentpath); + } + }; + unlink(); + } + else { + window.resolveLocalFileSystemURL(lib.assetURL + page.currentpath, function (entry) { + var unlink = function () { + if (selected.length) { + entry.getFile(selected.shift().filename, { create: false }, function (fileEntry) { + fileEntry.remove(unlink); + }); + } + else { + enterDirectory(page, page.currentpath); + } + }; + unlink(); + }); + } + }; + var clickDirectory = function () { + if (_status.dragged) return; + var page = this.parentNode.parentNode.parentNode; + if (page.deletebutton.classList.contains('active')) { + if (confirm('确认删除' + this.innerHTML + '文件夹?(此操作不可撤销)')) { + if (lib.node && lib.node.fs) { + try { + var removeDirectory = function (path, callback) { + lib.node.fs.readdir(__dirname + '/' + path, function (err, list) { + if (err) { + console.log(err); + return; + } + var removeFile = function () { + if (list.length) { + var filename = list.shift(); + var url = __dirname + '/' + path + '/' + filename; + if (lib.node.fs.statSync(url).isDirectory()) { + removeDirectory(path + '/' + filename, removeFile); + } + else { + lib.node.fs.unlink(url, removeFile); + } + } + else { + lib.node.fs.rmdir(__dirname + '/' + path, callback); + } + }; + removeFile(); + }); + }; + removeDirectory(this.path, function () { + enterDirectory(page, page.currentpath); + }); + } + catch (e) { + console.log(e); + } + } + else { + window.resolveLocalFileSystemURL(lib.assetURL + this.path, function (entry) { + entry.removeRecursively(function () { + enterDirectory(page, page.currentpath); + }); + }); + } + } + return; + } + enterDirectory(page, this.path); + }; + var clickFile = function () { + if (_status.dragged) return; + var page = this.parentNode.parentNode.parentNode; + if (page.deletebutton.classList.contains('active')) { + if (confirm('确认删除' + this.innerHTML + '?(此操作不可撤销)')) { + removeFile([this], page); + } + return; + } + this.classList.toggle('thundertext'); + page.clicked = true; + if (this.ext == 'jpg' || this.ext == 'png') { + if (this.classList.contains('thundertext')) { + if (!this.previewnode) { + this.previewnode = document.createElement('img'); + this.previewnode.src = lib.assetURL + this.path; + this.previewnode.width = '60'; + this.previewnode.style.maxHeight = '120px'; + this.parentNode.appendChild(this.previewnode); + } + } + else { + if (this.previewnode) { + this.previewnode.remove(); + delete this.previewnode; + } + } + } + else if (this.ext == 'mp3' || this.ext == 'ogg') { + if (this.classList.contains('thundertext')) { + if (!this.previewnode) { + this.previewnode = game.playAudio(this.path.slice(6)); + } + } + else { + if (this.previewnode) { + this.previewnode.remove(); + delete this.previewnode; + } + } + } + }; + var clickFileList = function () { + if (!this.parentNode) return; + if (this.parentNode.clicked) { + this.parentNode.clicked = false; + } + else { + var selected = Array.from(this.querySelectorAll('span.thundertext')); + for (var i = 0; i < selected.length; i++) { + selected[i].classList.remove('thundertext'); + if (selected[i].previewnode) { + selected[i].previewnode.remove(); + delete selected[i].previewnode; + } + } + } + }; + var enterDirectory = function (page, path) { + page.innerHTML = ''; + page.currentpath = path; + var backbutton = ui.create.div('.menubutton.round', '返', page, function () { + page.clicked = false; + clickFileList.call(filelist); + if (page.path == path) { + page.reset(); + } + else { + if (path.indexOf('/') == -1) { + enterDirectory(page, ''); + } + else { + enterDirectory(page, path.slice(0, path.lastIndexOf('/'))); + } + } + }); + backbutton.style.zIndex = 1; + backbutton.style.right = '10px'; + backbutton.style.bottom = '15px'; + + + var refresh = function () { + enterDirectory(page, path); + }; + var addbutton = ui.create.div('.menubutton.round', '添', page, function () { + var pos1 = this.getBoundingClientRect(); + var pos2 = ui.window.getBoundingClientRect(); + openMenu(this.menu, { + clientX: pos1.left + pos1.width + 5 - pos2.left, + clientY: pos1.top - pos2.top + }); + }); + addbutton.menu = ui.create.div('.menu'); + ui.create.div('', '添加文件', addbutton.menu, function () { + popupContainer.noclose = true; + }); + var createDir = function (str) { + if (lib.node && lib.node.fs) { + lib.node.fs.mkdir(__dirname + '/' + path + '/' + str, refresh); + } + else { + window.resolveLocalFileSystemURL(lib.assetURL + path, function (entry) { + entry.getDirectory(str, { create: true }, refresh); + }); + } + }; + ui.create.div('', '添加目录', addbutton.menu, function () { + ui.create.templayer(); + game.prompt('输入目录名称', function (str) { + if (str) { + createDir(str); + } + }); + }); + var input = document.createElement('input'); + input.className = 'fileinput'; + input.type = 'file'; + input.onchange = function () { + var fileToLoad = input.files[0]; + game.print(fileToLoad.name); + if (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + game.writeFile(e.target.result, path, fileToLoad.name, refresh); + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + } + }; + addbutton.menu.firstChild.appendChild(input); + addbutton.style.zIndex = 1; + addbutton.style.right = '10px'; + addbutton.style.bottom = '80px'; + + var deletebutton = ui.create.div('.menubutton.round', '删', page, function () { + if (!this.parentNode) return; + if (!this.classList.contains('active')) { + var selected = Array.from(filelist.querySelectorAll('span.thundertext')); + if (selected.length) { + if (confirm('一共要删除' + selected.length + '个文件,此操作不可撤销,是否确定?')) { + removeFile(selected, page); + } + } + else { + this.classList.add('active'); + } + } + else { + this.classList.remove('active'); + } + }); + deletebutton.style.zIndex = 1; + deletebutton.style.right = '10px'; + deletebutton.style.bottom = '145px'; + + page.backbutton = backbutton; + page.addbutton = addbutton; + page.deletebutton = deletebutton; + var filelist = ui.create.div(page); + filelist.classList.add('file-container'); + filelist.listen(clickFileList); + lib.setScroll(filelist); + game.getFileList(path, function (folders, files) { + var sort = function (a, b) { + if (a > b) return 1; + if (a < b) return -1; + return 0; + }; + folders.sort(sort); + files.sort(sort); + var parent = path; + if (parent) { + parent += '/'; + } + for (var i = 0; i < folders.length; i++) { + if (!page.path && folders[i] == 'app') continue; + var entry = ui.create.div('', '' + folders[i], filelist); + entry.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickDirectory); + entry.firstChild.path = parent + folders[i]; + } + for (var i = 0; i < files.length; i++) { + if (!page.path) { + if (files[i] == 'app.html') continue; + if (files[i] == 'main.js') continue; + if (files[i] == 'package.json') continue; + } + var entry = ui.create.div('', '' + files[i], filelist); + entry.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickFile); + entry.firstChild.ext = files[i].slice(files[i].lastIndexOf('.') + 1); + entry.firstChild.path = parent + files[i]; + entry.firstChild.filename = files[i]; + } + }); + }; + var dash1 = (function () { + var page = ui.create.div('.hidden.menu-buttons'); + page.reset = function () { + page.innerHTML = ''; + var backbutton = ui.create.div('.menubutton.round', '返', page, function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + }); + backbutton.style.zIndex = 1; + backbutton.style.right = '10px'; + backbutton.style.bottom = '15px'; + var placeholder = ui.create.div('.placeholder', page); + placeholder.style.position = 'relative'; + placeholder.style.display = 'block'; + placeholder.style.width = '100%'; + placeholder.style.height = '14px'; + createDash2('将', '武将图片', 'image/character', page); + createDash2('肤', '皮肤图片', 'image/skin', page); + createDash2('卡', '卡牌图片', 'image/card', page); + createDash2('模', '模式图片', 'image/mode', page); + createDash2('始', '开始图片', 'image/splash', page); + createDash2('景', '背景图片', 'image/background', page); + }; + page.reset(); + return page; + }()); + var dash2 = (function () { + var page = ui.create.div('.hidden.menu-buttons'); + page.reset = function () { + page.innerHTML = ''; + var backbutton = ui.create.div('.menubutton.round', '返', page, function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + }); + backbutton.style.zIndex = 1; + backbutton.style.right = '10px'; + backbutton.style.bottom = '15px'; + var placeholder = ui.create.div('.placeholder', page); + placeholder.style.position = 'relative'; + placeholder.style.display = 'block'; + placeholder.style.width = '100%'; + placeholder.style.height = '14px'; + createDash2('技', '技能配音', 'audio/skill', page); + createDash2('卡', '男性卡牌', 'audio/card/male', page); + createDash2('牌', '女性卡牌', 'audio/card/female', page); + createDash2('亡', '阵亡配音', 'audio/die', page); + createDash2('效', '游戏音效', 'audio/effect', page); + createDash2('景', '背景音乐', 'audio/background', page); + }; + page.reset(); + return page; + }()); + var dash3 = (function () { + var page = ui.create.div('.hidden.menu-buttons'); + page.path = 'font'; + page.reset = function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + }; + page.init = function () { + enterDirectory(page, 'font'); + }; + return page; + }()); + var dash4 = (function () { + var page = ui.create.div('.hidden.menu-buttons'); + page.path = ''; + page.reset = function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + }; + page.init = function () { + enterDirectory(page, ''); + }; + return page; + }()); + createDash('图', '图片文件', dash1); + createDash('音', '音频文件', dash2); + createDash('字', '字体文件', dash3); + createDash('全', '全部文件', dash4); + }; + if (!get.config('menu_loadondemand')) node._initLink(); + }()); + createModeConfig('others', start.firstChild); + + var active = start.firstChild.querySelector('.active'); + if (!active) { + active = start.firstChild.firstChild; + active.classList.add('active'); + } + if (!active.link) active._initLink(); + rightPane.appendChild(active.link); + }()); + + (function () { + var start = menuxpages.shift(); + var rightPane = start.lastChild; + + var clickMode = function () { + var active = this.parentNode.querySelector('.active'); + if (active) { + if (active === this) { + return; + } + active.classList.remove('active'); + active.link.remove(); + } + this.classList.add('active'); + updateActive(this); + if (this.link) rightPane.appendChild(this.link); + else { + this._initLink(); + rightPane.appendChild(this.link); + } + }; + updateActive = function (node) { + if (!node) { + node = start.firstChild.querySelector('.active'); + if (!node) { + return; + } + } + if (!node.link) { + node._initLink(); + } + for (var i = 0; i < node.link.childElementCount; i++) { + if (node.link.childNodes[i].updateBanned) { + node.link.childNodes[i].updateBanned(); + } + } + }; + var updateNodes = function () { + for (var i = 0; i < start.firstChild.childNodes.length; i++) { + var node = start.firstChild.childNodes[i]; + if (node.mode) { + if (node.mode.startsWith('mode_')) continue; + if (node.mode == 'custom') continue; + if (connectMenu) { + if (!lib.config.connect_characters.includes(node.mode)) { + node.classList.remove('off'); + if (node.link) node.link.firstChild.classList.add('on'); + } + else { + node.classList.add('off'); + if (node.link) node.link.firstChild.classList.remove('on'); + } + } + else { + if (lib.config.characters.includes(node.mode)) { + node.classList.remove('off'); + if (node.link) node.link.firstChild.classList.add('on'); + } + else { + node.classList.add('off'); + if (node.link) node.link.firstChild.classList.remove('on'); + } + } + } + } + }; + var togglePack = function (bool) { + var name = this._link.config._name; + if (connectMenu) { + if (!bool) { + lib.config.connect_characters.add(name); + } + else { + lib.config.connect_characters.remove(name); + } + game.saveConfig('connect_characters', lib.config.connect_characters); + } + else { + if (bool) { + lib.config.characters.add(name); + } + else { + lib.config.characters.remove(name); + } + game.saveConfig('characters', lib.config.characters); + } + updateNodes(); + }; + + var createModeConfig = function (mode, position, position2) { + var _info = lib.characterPack[mode]; + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', lib.translate[mode + '_character_config'], position, clickMode); + if (node.innerHTML.length >= 5) { + node.classList.add('smallfont'); + } + if (position2) { + position.insertBefore(node, position2); + } + node.mode = mode; + node._initLink = function () { + node.link = page; + page.node = node; + var list = []; + var boolAI = true; + var alterableSkills = []; + var alterableCharacters = []; + var charactersToAlter = []; + for (var i in _info) { + if (_info[i][4] && _info[i][4].includes('unseen')) continue; + if (connectMenu && lib.connectBanned.includes(i)) continue; + list.push(i); + if (boolAI && !lib.config.forbidai_user.includes(i)) boolAI = false; + for (var j = 0; j < _info[i][3].length; j++) { + if (!lib.skill[_info[i][3][j]]) { + continue; + } + if (lib.skill[_info[i][3][j]].alter) { + alterableSkills.add(_info[i][3][j]); + alterableCharacters.add(i); + if (lib.config.vintageSkills.includes(_info[i][3][j])) { + charactersToAlter.add(i); + } + } + } + } + alterableCharacters.sort(); + list.sort(lib.sort.character); + var list2 = list.slice(0); + var cfgnode = createConfig({ + name: '开启', + _name: mode, + init: connectMenu ? (!lib.config.connect_characters.includes(mode)) : (lib.config.characters.includes(mode)), + onclick: togglePack + }); + var cfgnodeAI = createConfig({ + name: '仅点将可用', + _name: mode, + init: boolAI, + intro: '将该武将包内的武将全部设置为仅点将可用', + onclick(bool) { + if (bool) { + for (var i = 0; i < list.length; i++) { + lib.config.forbidai_user.add(list[i]); + } + } + else { + for (var i = 0; i < list.length; i++) { + lib.config.forbidai_user.remove(list[i]); + } + } + game.saveConfig('forbidai_user', lib.config.forbidai_user); + }, + }); + if (!mode.startsWith('mode_')) { + cfgnodeAI.style.marginTop = '0px'; + page.appendChild(cfgnode); + page.appendChild(cfgnodeAI); + if (alterableCharacters.length) { + var cfgnode2 = createConfig({ + name: '新版替换', + _name: mode, + init: charactersToAlter.length == 0, + intro: '以下武将将被修改:' + get.translation(alterableCharacters), + onclick(bool) { + if (bool) { + for (var i = 0; i < alterableSkills.length; i++) { + lib.config.vintageSkills.remove(alterableSkills[i]); + lib.translate[alterableSkills[i] + '_info'] = lib.translate[alterableSkills[i] + '_info_alter']; + } + } + else { + for (var i = 0; i < alterableSkills.length; i++) { + lib.config.vintageSkills.add(alterableSkills[i]); + lib.translate[alterableSkills[i] + '_info'] = lib.translate[alterableSkills[i] + '_info_origin']; + } + } + game.saveConfig('vintageSkills', lib.config.vintageSkills); + } + }); + cfgnode2.style.marginTop = '0px'; + page.appendChild(cfgnode2); + } + } + else if (mode.startsWith('mode_extension')) { + page.appendChild(cfgnodeAI); + } + else { + page.style.paddingTop = '8px'; + } + var banCharacter = function (e) { + if (_status.clicked) { + _status.clicked = false; + return; + } + if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && + mode != 'mode_favourite' && mode != 'mode_banned') { + if (!connectMenu && lib.config.show_charactercard) { + ui.click.charactercard(this.link, this, mode == 'mode_guozhan' ? 'guozhan' : true); + } + return; + } + ui.click.touchpop(); + this._banning = connectMenu ? 'online' : 'offline'; + if (!connectMenu && lib.config.show_charactercard) { + ui.click.charactercard(this.link, this); + } + else { + ui.click.intro.call(this, e); + } + _status.clicked = false; + delete this._banning; + }; + var updateBanned = function () { + var _list; + if (connectMenu) { + var mode = menux.pages[0].firstChild.querySelector('.active'); + if (mode && mode.mode) { + _list = lib.config['connect_' + mode.mode + '_banned']; + } + } + else { + _list = lib.config[get.mode() + '_banned']; + } + if (_list && _list.includes(this.link)) { + this.classList.add('banned'); + } + else { + this.classList.remove('banned'); + } + }; + if (lib.characterSort[mode]) { + var listb = []; + if (!connectMenu) { + listb = lib.config[get.mode() + '_banned'] || []; + } + else { + var modex = menux.pages[0].firstChild.querySelector('.active'); + if (modex && modex.mode) { + listb = lib.config['connect_' + modex.mode + '_banned']; + } + } + for (var pak in lib.characterSort[mode]) { + var info = lib.characterSort[mode][pak]; + var listx = []; + var boolx = false; + for (var ii = 0; ii < list2.length; ii++) { + if (info.includes(list2[ii])) { + listx.add(list2[ii]); + if (!listb.includes(list2[ii])) boolx = true; + list2.splice(ii--, 1); + } + } + if (listx.length) { + var cfgnodeY = { + name: lib.translate[pak], + _name: pak, + init: boolx, + onclick(bool) { + var banned = []; + if (connectMenu) { + var modex = menux.pages[0].firstChild.querySelector('.active'); + if (modex && modex.mode) { + banned = lib.config['connect_' + modex.mode + '_banned']; + } + } + else if (_status.connectMode) return; + else banned = lib.config[get.mode() + '_banned'] || []; + var listx = lib.characterSort[mode][this._link.config._name]; + if (bool) { + for (var i = 0; i < listx.length; i++) { + banned.remove(listx[i]); + } + } + else { + for (var i = 0; i < listx.length; i++) { + banned.add(listx[i]); + } + } + game.saveConfig(connectMenu ? ('connect_' + modex.mode + '_banned') : (get.mode() + '_banned'), banned); + updateActive(); + }, + }; + if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && !mode.startsWith('mode_guozhan')) { + cfgnodeY.clear = true; + delete cfgnodeY.onclick; + } + var cfgnodeX = createConfig(cfgnodeY); + page.appendChild(cfgnodeX); + var buttons = ui.create.buttons(listx, 'character', page); + for (var i = 0; i < buttons.length; i++) { + buttons[i].classList.add('noclick'); + buttons[i].listen(banCharacter); + ui.create.rarity(buttons[i]); + buttons[i].node.hp.style.transition = 'all 0s'; + buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; + if (mode != 'mode_banned') { + buttons[i].updateBanned = updateBanned; + } + } + } + } + if (list2.length) { + var cfgnodeX = createConfig({ + name: '其他', + _name: 'others', + clear: true, + }); + page.appendChild(cfgnodeX); + var buttons = ui.create.buttons(list2, 'character', page); + for (var i = 0; i < buttons.length; i++) { + buttons[i].classList.add('noclick'); + buttons[i].listen(banCharacter); + ui.create.rarity(buttons[i]); + buttons[i].node.hp.style.transition = 'all 0s'; + buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; + if (mode != 'mode_banned') { + buttons[i].updateBanned = updateBanned; + } + } + } + } + else { + var buttons = ui.create.buttons(list, 'character', page); + for (var i = 0; i < buttons.length; i++) { + buttons[i].classList.add('noclick'); + ui.create.rarity(buttons[i]); + buttons[i].listen(banCharacter); + buttons[i].node.hp.style.transition = 'all 0s'; + buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; + if (mode != 'mode_banned') { + buttons[i].updateBanned = updateBanned; + } + } + } + page.classList.add('menu-buttons'); + page.classList.add('leftbutton'); + if (!connectMenu) { + if (lib.config.all.sgscharacters.includes(mode)) { + ui.create.div('.config.pointerspan', '该武将包不可被隐藏', page); + } + else if (!mode.startsWith('mode_')) { + ui.create.div('.config.pointerspan', '隐藏武将包', page, function () { + if (this.firstChild.innerHTML == '隐藏武将包') { + if (confirm('真的要隐藏“' + get.translation(mode + '_character_config') + '”武将包吗?\n建议使用“关闭”而不是“隐藏”功能,否则将会影响其他相关武将包的正常运行!')) { + this.firstChild.innerHTML = '武将包将在重启后隐藏'; + lib.config.hiddenCharacterPack.add(mode); + if (!lib.config.prompt_hidepack) { + alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); + game.saveConfig('prompt_hidepack', true); + } + } + } + else { + this.firstChild.innerHTML = '隐藏武将包'; + lib.config.hiddenCharacterPack.remove(mode); + } + game.saveConfig('hiddenCharacterPack', lib.config.hiddenCharacterPack); + }); + } + } + }; + if (!get.config('menu_loadondemand')) node._initLink(); + return node; + }; + if (lib.config.show_favourite_menu && !connectMenu && Array.isArray(lib.config.favouriteCharacter)) { + lib.characterPack.mode_favourite = {}; + for (var i = 0; i < lib.config.favouriteCharacter.length; i++) { + var favname = lib.config.favouriteCharacter[i]; + if (lib.character[favname]) { + lib.characterPack.mode_favourite[favname] = lib.character[favname]; + } + } + var favouriteCharacterNode = createModeConfig('mode_favourite', start.firstChild); + if (!favouriteCharacterNode.link) favouriteCharacterNode._initLink(); + ui.favouriteCharacter = favouriteCharacterNode.link; + if (get.is.empty(lib.characterPack.mode_favourite)) { + ui.favouriteCharacter.node.style.display = 'none'; + } + delete lib.characterPack.mode_favourite; + } + if (!connectMenu && lib.config.show_ban_menu) { + lib.characterPack.mode_banned = {}; + for (var i = 0; i < lib.config.all.mode.length; i++) { + var banned = lib.config[lib.config.all.mode[i] + '_banned']; + if (banned) { + for (var j = 0; j < banned.length; j++) { + if (lib.character[banned[j]]) { + lib.characterPack.mode_banned[banned[j]] = lib.character[banned[j]]; + } + } + } + } + var bannednode = createModeConfig('mode_banned', start.firstChild); + if (get.is.empty(lib.characterPack.mode_banned)) { + bannednode.style.display = 'none'; + } + delete lib.characterPack.mode_banned; + } + var characterlist = connectMenu ? lib.connectCharacterPack : lib.config.all.characters; + for (var i = 0; i < characterlist.length; i++) { + createModeConfig(characterlist[i], start.firstChild); + } + if (!connectMenu) Object.keys(lib.characterPack).forEach(key => { + if (key.startsWith('mode_')) createModeConfig(key, start.firstChild); + }); + var active = start.firstChild.querySelector('.active'); + if (!active) { + active = start.firstChild.firstChild; + if (active.style.display == 'none') { + active = active.nextSibling; + if (active.style.display == 'none') { + active = active.nextSibling; + } + } + active.classList.add('active'); + updateActive(active); + } + if (!active.link) active._initLink(); + rightPane.appendChild(active.link); + + if (!connectMenu) { + var node1 = ui.create.div('.lefttext', '全部开启', start.firstChild, function () { + game.saveConfig('characters', lib.config.all.characters); + updateNodes(); + }); + var node2 = ui.create.div('.lefttext', '恢复默认', start.firstChild, function () { + game.saveConfig('characters', lib.config.defaultcharacters); + updateNodes(); + }); + node1.style.marginTop = '12px'; + node2.style.marginTop = '7px'; + } + + updateNodes(); + }()); + + (function () { + var start = menuxpages.shift(); + var rightPane = start.lastChild; + var pileCreated = false; + var recreatePile = function () { + lib.config.customcardpile['当前牌堆'] = [lib.config.bannedpile, lib.config.addedpile]; + game.saveConfig('customcardpile', lib.config.customcardpile); + game.saveConfig('cardpilename', '当前牌堆', true); + pileCreated = false; + }; + + var clickMode = function () { + var active = this.parentNode.querySelector('.active'); + if (active === this) { + return; + } + active.classList.remove('active'); + active.link.remove(); + active = this; + this.classList.add('active'); + updateActiveCard(this); + if (this.mode == 'cardpile') { + this.create(); + } + if (this.link) rightPane.appendChild(this.link); + else { + this._initLink(); + rightPane.appendChild(this.link); + } + }; + updateActiveCard = function (node) { + if (!node) { + node = start.firstChild.querySelector('.active'); + if (!node) { + return; + } + } + if (!node.link) node._initLink(); + for (var i = 0; i < node.link.childElementCount; i++) { + if (node.link.childNodes[i].updateBanned) { + node.link.childNodes[i].updateBanned(); + } + } + }; + var updateNodes = function () { + for (var i = 0; i < start.firstChild.childNodes.length; i++) { + var node = start.firstChild.childNodes[i]; + if (node.mode) { + if (node.mode.startsWith('mode_')) continue; + if (node.mode == 'custom') continue; + if (node.mode == 'cardpile') continue; + if (connectMenu) { + if (!lib.config.connect_cards.includes(node.mode)) { + node.classList.remove('off'); + if (node.link) node.link.firstChild.classList.add('on'); + } + else { + node.classList.add('off'); + if (node.link) node.link.firstChild.classList.remove('on'); + } + } + else { + if (lib.config.cards.includes(node.mode)) { + node.classList.remove('off'); + if (node.link) node.link.firstChild.classList.add('on'); + } + else { + node.classList.add('off'); + if (node.link) node.link.firstChild.classList.remove('on'); + } + } + } + } + }; + var togglePack = function (bool) { + var name = this._link.config._name; + if (connectMenu) { + if (!bool) { + lib.config.connect_cards.add(name); + } + else { + lib.config.connect_cards.remove(name); + } + game.saveConfig('connect_cards', lib.config.connect_cards); + } + else { + if (bool) { + lib.config.cards.add(name); + } + else { + lib.config.cards.remove(name); + } + game.saveConfig('cards', lib.config.cards); + } + updateNodes(); + }; + var toggleCardPile = function (bool) { + var name = this._link.config._name; + var number = this._link.config._number; + if (!lib.config.bannedpile[name]) { + lib.config.bannedpile[name] = []; + } + if (bool) { + lib.config.bannedpile[name].remove(number); + } + else { + lib.config.bannedpile[name].add(number); + } + recreatePile(); + }; + + var createModeConfig = function (mode, position) { + var info = lib.cardPack[mode]; + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', lib.translate[mode + '_card_config'], position, clickMode); + if (node.innerHTML.length >= 5) { + node.classList.add('smallfont'); + } + node.mode = mode; + node._initLink = function () { + node.link = page; + var list = []; + for (var i = 0; i < info.length; i++) { + if (!lib.card[info[i]] || (lib.card[info[i]].derivation && mode != 'mode_derivation')) continue; + list.push([get.translation(get.type(info[i], 'trick')), '', info[i]]); + } + var sortCard = function (card) { + var type = lib.card[card[2]].type; + var subtype = lib.card[card[2]].subtype; + if (lib.cardType[subtype]) { + return lib.cardType[subtype]; + } + if (lib.cardType[type]) { + return lib.cardType[type]; + } + switch (type) { + case 'basic': return 0; + case 'chess': return 1.5; + case 'trick': return 2; + case 'delay': return 3; + case 'equip': { + switch (lib.card[card[2]].subtype) { + case 'equip1': return 4.1; + case 'equip2': return 4.2; + case 'equip3': return 4.3; + case 'equip4': return 4.4; + case 'equip5': return 4.5; + default: return 4; + } + } + case 'zhenfa': return 5; + default: return 6; + } + }; + list.sort(function (a, b) { + var sort1 = sortCard(a); + var sort2 = sortCard(b); + if (sort1 == sort2) { + return (b[2] < a[2]) ? 1 : -1; + } + else if (sort1 > sort2) { + return 1; + } + else { + return -1; + } + }); + var cfgnode = createConfig({ + name: '开启', + _name: mode, + init: lib.config.cards.includes(mode), + onclick: togglePack + }); + if (!mode.startsWith('mode_')) { + page.appendChild(cfgnode); + } + else { + page.style.paddingTop = '8px'; + } + var banCard = function (e) { + if (_status.clicked) { + _status.clicked = false; + return; + } + if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && mode != 'mode_banned') { + return; + } + ui.click.touchpop(); + this._banning = connectMenu ? 'online' : 'offline'; + ui.click.intro.call(this, e); + _status.clicked = false; + delete this._banning; + }; + var updateBanned = function () { + var list; + if (connectMenu) { + var mode = menux.pages[0].firstChild.querySelector('.active'); + if (mode && mode.mode) { + list = lib.config['connect_' + mode.mode + '_bannedcards']; + } + } + else { + list = lib.config[get.mode() + '_bannedcards']; + } + if (list && list.includes(this.link[2])) { + this.classList.add('banned'); + } + else { + this.classList.remove('banned'); + } + }; + var buttons = ui.create.buttons(list, 'vcard', page); + for (var i = 0; i < buttons.length; i++) { + buttons[i].classList.add('noclick'); + buttons[i].listen(banCard); + if (mode != 'mode_banned') { + buttons[i].updateBanned = updateBanned; + } + } + page.classList.add('menu-buttons'); + page.classList.add('leftbutton'); + if (!connectMenu && !lib.config.all.sgscards.includes(mode) && !mode.startsWith('mode_')) { + ui.create.div('.config.pointerspan', '隐藏卡牌包', page, function () { + if (this.firstChild.innerHTML == '隐藏卡牌包') { + this.firstChild.innerHTML = '卡牌包将在重启后隐藏'; + lib.config.hiddenCardPack.add(mode); + if (!lib.config.prompt_hidepack) { + alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); + game.saveConfig('prompt_hidepack', true); + } + } + else { + this.firstChild.innerHTML = '隐藏卡牌包'; + lib.config.hiddenCardPack.remove(mode); + } + game.saveConfig('hiddenCardPack', lib.config.hiddenCardPack); + }); + } + if (!mode.startsWith('mode_') && lib.cardPile[mode]) { + var cardpileNodes = []; + var cardpileexpanded = false; + if (!lib.config.bannedpile[mode]) { + lib.config.bannedpile[mode] = []; + } + if (!lib.config.addedpile[mode]) { + lib.config.addedpile[mode] = []; + } + ui.create.div('.config.more.pile', '编辑牌堆
      >
      ', page, function () { + if (cardpileexpanded) { + this.classList.remove('on'); + for (var k = 0; k < cardpileNodes.length; k++) { + cardpileNodes[k].style.display = 'none'; + } + } + else { + this.classList.add('on'); + for (var k = 0; k < cardpileNodes.length; k++) { + cardpileNodes[k].style.display = ''; + } + } + cardpileexpanded = !cardpileexpanded; + }); + var cfgnode = ui.create.div(page, '.config.pointerspan.cardpilecfg.toggle'); + var cfgaddcard = ui.create.node('button', '', '添加卡牌', cfgnode, function () { + this.parentNode.nextSibling.classList.toggle('hidden'); + }); + var cfgbancard = ui.create.node('button', '', '全部关闭', cfgnode, function () { + for (var i = 0; i < cardpileNodes.length; i++) { + if (cardpileNodes[i].type == 'defaultcards' && cardpileNodes[i].classList.contains('on')) { + clickToggle.call(cardpileNodes[i]); + } + } + }); + var cfgenablecard = ui.create.node('button', '', '全部开启', cfgnode, function () { + for (var i = 0; i < cardpileNodes.length; i++) { + if (cardpileNodes[i].type == 'defaultcards' && !cardpileNodes[i].classList.contains('on')) { + clickToggle.call(cardpileNodes[i]); + } + } + }); + cfgbancard.style.marginLeft = '5px'; + cfgenablecard.style.marginLeft = '5px'; + cardpileNodes.push(cfgnode); + cfgnode.style.display = 'none'; + cfgnode.classList.add('cardpilecfg'); + cfgnode.classList.add('toggle'); + cfgnode.style.marginTop = '5px'; + page.appendChild(cfgnode); + + var cardpileadd = ui.create.div('.config.toggle.hidden.cardpilecfg.cardpilecfgadd', page); + var pileaddlist = []; + for (var i = 0; i < lib.config.cards.length; i++) { + if (!lib.cardPack[lib.config.cards[i]]) continue; + for (var j = 0; j < lib.cardPack[lib.config.cards[i]].length; j++) { + var cname = lib.cardPack[lib.config.cards[i]][j]; + pileaddlist.push([cname, get.translation(cname)]); + if (cname == 'sha') { + pileaddlist.push(['huosha', '火杀']); + pileaddlist.push(['leisha', '雷杀']); + pileaddlist.push(['icesha', '冰杀']); + pileaddlist.push(['cisha', '刺杀']); + } + } + } + var cardpileaddname = ui.create.selectlist(pileaddlist, null, cardpileadd); + cardpileaddname.style.width = '75px'; + cardpileaddname.style.marginRight = '2px'; + cardpileaddname.style.marginLeft = '-1px'; + var cardpileaddsuit = ui.create.selectlist([ + ['heart', '红桃'], + ['diamond', '方片'], + ['club', '梅花'], + ['spade', '黑桃'], + ], null, cardpileadd); + cardpileaddsuit.style.width = '53px'; + cardpileaddsuit.style.marginRight = '2px'; + var cardpileaddnumber = ui.create.selectlist([ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 + ], null, cardpileadd); + cardpileaddnumber.style.width = '43px'; + cardpileaddnumber.style.marginRight = '2px'; + var button = document.createElement('button'); + button.innerHTML = '确定'; + button.style.width = '40px'; + var deletecard = function () { + this.parentNode.remove(); + var info = this.parentNode._info; + var list = lib.config.addedpile[mode]; + for (var i = 0; i < list.length; i++) { + if (list[i][0] == info[0] && list[i][1] == info[1] && list[i][2] == info[2]) { + list.splice(i, 1); break; + } + } + recreatePile(); + }; + button.onclick = function () { + var card = [ + cardpileaddsuit.value, + cardpileaddnumber.value, + cardpileaddname.value, + ]; + lib.config.addedpile[mode].push(card); + recreatePile(); + var cfgnode = ui.create.div('.config.toggle.cardpilecfg'); + cfgnode._info = card; + cfgnode.innerHTML = get.translation(card[2]) + ' ' + get.translation(card[0]) + get.strNumber(card[1]); + var cfgnodedelete = document.createElement('span'); + cfgnodedelete.classList.add('cardpiledelete'); + cfgnodedelete.innerHTML = '删除'; + cfgnodedelete.onclick = deletecard; + cfgnode.appendChild(cfgnodedelete); + page.insertBefore(cfgnode, cardpileadd.nextSibling); + }; + cardpileadd.appendChild(button); + cardpileadd.style.whiteSpace = 'nowrap'; + cardpileNodes.push(cardpileadd); + + for (var i = 0; i < lib.config.addedpile[mode].length; i++) { + var card = lib.config.addedpile[mode][i]; + var cfgnode = ui.create.div('.config.toggle.cardpilecfg'); + cfgnode._info = card; + cfgnode.innerHTML = get.translation(card[2]) + ' ' + get.translation(card[0]) + card[1]; + var cfgnodedelete = document.createElement('span'); + cfgnodedelete.classList.add('cardpiledelete'); + cfgnodedelete.innerHTML = '删除'; + cfgnodedelete.onclick = deletecard; + cfgnode.appendChild(cfgnodedelete); + cfgnode.style.display = 'none'; + cardpileNodes.push(cfgnode); + page.appendChild(cfgnode); + } + + for (var i = 0; i < lib.cardPile[mode].length; i++) { + var card = lib.cardPile[mode][i]; + var cfgnode = createConfig({ + name: ((card[2] == 'sha' && card[3]) ? (get.translation(card[3])) : '') + get.translation(card[2]) + ' ' + get.translation(card[0]) + get.strNumber(card[1]), + _number: i, + _name: mode, + init: !lib.config.bannedpile[mode].includes(i), + onclick: toggleCardPile + }); + cfgnode.type = 'defaultcards'; + cardpileNodes.push(cfgnode); + cfgnode.style.display = 'none'; + cfgnode.classList.add('cardpilecfg'); + page.appendChild(cfgnode); + } + ui.create.div('.menuplaceholder', page); + } + }; + if (!get.config('menu_loadondemand')) node._initLink(); + return node; + }; + if (!connectMenu && lib.config.show_ban_menu) { + lib.cardPack.mode_banned = []; + for (var i = 0; i < lib.config.all.mode.length; i++) { + var banned = lib.config[lib.config.all.mode[i] + '_bannedcards']; + if (banned) { + for (var j = 0; j < banned.length; j++) { + lib.cardPack.mode_banned.add(banned[j]); + } + } + } + var bannednode = createModeConfig('mode_banned', start.firstChild); + if (lib.cardPack.mode_banned.length == 0) { + bannednode.style.display = 'none'; + } + delete lib.cardPack.mode_banned; + } + for (var i = 0; i < lib.config.all.cards.length; i++) { + if (connectMenu && !lib.connectCardPack.includes(lib.config.all.cards[i])) continue; + createModeConfig(lib.config.all.cards[i], start.firstChild); + } + if (!connectMenu) Object.keys(lib.cardPack).forEach(key => { + if (key.startsWith('mode_')) createModeConfig(key, start.firstChild); + }); + var active = start.firstChild.querySelector('.active'); + if (!active) { + active = start.firstChild.firstChild; + if (active.style.display == 'none') { + active = active.nextSibling; + } + active.classList.add('active'); + updateActiveCard(active); + } + if (!active.link) active._initLink(); + rightPane.appendChild(active.link); + + (function () { + if (connectMenu) return; + var page = ui.create.div('.menu-buttons'); + var node = ui.create.div('.menubutton.large', '牌堆', clickMode); + start.firstChild.insertBefore(node, start.firstChild.querySelector('.lefttext')); + node.link = page; + node.mode = 'cardpile'; + node.create = function () { + if (pileCreated) return; + pileCreated = true; + page.innerHTML = ''; + + var pileList = null; + var createList = function () { + if (pileList) { + pileList.remove(); + } + var list = ['默认牌堆']; + if (lib.config.customcardpile['当前牌堆']) { + list.push('当前牌堆'); + } + for (var i in lib.config.customcardpile) { + list.add(i); + } + var currentpile = get.config('cardpilename'); + if (!currentpile) { + if (list.includes('当前牌堆')) { + currentpile = '当前牌堆'; + } + else { + currentpile = '默认牌堆'; + } + } + pileList = ui.create.selectlist(list, currentpile, pileChoose, function (e) { + game.saveConfig('cardpilename', this.value, true); + restart.style.display = ''; + }); + pileList.style.float = 'right'; + }; + var pileChoose = ui.create.div('.config.toggle.cardpilecfg.nomarginleft', '选择牌堆', page); + createList(); + + var pileDel = function () { + delete lib.config.customcardpile[this.parentNode.link]; + this.parentNode.remove(); + game.saveConfig('customcardpile', lib.config.customcardpile); + for (var i in lib.config.mode_config) { + if (i == 'global') continue; + if (lib.config.mode_config[i].cardpilename == this.parentNode.link) { + game.saveConfig('cardpilename', null, i); + } + } + createList(); + }; + + var restart = ui.create.div('.config.more', '重新启动', game.reload, page); + restart.style.display = 'none'; + var createPileNode = function (name) { + var node = ui.create.div('.config.toggle.cardpilecfg.nomarginleft', name); + node.link = name; + var del = document.createElement('span'); + del.innerHTML = '删除'; + del.classList.add('cardpiledelete'); + del.onclick = pileDel; + node.appendChild(del); + if (name == '当前牌堆') { + page.insertBefore(node, pileChoose.nextSibling); + } + else { + page.insertBefore(node, restart); + } + }; + for (var i in lib.config.customcardpile) { + createPileNode(i); + } + var exportCardPile; + ui.create.div('.config.more', '保存当前牌堆
      >
      ', page, function () { + this.classList.toggle('on'); + if (this.classList.contains('on')) { + exportCardPile.classList.remove('hidden'); + } + else { + exportCardPile.classList.add('hidden'); + } + }); + exportCardPile = ui.create.div('.config.cardpileadd.indent', page); + exportCardPile.classList.add('hidden'); + ui.create.div('', '名称:', exportCardPile); + var input = exportCardPile.firstChild.lastChild.previousSibling; + input.value = '自定义牌堆'; + input.style.marginRight = '3px'; + input.style.width = '120px'; + exportCardPile.firstChild.lastChild.onclick = function () { + var name = input.value; + var ok = true; + if (lib.config.customcardpile[name] || name == '默认牌堆' || name == '当前牌堆') { + for (var i = 1; i <= 1000; i++) { + if (!lib.config.customcardpile[name + '(' + i + ')']) { + name = name + '(' + i + ')'; + break; + } + } + } + lib.config.customcardpile[name] = [lib.config.bannedpile, lib.config.addedpile]; + delete lib.config.customcardpile['当前牌堆']; + for (var i in lib.mode) { + if (lib.config.mode_config[i] && + (lib.config.mode_config[i].cardpilename == '当前牌堆' || !lib.config.mode_config[i].cardpilename)) { + game.saveConfig('cardpilename', name, i); + } + } + for (var i = 0; i < page.childElementCount; i++) { + if (page.childNodes[i].link == '当前牌堆') { + page.childNodes[i].remove(); + break; + } + } + game.saveConfig('customcardpile', lib.config.customcardpile); + createPileNode(name); + createList(); + }; + }; + }()); + + if (!connectMenu) { + var node1 = ui.create.div('.lefttext', '全部开启', start.firstChild, function () { + game.saveConfig('cards', lib.config.all.cards); + updateNodes(); + }); + var node2 = ui.create.div('.lefttext', '恢复默认', start.firstChild, function () { + game.saveConfig('cards', lib.config.defaultcards); + updateNodes(); + }); + node1.style.marginTop = '12px'; + node2.style.marginTop = '7px'; + } + + updateNodes(); + }()); + + (function () { + if (connectMenu) return; + var start = menuxpages.shift(); + var rightPane = start.lastChild; + + var clickMode = function () { + if (this.mode == 'get') { + this.update(); + } + var active = this.parentNode.querySelector('.active'); + if (active === this) { + return; + } + active.classList.remove('active'); + active.link.remove(); + active = this; + this.classList.add('active'); + if (this.link) rightPane.appendChild(this.link); + else { + this._initLink(); + rightPane.appendChild(this.link); + } + updateNodes(); + }; + ui.click.extensionTab = function (name) { + ui.click.menuTab('扩展'); + for (var i = 0; i < start.firstChild.childElementCount; i++) { + if (start.firstChild.childNodes[i].innerHTML == name) { + clickMode.call(start.firstChild.childNodes[i]); + break; + } + } + }; + var updateNodes = function () { + for (var i = 0; i < start.firstChild.childNodes.length; i++) { + var node = start.firstChild.childNodes[i]; + if (node.mode == 'get') continue; + if (node.mode == 'create') continue; + if (node.mode && node.mode.startsWith('extension_')) { + if (lib.config[node.mode + '_enable']) { + node.classList.remove('off'); + if (node.link) node.link.firstChild.classList.add('on'); + } + else { + node.classList.add('off'); + if (node.link) node.link.firstChild.classList.remove('on'); + } + } + else { + if (lib.config.plays.includes(node.mode)) { + node.classList.remove('off'); + if (node.link) node.link.firstChild.classList.add('on'); + } + else { + node.classList.add('off'); + if (node.link) node.link.firstChild.classList.remove('on'); + } + } + } + }; + var togglePack = function (bool) { + var name = this._link.config._name; + if (name.startsWith('extension_')) { + if (bool) { + game.saveConfig(name, true); + } + else { + game.saveConfig(name, false); + } + } + else { + name = name.slice(0, name.indexOf('_enable_playpackconfig')); + if (bool) { + lib.config.plays.add(name); + } + else { + lib.config.plays.remove(name); + } + game.saveConfig('plays', lib.config.plays); + } + if (this.onswitch) { + this.onswitch(bool); + } + updateNodes(); + }; + + var createModeConfig = function (mode, position) { + var page = ui.create.div(''); + page.style.paddingBottom = '10px'; + var node; + if (mode.startsWith('extension_')) { + node = ui.create.div('.menubutton.large', mode.slice(10), position, clickMode); + } + else { + node = ui.create.div('.menubutton.large', lib.translate[mode + '_play_config'], position, clickMode); + } + if (node.innerHTML.length >= 5) { + node.classList.add('smallfont'); + } + node.mode = mode; + // node._initLink=function(){ + node.link = page; + for (var i in lib.extensionMenu[mode]) { + if (i == 'game') continue; + var cfg = copyObj(lib.extensionMenu[mode][i]); + var j; + if (mode.startsWith('extension_')) { + j = mode + '_' + i; + } + else { + j = mode + '_' + i + '_playpackconfig'; + } + cfg._name = j; + if (j in lib.config) { + cfg.init = lib.config[j]; + } + else { + game.saveConfig(j, cfg.init); + } + + if (i == 'enable') { + cfg.onclick = togglePack; + } + else if (!lib.extensionMenu[mode][i].onclick) { + cfg.onclick = function (result) { + var cfg = this._link.config; + game.saveConfig(cfg._name, result); + }; + } + var cfgnode = createConfig(cfg); + if (cfg.onswitch) { + cfgnode.onswitch = cfg.onswitch; + } + page.appendChild(cfgnode); + } + // }; + // if(!get.config('menu_loadondemand')) node._initLink(); + return node; + }; + for (var i in lib.extensionMenu) { + if (lib.config.all.stockextension.includes(i) && !lib.config.all.plays.includes(i)) continue; + if (lib.config.hiddenPlayPack.includes(i)) continue; + createModeConfig(i, start.firstChild); + } + (function () { + if (!lib.device && !lib.db) return; + if (lib.config.show_extensionmaker == false) return; + var page = ui.create.div('#create-extension'); + var node = ui.create.div('.menubutton.large', '制作扩展', start.firstChild, clickMode); + node.mode = 'create'; + game.editExtension = function (name) { + node._initLink(); + game.editExtension(name); + }; + node._initLink = function () { + node.link = page; + var pageboard = ui.create.div(page); + var inputExtLine = ui.create.div(pageboard); + inputExtLine.style.transition = 'all 0s'; + inputExtLine.style.padding = '10px'; + inputExtLine.style.height = '22px'; + inputExtLine.style.lineHeight = '22px'; + inputExtLine.style.whiteSpace = 'nowrap'; + inputExtLine.style.overflow = 'visible'; + var inputExtSpan = document.createElement('span'); + inputExtSpan.innerHTML = '扩展名:'; + inputExtLine.appendChild(inputExtSpan); + var inputExtName = document.createElement('input'); + inputExtName.type = 'text'; + inputExtName.value = '无名扩展'; + inputExtName.style.width = '80px'; + inputExtName.style.textAlign = 'center'; + inputExtLine.appendChild(inputExtName); + + var buttonConfirmOnclick = function () { + buttonConfirm.style.display = 'none'; + inputExtSpan.style.display = 'none'; + inputExtName.style.display = 'none'; + authorExtLine.style.display = 'none'; + introExtLine.style.display = 'none'; + forumExtLine.style.display = 'none'; + diskExtLine.style.display = 'none'; + versionExtLine.style.display = 'none'; + okExtLine.style.display = 'none'; + inputExtLine.style.padding = '10px'; + buttonRename.style.display = ''; + buttonSave.style.display = ''; + buttonReset.style.display = ''; + buttonExport.style.display = ''; + inputExtSpan.innerHTML = '扩展名称:'; + inputExtName.style.width = '100px'; + inputExtName.style.textAlign = ''; + + dashboard.style.display = ''; + }; + var createExtLine = function (str, str2) { + var infoExtLine = ui.create.div(pageboard); + infoExtLine.style.display = 'none'; + infoExtLine.style.padding = '0 10px 10px 10px'; + infoExtLine.style.height = '22px'; + infoExtLine.style.lineHeight = '22px'; + infoExtLine.style.whiteSpace = 'nowrap'; + infoExtLine.style.overflow = 'visible'; + if (typeof str == 'boolean') { + var inputConfirm = document.createElement('button'); + inputConfirm.innerHTML = '确定'; + inputConfirm.onclick = buttonConfirmOnclick; + infoExtLine.appendChild(inputConfirm); + return infoExtLine; + } + var infoExtSpan = document.createElement('span'); + infoExtSpan.innerHTML = str + ':'; + infoExtLine.appendChild(infoExtSpan); + var infoExtName = document.createElement('input'); + infoExtName.type = 'text'; + infoExtName.style.width = '100px'; + infoExtName.value = str2 || ''; + infoExtLine.appendChild(infoExtName); + return infoExtLine; + }; + var authorExtLine = createExtLine('扩展作者', get.connectNickname()); + var introExtLine = createExtLine('扩展描述'); + var versionExtLine = createExtLine('扩展版本', '1.0'); + var diskExtLine = createExtLine('网盘地址'); + var forumExtLine = createExtLine('讨论地址'); + var okExtLine = createExtLine(true); + + game.editExtension = function (name) { + page.currentExtension = name || '无名扩展'; + inputExtName.value = page.currentExtension; + if (name && lib.extensionPack[name]) { + authorExtLine.querySelector('input').value = lib.extensionPack[name].author || ''; + introExtLine.querySelector('input').value = lib.extensionPack[name].intro || ''; + diskExtLine.querySelector('input').value = lib.extensionPack[name].diskURL || ''; + forumExtLine.querySelector('input').value = lib.extensionPack[name].forumURL || ''; + versionExtLine.querySelector('input').value = lib.extensionPack[name].version || ''; + } + else { + authorExtLine.querySelector('input').value = get.connectNickname() || ''; + introExtLine.querySelector('input').value = ''; + diskExtLine.querySelector('input').value = ''; + forumExtLine.querySelector('input').value = ''; + versionExtLine.querySelector('input').value = '1.0'; + } + if (name) { + inputExtName.disabled = true; + buttonConfirm.style.display = 'none'; + inputExtSpan.style.display = 'none'; + inputExtName.style.display = 'none'; + buttonRename.style.display = ''; + buttonSave.style.display = ''; + buttonReset.style.display = ''; + buttonExport.style.display = ''; + } + else { + inputExtName.disabled = false; + buttonConfirm.style.display = ''; + inputExtSpan.innerHTML = '扩展名:'; + inputExtName.style.width = '80px'; + inputExtName.style.textAlign = 'center'; + inputExtSpan.style.display = ''; + inputExtName.style.display = ''; + buttonRename.style.display = 'none'; + buttonSave.style.display = 'none'; + buttonReset.style.display = 'none'; + buttonExport.style.display = 'none'; + } + + dashboard.style.display = ''; + + exportExtLine.style.display = 'none'; + shareExtLine.style.display = 'none'; + authorExtLine.style.display = 'none'; + introExtLine.style.display = 'none'; + forumExtLine.style.display = 'none'; + diskExtLine.style.display = 'none'; + versionExtLine.style.display = 'none'; + okExtLine.style.display = 'none'; + inputExtLine.style.padding = '10px'; + dash1.reset(name); + dash2.reset(name); + dash3.reset(name); + dash4.reset(name); + dash1.link.classList.remove('active'); + dash2.link.classList.remove('active'); + dash3.link.classList.remove('active'); + dash4.link.classList.remove('active'); + var active = node.parentNode.querySelector('.active'); + if (active === node) { + return; + } + active.classList.remove('active'); + active.link.remove(); + node.classList.add('active'); + rightPane.appendChild(node.link); + }; + var processExtension = function (exportext) { + if (page.currentExtension) { + if (page.currentExtension != inputExtName.value && !exportext) { + game.removeExtension(page.currentExtension); + } + } + inputExtName.disabled = true; + setTimeout(function () { + var ext = {}; + var config = null, help = null; + for (var i in dash4.content) { + try { + if (i == 'content' || i == 'precontent') { + eval('ext[i]=' + dash4.content[i]); + if (typeof ext[i] != 'function') { + throw ('err'); + } + else { + ext[i] = ext[i].toString(); + } + } + else { + eval(dash4.content[i]); + eval('ext[i]=' + i); + if (ext[i] == null || typeof ext[i] != 'object') { + throw ('err'); + } + else { + ext[i] = JSON.stringify(ext[i]); + } + } + } + catch (e) { + console.log(e); + delete ext[i]; + } + } + page.currentExtension = inputExtName.value || '无名扩展'; + var str = '{name:"' + page.currentExtension + '"'; + for (var i in ext) { + str += ',' + i + ':' + ext[i]; + } + dash2.content.pack.list = []; + for (var i = 0; i < dash2.pile.childNodes.length; i++) { + dash2.content.pack.list.push(dash2.pile.childNodes[i].link); + } + str += ',package:' + get.stringify({ + //替换die audio,加上扩展名 + character: (pack => { + var character = pack.character; + for (var key in character) { + var info = character[key]; + if (Array.isArray(info[4])) { + var tag = info[4].find(tag => /^die:.+$/.test(tag)); + if (tag) { + info[4].remove(tag); + if (typeof game.readFile == 'function') { + info[4].push('die:ext:' + page.currentExtension + '/audio/die/' + tag.slice(tag.lastIndexOf('/') + 1)); + } else { + info[4].push('die:db:extension-' + page.currentExtension + ':audio/die/' + tag.slice(tag.lastIndexOf('/') + 1)); + } + } + } + } + return pack; + })(dash1.content.pack), + card: dash2.content.pack, + skill: dash3.content.pack, + intro: introExtLine.querySelector('input').value || '', + author: authorExtLine.querySelector('input').value || '', + diskURL: diskExtLine.querySelector('input').value || '', + forumURL: forumExtLine.querySelector('input').value || '', + version: versionExtLine.querySelector('input').value || '', + }); + var files = { character: [], card: [], skill: [], audio: [] }; + for (var i in dash1.content.image) { + files.character.push(i); + } + for (var i in dash1.content.audio) { + files.audio.push('audio/die/' + i); + } + for (var i in dash2.content.image) { + files.card.push(i); + } + for (var i in dash3.content.audio) { + files.skill.push(i); + } + str += ',files:' + JSON.stringify(files); + str += '}'; + var extension = { 'extension.js': 'game.import("extension",function(lib,game,ui,get,ai,_status){return ' + str + '})' }; + for (var i in dash1.content.image) { + extension[i] = dash1.content.image[i]; + } + for (var i in dash1.content.audio) { + extension['audio/die/' + i] = dash1.content.audio[i]; + } + for (var i in dash2.content.image) { + extension[i] = dash2.content.image[i]; + } + var callback = () => { + if (exportext) { + var proexport = function () { + game.importExtension(extension, null, page.currentExtension, { + intro: introExtLine.querySelector('input').value || '', + author: authorExtLine.querySelector('input').value || '', + netdisk: diskExtLine.querySelector('input').value || '', + forum: forumExtLine.querySelector('input').value || '', + version: versionExtLine.querySelector('input').value || '', + }); + }; + if (game.getFileList) { + game.getFileList('extension/' + page.currentExtension, function (folders, files) { + extension._filelist = files; + proexport(); + }); + } + else { + proexport(); + } + } + else { + game.importExtension(extension, function () { + exportExtLine.style.display = ''; + }); + } + }; + //兼容网页版情况 + if (typeof game.readFile == "function") { + game.readFile('LICENSE', function (data) { + extension['LICENSE'] = data; + game.writeFile(data, 'extension/' + page.currentExtension, 'LICENSE', function () { }); + callback(); + }, function () { + alert('许可证文件丢失,无法导出扩展'); + }); + } else { + callback(); + } + }, 500); + }; + var buttonConfirm = document.createElement('button'); + buttonConfirm.innerHTML = '确定'; + buttonConfirm.style.marginLeft = '5px'; + buttonConfirm.onclick = buttonConfirmOnclick; + inputExtLine.appendChild(buttonConfirm); + var buttonRename = document.createElement('button'); + buttonRename.innerHTML = '选项'; + buttonRename.style.marginLeft = '2px'; + buttonRename.style.marginRight = '2px'; + buttonRename.style.display = 'none'; + buttonRename.onclick = function () { + inputExtSpan.style.display = ''; + inputExtName.style.display = ''; + authorExtLine.style.display = ''; + introExtLine.style.display = ''; + forumExtLine.style.display = ''; + diskExtLine.style.display = ''; + versionExtLine.style.display = ''; + okExtLine.style.display = 'block'; + inputExtLine.style.padding = '20px 10px 10px 10px'; + inputExtName.disabled = false; + buttonRename.style.display = 'none'; + buttonSave.style.display = 'none'; + buttonReset.style.display = 'none'; + buttonExport.style.display = 'none'; + inputExtSpan.innerHTML = '扩展名称:'; + inputExtName.style.width = '100px'; + inputExtName.style.textAlign = ''; + + dashboard.style.display = 'none'; + }; + inputExtLine.appendChild(buttonRename); + var buttonReset = document.createElement('button'); + buttonReset.innerHTML = '重置'; + buttonReset.style.marginLeft = '2px'; + buttonReset.style.marginRight = '2px'; + buttonReset.style.display = 'none'; + buttonReset.onclick = function () { + if (confirm('当前扩展将被清除,是否确定?')) { + game.editExtension(); + } + }; + inputExtLine.appendChild(buttonReset); + var buttonSave = document.createElement('button'); + buttonSave.innerHTML = '保存'; + buttonSave.style.marginLeft = '2px'; + buttonSave.style.marginRight = '2px'; + buttonSave.style.display = 'none'; + buttonSave.onclick = function () { + dash1.link.classList.remove('active'); + dash2.link.classList.remove('active'); + dash3.link.classList.remove('active'); + dash4.link.classList.remove('active'); + processExtension(); + }; + inputExtLine.appendChild(buttonSave); + var buttonExport = document.createElement('button'); + buttonExport.innerHTML = '导出'; + buttonExport.style.marginLeft = '2px'; + buttonExport.style.marginRight = '2px'; + buttonExport.style.display = 'none'; + buttonExport.onclick = function () { + function oldExport() { + processExtension(true); + if (lib.config.show_extensionshare) { + shareExtLine.style.display = ''; + } + } + if (typeof game.readFile == 'function' && + window.noname_shijianInterfaces && + typeof window.noname_shijianInterfaces.shareExtensionWithPassWordAsync == 'function' && + confirm('是否使用诗笺版自带的导出功能来导出扩展?')) { + const extName = inputExtName.value; + if (!extName) { + alert('未检测到扩展名,将使用无名杀自带的导出功能'); + oldExport(); + return; + } + game.readFile(`extension/${extName}/extension.js`, () => { + const pwd = prompt("请输入压缩包密码,不设密码直接点确定"); + let result; + if (pwd === '' || pwd === null) { + window.noname_shijianInterfaces.shareExtensionAsync(extName); + } else { + window.noname_shijianInterfaces.shareExtensionWithPassWordAsync(extName, pwd); + } + }, () => { + alert('未检测到扩展文件,将使用无名杀自带的导出功能'); + oldExport(); + }); + } else { + oldExport(); + } + }; + inputExtLine.appendChild(buttonExport); + var exportExtLine = ui.create.div(pageboard); + exportExtLine.style.display = 'none'; + exportExtLine.style.width = 'calc(100% - 40px)'; + exportExtLine.style.textAlign = 'left'; + exportExtLine.style.marginBottom = '5px'; + if (lib.device == 'ios') { + exportExtLine.innerHTML = '已保存。退出游戏并重新打开后生效×'; + exportExtLine.querySelectorAll('span')[0].onclick = function () { + exportExtLine.style.display = 'none'; + }; + } + else { + exportExtLine.innerHTML = '重启后生效。立即重启×'; + exportExtLine.querySelectorAll('span')[0].onclick = game.reload; + exportExtLine.querySelectorAll('span')[1].onclick = function () { + exportExtLine.style.display = 'none'; + }; + } + + + var shareExtLine = ui.create.div(pageboard); + shareExtLine.style.display = 'none'; + shareExtLine.style.width = 'calc(100% - 40px)'; + shareExtLine.style.textAlign = 'left'; + shareExtLine.style.marginBottom = '5px'; + shareExtLine.innerHTML = '已导出扩展。分享扩展×'; + shareExtLine.querySelectorAll('span')[0].onclick = function () { + //这个链接404了 + //game.open('https://tieba.baidu.com/p/5439380222'); + //无名杀贴吧首页 + game.open('https://tieba.baidu.com/f?ie=utf-8&kw=%E6%97%A0%E5%90%8D%E6%9D%80'); + }; + shareExtLine.querySelectorAll('span')[1].onclick = function () { + shareExtLine.style.display = 'none'; + }; + + var dashboard = ui.create.div(pageboard); + var clickDash = function () { + ui.create.templayer(); + pageboard.hide(); + this.link.show(); + if (this.link.init) { + this.link.init(); + } + }; + var createDash = function (str1, str2, node) { + var dash = ui.create.div('.menubutton.large.dashboard'); + dashboard.appendChild(dash); + page.appendChild(node); + dash.link = node; + node.link = dash; + dash.listen(clickDash); + lib.setScroll(node); + ui.create.div('', str1, dash); + ui.create.div('', str2, dash); + }; + var dash1 = (function () { + var page = ui.create.div('.hidden.menu-buttons'); + var currentButton = null; + page.init = function () { + if (!page.querySelector('.button.character')) { + toggle.classList.add('on'); + newCharacter.style.display = ''; + } + }; + var updateButton = function () { + var name = page.querySelector('input.new_name').value; + if (!name) { + editnode.classList.add('disabled'); + return; + } + name = name.split('|'); + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.character[name] || page.content.pack.character[name]) { + editnode.classList.add('disabled'); + return; + } + } + } + else { + if (lib.character[name] || page.content.pack.character[name]) { + editnode.classList.add('disabled'); + return; + } + } + if (!fakeme.image) { + if (!page.content.image[name + '.jpg']) { + editnode.classList.add('disabled'); + return; + } + } + editnode.classList.remove('disabled'); + }; + var clickButton = async () => { + if (currentButton == this) { + resetEditor(); + return; + } + resetEditor(); + currentButton = this; + toggle.classList.add('on'); + newCharacter.style.display = ''; + fakeme.classList.add('inited'); + fakeme.style.backgroundImage = this.style.backgroundImage; + if (page.content.pack.translate[this.link] != this.link) { + newCharacter.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; + } + else { + newCharacter.querySelector('.new_name').value = this.link; + } + var info = page.content.pack.character[this.link]; + newCharacter.querySelector('.new_hp').value = info[2]; + sexes.value = info[0]; + groups.value = info[1]; + if (info[4]) { + for (var i = 0; i < options.childNodes.length - 1; i++) { + if (options.childNodes[i].lastChild && info[4].includes(options.childNodes[i].lastChild.name)) { + options.childNodes[i].lastChild.checked = true; + } + else if (options.childNodes[i].lastChild) { + options.childNodes[i].lastChild.checked = false; + } + } + for (var i = 0; i < info[4].length; i++) { + if (info[4][i].startsWith('des:')) { + newCharacter.querySelector('.new_des').value = info[4][i].slice(4); + } + if (info[4][i].startsWith('die:')) { + var dieaudionode = newCharacter.querySelector('.die_audio'); + dieaudionode.file = { + name: info[4][i].slice(info[4][i].lastIndexOf('/') + 1) + }; + await new Promise((resolve) => { + if (typeof game.readFile == 'function') { + game.readFile(info[4][i].slice(4).replace('ext:', 'extension/'), arraybuffer => { + dieaudionode.arrayBuffer = arraybuffer; + resolve(); + }, () => { + console.warn(`未找到${info[4][i].slice(4).replace('ext:', 'extension/')}阵亡配音`); + resolve(); + }); + } else { + game.getDB('image', info[4][i].slice(7)).then(octetStream => { + dieaudionode.arrayBuffer = octetStream; + resolve(); + }, () => { + console.warn(`未找到${info[4][i].slice(4)}阵亡配音`); + resolve(); + }); + } + }); + } + } + } + + var skills = info[3]; + for (var i = 0; i < skills.length; i++) { + var node = document.createElement('button'); + node.skill = skills[i]; + node.onclick = deletenode; + node.innerHTML = lib.translate[skills[i]]; + skillList.firstChild.appendChild(node); + } + + toggle.innerHTML = '编辑武将
      >
      '; + editnode.innerHTML = '编辑武将'; + editnode.classList.remove('disabled'); + delnode.innerHTML = '删除'; + delnode.button = this; + }; + var createButton = function (name, image) { + var button = ui.create.div('.button.character'); + button.link = name; + button.image = image; + button.style.backgroundImage = 'url(' + image + ')'; + button.style.backgroundSize = 'cover'; + button.listen(clickButton); + button.classList.add('noclick'); + button.nodename = ui.create.div(button, '.name', get.verticalStr(page.content.pack.translate[name])); + button.nodename.style.top = '8px'; + page.insertBefore(button, page.childNodes[1]); + }; + page.reset = function (name) { + resetEditor(); + var buttons = page.querySelectorAll('.button.character'); + var list = []; + for (var i = 0; i < buttons.length; i++) { + list.push(buttons[i]); + } + for (var i = 0; i < list.length; i++) { + list[i].remove(); + } + if (lib.extensionPack[name]) { + page.content.pack = lib.extensionPack[name].character || { + character: {}, + translate: {} + }; + page.content.image = {}; + for (var i in page.content.pack.character) { + var file = i + '.jpg'; + var loadImage = function (file, data) { + var img = new Image(); + img.crossOrigin = 'Anonymous'; + img.onload = function () { + var canvas = document.createElement('CANVAS'); + var ctx = canvas.getContext('2d'); + var dataURL; + canvas.height = this.height; + canvas.width = this.width; + ctx.drawImage(this, 0, 0); + canvas.toBlob(function (blob) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + page.content.image[file] = e.target.result; + }; + fileReader.readAsArrayBuffer(blob, "UTF-8"); + }); + }; + img.src = data; + }; + if (game.download) { + var url = lib.assetURL + 'extension/' + name + '/' + file; + createButton(i, url); + if (lib.device == 'ios' || lib.device == 'android') { + window.resolveLocalFileSystemURL(lib.assetURL + 'extension/' + name, function (entry) { + entry.getFile(file, {}, function (fileEntry) { + fileEntry.file(function (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + page.content.image[file] = e.target.result; + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + }); + }); + }); + } + else { + loadImage(file, url); + } + } + else game.getDB('image', `extension-${name}:${file}`).then(value => { + createButton(i, value); + loadImage(file, value); + }); + } + } + else { + page.content = { + pack: { + character: {}, + translate: {} + }, + image: {}, + audio: {} + }; + toggle.classList.add('on'); + newCharacter.style.display = ''; + } + }; + ui.create.div('.config.more', '
      返回', page, function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + }); + page.content = { + pack: { + character: {}, + translate: {} + }, + image: {}, + audio: {} + }; + var newCharacter; + var toggle = ui.create.div('.config.more.on', '创建武将
      >
      ', page, function () { + this.classList.toggle('on'); + if (this.classList.contains('on')) { + newCharacter.style.display = ''; + } + else { + newCharacter.style.display = 'none'; + } + }); + var resetEditor = function () { + currentButton = null; + toggle.classList.remove('on'); + newCharacter.style.display = 'none'; + fakeme.classList.remove('inited'); + delete fakeme.image; + delete fakeme.image64; + fakeme.style.backgroundImage = ''; + var inputs = newCharacter.querySelectorAll('input'); + for (var i = 0; i < inputs.length; i++) { + inputs[i].value = ''; + } + inputs = newCharacter.querySelectorAll('textarea'); + for (var i = 0; i < inputs.length; i++) { + inputs[i].value = ''; + } + skillList.firstChild.innerHTML = ''; + toggle.innerHTML = '创建武将
      >
      '; + editnode.innerHTML = '创建武将'; + editnode.classList.add('disabled'); + delnode.innerHTML = '取消'; + delete delnode.button; + }; + + newCharacter = ui.create.div('.new_character', page); + var fakeme = ui.create.div('.avatar', newCharacter); + + var input = document.createElement('input'); + input.type = 'file'; + input.accept = 'image/*'; + input.className = 'fileinput'; + input.onchange = function () { + var fileToLoad = input.files[0]; + if (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (fileLoadedEvent) { + var data = fileLoadedEvent.target.result; + fakeme.style.backgroundImage = 'url(' + data + ')'; + fakeme.image64 = data; + fakeme.classList.add('inited'); + var fileReader = new FileReader(); + fileReader.onload = function (fileLoadedEvent) { + fakeme.image = fileLoadedEvent.target.result; + updateButton(); + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + }; + fileReader.readAsDataURL(fileToLoad, "UTF-8"); + } + }; + fakeme.appendChild(input); + + ui.create.div('.select_avatar', '选择头像', fakeme); + + ui.create.div('.indent', '姓名:', newCharacter).style.paddingTop = '8px'; + ui.create.div('.indent', '介绍:', newCharacter).style.paddingTop = '8px'; + ui.create.div('.indent', '体力:', newCharacter).style.paddingTop = '8px'; + newCharacter.querySelector('input.new_name').onblur = updateButton; + var sexes = ui.create.selectlist([ + ['male', '男'], + ['female', '女'], + ['double', '双性'], + ['none', '无'] + ], null, ui.create.div('.indent', '性别:', newCharacter)); + var grouplist = lib.group.map((group, i) => [lib.group[i], get.translation(lib.group[i])]); + var groups = ui.create.selectlist(grouplist, null, ui.create.div('.indent', '势力:', newCharacter)); + var dieaudio = ui.create.div('.die_audio', newCharacter, { textAlign: 'left' }); + var dieaudiolabel = ui.create.node('label', '阵亡配音:', dieaudio); + var dieaudioUpload = dieaudio.appendChild(document.createElement('input')); + dieaudioUpload.type = 'file'; + dieaudioUpload.accept = 'audio/*'; + dieaudioUpload.style.width = 'calc(100% - 100px)'; + dieaudioUpload.onchange = function () { + var fileToLoad = dieaudioUpload.files[0]; + if (fileToLoad) { + console.log(fileToLoad); + var fileReader = new FileReader(); + fileReader.onload = function (fileLoadedEvent) { + var data = fileLoadedEvent.target.result; + var blob = new Blob([data]); + dieaudio.file = fileToLoad; + dieaudio.arrayBuffer = data; + dieaudio.blob = blob; + var new_name = newCharacter.querySelector('input.new_name'); + dieaudioUpload.style.display = 'none'; + dieaudiopreview.style.display = + dieaudiocancel.style.display = ''; + dieaudiotag.src = window.URL.createObjectURL(blob); + }; + fileReader.readAsArrayBuffer(fileToLoad); + } + }; + var dieaudiotag = ui.create.node('audio', dieaudio); + var dieaudiopreview = ui.create.node('button', dieaudio, () => { + if (dieaudiotag.error) { + alert('您使用的客户端不支持预览此音频!'); + } else dieaudiotag.play(); + }); + dieaudiopreview.innerHTML = '播放'; + dieaudiopreview.style.display = 'none'; + var dieaudiocancel = ui.create.node('button', dieaudio, () => { + dieaudiopreview.style.display = 'none'; + dieaudiocancel.style.display = 'none'; + if (dieaudio.blob) { + window.URL.revokeObjectURL(dieaudio.blob); + dieaudiotag.src = null; + delete dieaudio.file; + delete dieaudio.arrayBuffer; + delete dieaudio.blob; + } + dieaudioUpload.value = ''; + dieaudioUpload.style.display = ''; + }); + dieaudiocancel.innerHTML = '取消'; + dieaudiocancel.style.display = 'none'; + var options = ui.create.div('.add_skill.options', '主公BOSS仅点将可用
      隐匿技
      ', newCharacter); + var addSkill = ui.create.div('.add_skill', '添加技能
      ', newCharacter); + var list = []; + for (var i in lib.character) { + if (lib.character[i][3].length) { + list.push([i, lib.translate[i]]); + } + } + list.sort(function (a, b) { + a = a[0]; b = b[0]; + var aa = a, bb = b; + if (aa.includes('_')) { + aa = aa.slice(aa.indexOf('_') + 1); + } + if (bb.includes('_')) { + bb = bb.slice(bb.indexOf('_') + 1); + } + if (aa != bb) { + return aa > bb ? 1 : -1; + } + return a > b ? 1 : -1; + }); + var list2 = []; + var skills = lib.character[list[0][0]][3]; + for (var i = 0; i < skills.length; i++) { + list2.push([skills[i], lib.translate[skills[i]]]); + } + list.unshift(['current_extension', '此扩展']); + + var selectname = ui.create.selectlist(list, list[1], addSkill); + page.selectname = selectname; + selectname.onchange = function () { + skillopt.innerHTML = ''; + if (this.value == 'current_extension') { + for (var i in dash3.content.pack.skill) { + var option = document.createElement('option'); + option.value = i; + option.innerHTML = dash3.content.pack.translate[i]; + skillopt.appendChild(option); + } + } + else { + var skills = lib.character[this.value][3]; + for (var i = 0; i < skills.length; i++) { + var option = document.createElement('option'); + option.value = skills[i]; + option.innerHTML = lib.translate[skills[i]]; + skillopt.appendChild(option); + } + } + }; + selectname.style.maxWidth = '85px'; + var skillopt = ui.create.selectlist(list2, list2[0], addSkill); + skillopt.style.maxWidth = '60px'; + page.skillopt = skillopt; + var addSkillButton = document.createElement('button'); + addSkillButton.innerHTML = '添加'; + addSkill.appendChild(addSkillButton); + page.addSkillButton = addSkillButton; + var deletenode = function () { + this.remove(); + }; + addSkillButton.onclick = function () { + for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { + if (skillList.firstChild.childNodes[i].skill == skillopt.value) return alert(selectname.value == 'current_extension' ? '此扩展还未添加技能' : '此武将没有技能可添加'); + } + //无技能时 + if (!skillopt.value || skillopt.childElementCount == 0) return; + var node = document.createElement('button'); + node.skill = skillopt.value; + node.onclick = deletenode; + for (var i = 0; i < skillopt.childElementCount; i++) { + if (skillopt.childNodes[i].value == skillopt.value) { + node.innerHTML = skillopt.childNodes[i].innerHTML; break; + } + } + skillList.firstChild.appendChild(node); + }; + var createSkillButton = document.createElement('button'); + createSkillButton.innerHTML = '创建'; + createSkillButton.style.marginLeft = '3px'; + addSkill.appendChild(createSkillButton); + createSkillButton.onclick = function () { + ui.create.templayer(); + page.hide(); + dash3.show(); + dash3.fromchar = 'add'; + dash3.toggle.classList.add('on'); + dash3.newSkill.style.display = ''; + }; + page.updateSkill = function () { + for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { + var node = skillList.firstChild.childNodes[i]; + var skill = skillList.firstChild.childNodes[i].skill; + if (dash3.content.pack.skill[skill]) { + node.innerHTML = dash3.content.pack.translate[skill]; + } + else if (lib.skill[skill]) { + node.innerHTML = lib.translate[skill]; + } + else { + node.remove(); i--; + } + } + }; + var skillList = ui.create.div('.skill_list', newCharacter); + ui.create.div(skillList); + var editnode = ui.create.div('.menubutton.large.disabled', '创建武将', ui.create.div(skillList), function () { + var name = page.querySelector('input.new_name').value; + if (!name) { + alert('请填写武将名\n提示:武将名格式为id+|+中文名,其中id必须惟一'); + return; + } + name = name.split('|'); + var translate = name[1] || name[0]; + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.character[name] || page.content.pack.character[name]) { + alert('武将名与现有武将重复,请更改\n提示:武将名格式为id+|+中文名,其中id必须惟一'); + return; + } + page.content.image[name + '.jpg'] = page.content.image[currentButton.link + '.jpg']; + delete page.content.image[currentButton.link + '.jpg']; + delete page.content.pack.character[currentButton.link]; + delete page.content.pack.translate[currentButton.link]; + currentButton.link = name; + } + } + else { + if (lib.character[name] || page.content.pack.character[name]) { + alert('武将名与现有武将重复,请更改\n提示:武将名格式为id+|+中文名,其中id必须惟一'); + return; + } + } + if (fakeme.image) { + page.content.image[name + '.jpg'] = fakeme.image; + } + else { + if (!page.content.image[name + '.jpg']) { + alert('请选择武将头像'); + return; + } + } + var hp = page.querySelector('input.new_hp').value; + //体力支持‘Infinity,∞,无限’表示无限 + if (['Infinity', '∞', '无限'].includes(hp)) hp = Infinity; + else if (hp.indexOf('/') == -1) hp = parseInt(hp) || 1; + var skills = []; + for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { + skills.add(skillList.firstChild.childNodes[i].skill); + } + var tags = []; + for (var i = 0; i < options.childNodes.length - 1; i++) { + if (options.childNodes[i].lastChild && options.childNodes[i].lastChild.checked) { + tags.push(options.childNodes[i].lastChild.name); + } + } + if (tags.includes('boss')) { + tags.add('bossallowed'); + } + var des = page.querySelector('input.new_des').value; + if (des) { + tags.add('des:' + des); + } + //阵亡配音 + if (dieaudio.file && dieaudio.arrayBuffer) { + var audioname = name + dieaudio.file.name.slice(dieaudio.file.name.indexOf('.')); + tags.add(`die:${typeof game.readFile == 'function' ? 'ext' : 'db'}:audio/die/${audioname}`); + page.content.audio[audioname] = dieaudio.arrayBuffer; + } + + page.content.pack.translate[name] = translate; + page.content.pack.character[name] = [sexes.value, groups.value, hp, skills, tags]; + if (this.innerHTML == '创建武将') { + createButton(name, fakeme.image64); + } + else if (currentButton) { + if (fakeme.image64) { + currentButton.image = fakeme.image64; + currentButton.style.backgroundImage = 'url(' + fakeme.image64 + ')'; + } + currentButton.nodename.innerHTML = get.verticalStr(translate); + } + resetEditor(); + dash1.link.classList.add('active'); + }); + var delnode = ui.create.div('.menubutton.large', '取消', editnode.parentNode, function () { + if (this.innerHTML == '删除') { + this.button.remove(); + var name = this.button.link; + delete dash1.content.pack.character[name]; + delete dash1.content.pack.translate[name]; + delete dash1.content.image[name]; + delete dash1.content.audio[name]; + dash1.link.classList.add('active'); + } + resetEditor(); + }); + delnode.style.marginLeft = '13px'; + + return page; + }()); + var dash2 = (function () { + var page = ui.create.div('.hidden.menu-buttons'); + var currentButton = null; + page.init = function () { + if (!page.querySelector('.button.card')) { + toggle.classList.add('on'); + newCard.style.display = ''; + } + }; + var updateButton = function () { + var name = page.querySelector('input.new_name').value; + if (!name) { + editnode.classList.add('disabled'); + return; + } + name = name.split('|'); + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.card[name] || page.content.pack.card[name]) { + editnode.classList.add('disabled'); + return; + } + } + } + else { + if (lib.card[name] || page.content.pack.card[name]) { + editnode.classList.add('disabled'); + return; + } + } + if (!fakeme.image && !fakeme.classList.contains('inited')) { + editnode.classList.add('disabled'); + return; + } + editnode.classList.remove('disabled'); + }; + var clickButton = function () { + if (currentButton == this) { + resetEditor(); + return; + } + resetEditor(); + currentButton = this; + toggle.classList.add('on'); + newCard.style.display = ''; + fakeme.classList.add('inited'); + delete fakeme.image; + delete fakeme.image64; + if (this.classList.contains('fullskin')) { + fakeme.imagenode.style.backgroundImage = this.imagenode.style.backgroundImage; + fakeme.classList.add('fullskin'); + } + else { + fakeme.style.backgroundImage = this.style.backgroundImage; + fakeme.classList.remove('fullskin'); + } + if (page.content.pack.translate[this.link] != this.link) { + newCard.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; + } + else { + newCard.querySelector('.new_name').value = this.link; + } + newCard.querySelector('.new_description').value = page.content.pack.translate[this.link + '_info']; + var info = page.content.pack.card[this.link]; + container.code = 'card=' + get.stringify(info); + + toggle.innerHTML = '编辑卡牌
      >
      '; + editnode.innerHTML = '编辑卡牌'; + editnode.classList.remove('disabled'); + delnode.innerHTML = '删除'; + delnode.button = this; + }; + var createButton = function (name, image, fullskin) { + var button = ui.create.div('.button.card'); + button.link = name; + button.image = image; + button.imagenode = ui.create.div('.image', button); + if (image) { + if (fullskin) { + button.imagenode.style.backgroundImage = 'url(' + image + ')'; + button.style.backgroundImage = ''; + button.style.backgroundSize = ''; + button.classList.add('fullskin'); + } + else { + button.style.color = 'white'; + button.style.textShadow = 'black 0 0 2px'; + button.imagenode.style.backgroundImage = ''; + button.style.backgroundImage = 'url(' + image + ')'; + button.style.backgroundSize = 'cover'; + } + } + button.listen(clickButton); + button.classList.add('noclick'); + button.nodename = ui.create.div(button, '.name', get.verticalStr(page.content.pack.translate[name])); + page.insertBefore(button, page.childNodes[1]); + }; + page.reset = function (name) { + resetEditor(); + var buttons = page.querySelectorAll('.button.card'); + var list = []; + for (var i = 0; i < buttons.length; i++) { + list.push(buttons[i]); + } + for (var i = 0; i < list.length; i++) { + list[i].remove(); + } + if (lib.extensionPack[name]) { + page.content.pack = lib.extensionPack[name].card || { + card: {}, + translate: {} + }; + page.content.image = {}; + if (Array.isArray(page.content.pack.list)) { + for (var i = 0; i < page.content.pack.list.length; i++) { + var card = page.content.pack.list[i]; + var node = document.createElement('button'); + node.innerHTML = page.content.pack.translate[card[2]] + ' ' + lib.translate[card[0]] + card[1]; + node.name = card[2]; + node.link = card; + pile.appendChild(node); + node.onclick = function () { + this.remove(); + }; + } + } + for (var i in page.content.pack.card) { + var file; + var fullskin = page.content.pack.card[i].fullskin ? true : false; + if (fullskin) { + file = i + '.png'; + } + else { + file = i + '.jpg'; + } + var loadImage = function (file, data) { + var img = new Image(); + img.crossOrigin = 'Anonymous'; + img.onload = function () { + var canvas = document.createElement('CANVAS'); + var ctx = canvas.getContext('2d'); + var dataURL; + canvas.height = this.height; + canvas.width = this.width; + ctx.drawImage(this, 0, 0); + canvas.toBlob(function (blob) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + page.content.image[file] = e.target.result; + }; + fileReader.readAsArrayBuffer(blob, "UTF-8"); + }); + }; + img.src = data; + }; + if (game.download) { + var url = lib.assetURL + 'extension/' + name + '/' + file; + createButton(i, url, fullskin); + if (lib.device == 'ios' || lib.device == 'android') { + window.resolveLocalFileSystemURL(lib.assetURL + 'extension/' + name, function (entry) { + entry.getFile(file, {}, function (fileEntry) { + fileEntry.file(function (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + page.content.image[file] = e.target.result; + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + }); + }); + }); + } + else { + loadImage(file, url); + } + } + else game.getDB('image', `extension-${name}:${file}`).then(value => { + createButton(i, value, fullskin); + loadImage(file, value); + }); + } + } + else { + page.content = { + pack: { + card: {}, + translate: {} + }, + image: {} + }; + toggle.classList.add('on'); + newCard.style.display = ''; + } + updatePile(); + }; + ui.create.div('.config.more.margin-bottom', '
      返回', page, function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + }); + page.content = { + pack: { + card: {}, + translate: {}, + list: [] + }, + image: {} + }; + var newCard; + var toggle = ui.create.div('.config.more.on', '创建卡牌
      >
      ', page, function () { + this.classList.toggle('on'); + if (this.classList.contains('on')) { + newCard.style.display = ''; + } + else { + newCard.style.display = 'none'; + } + }); + var resetEditor = function () { + currentButton = null; + toggle.classList.remove('on'); + newCard.style.display = 'none'; + fakeme.classList.remove('inited'); + fakeme.classList.add('fullskin'); + delete fakeme.image; + delete fakeme.image64; + fakeme.style.backgroundImage = ''; + fakeme.imagenode.style.backgroundImage = ''; + var inputs = newCard.querySelectorAll('input'); + for (var i = 0; i < inputs.length; i++) { + inputs[i].value = ''; + } + toggle.innerHTML = '创建卡牌
      >
      '; + editnode.innerHTML = '创建卡牌'; + editnode.classList.add('disabled'); + delnode.innerHTML = '取消'; + delete delnode.button; + container.code = 'card={\n \n}\n\n/*\n示例:\ncard={\n type:"basic",\n enable:true,\n filterTarget:true,\n content:function(){\n target.draw()\n },\n ai:{\n order:1,\n result:{\n target:1\n }\n }\n}\n此例的效果为目标摸一张牌\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + }; + + newCard = ui.create.div('.new_character', page); + newCard.style.height = '173px'; + var fakeme = ui.create.div('.card.fullskin', newCard); + + var input = document.createElement('input'); + input.type = 'file'; + input.accept = 'image/*'; + input.className = 'fileinput'; + input.onchange = function () { + var fileToLoad = input.files[0]; + if (fileToLoad) { + var fileReader = new FileReader(); + var fullimage = (fileToLoad.name.includes('.jpg')); + fileReader.onload = function (fileLoadedEvent) { + var data = fileLoadedEvent.target.result; + if (fullimage) { + fakeme.imagenode.style.backgroundImage = ''; + fakeme.style.backgroundImage = 'url(' + data + ')'; + fakeme.classList.remove('fullskin'); + } + else { + fakeme.style.backgroundImage = ''; + fakeme.imagenode.style.backgroundImage = 'url(' + data + ')'; + fakeme.classList.add('fullskin'); + } + fakeme.image64 = data; + fakeme.classList.add('inited'); + var fileReader = new FileReader(); + fileReader.onload = function (fileLoadedEvent) { + fakeme.image = fileLoadedEvent.target.result; + updateButton(); + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + }; + fileReader.readAsDataURL(fileToLoad, "UTF-8"); + } + }; + fakeme.appendChild(input); + + fakeme.imagenode = ui.create.div('.image', fakeme); + ui.create.div('.name', '选择背景', fakeme); + + ui.create.div('.indent', '名称:', newCard).style.paddingTop = '8px'; + ui.create.div('.indent', '描述:', newCard).style.paddingTop = '6px'; + newCard.querySelector('input.new_name').onblur = updateButton; + var codeButton = document.createElement('button'); + newCard.appendChild(codeButton); + codeButton.innerHTML = '编辑代码'; + codeButton.style.left = '123px'; + codeButton.style.top = '66px'; + codeButton.style.position = 'absolute'; + + var citeButton = document.createElement('button'); + newCard.appendChild(citeButton); + citeButton.innerHTML = '引用代码'; + citeButton.style.left = '123px'; + citeButton.style.top = '90px'; + citeButton.style.position = 'absolute'; + citeButton.onclick = function () { + codeButton.style.display = 'none'; + citeButton.style.display = 'none'; + selectname.style.display = ''; + confirmcontainer.style.display = ''; + }; + + var list = []; + for (var i in lib.card) { + if (lib.translate[i]) { + list.push([i, lib.translate[i]]); + } + } + list.sort(function (a, b) { + a = a[0]; b = b[0]; + var aa = a, bb = b; + if (aa.includes('_')) { + aa = aa.slice(aa.indexOf('_') + 1); + } + if (bb.includes('_')) { + bb = bb.slice(bb.indexOf('_') + 1); + } + if (aa != bb) { + return aa > bb ? 1 : -1; + } + return a > b ? 1 : -1; + }); + var selectname = ui.create.selectlist(list, list[0], newCard); + selectname.style.left = '123px'; + selectname.style.top = '66px'; + selectname.style.position = 'absolute'; + selectname.style.display = 'none'; + + var confirmcontainer = ui.create.div(newCard); + confirmcontainer.style.left = '123px'; + confirmcontainer.style.top = '90px'; + confirmcontainer.style.position = 'absolute'; + confirmcontainer.style.display = 'none'; + + var citeconfirm = document.createElement('button'); + citeconfirm.innerHTML = '引用'; + confirmcontainer.appendChild(citeconfirm); + citeconfirm.onclick = function () { + codeButton.style.display = ''; + citeButton.style.display = ''; + selectname.style.display = 'none'; + confirmcontainer.style.display = 'none'; + container.code = 'card=' + get.stringify(lib.card[selectname.value]); + codeButton.onclick.call(codeButton); + if (lib.translate[selectname.value + '_info']) { + newCard.querySelector('input.new_description').value = lib.translate[selectname.value + '_info']; + } + }; + + var citecancel = document.createElement('button'); + citecancel.innerHTML = '取消'; + citecancel.style.marginLeft = '3px'; + confirmcontainer.appendChild(citecancel); + citecancel.onclick = function () { + codeButton.style.display = ''; + citeButton.style.display = ''; + selectname.style.display = 'none'; + confirmcontainer.style.display = 'none'; + }; + + codeButton.onclick = function () { + var node = container; + ui.window.classList.add('shortcutpaused'); + ui.window.classList.add('systempaused'); + window.saveNonameInput = saveInput; + if (node.aced) { + ui.window.appendChild(node); + node.editor.setValue(node.code, 1); + } + else if (lib.device == 'ios') { + ui.window.appendChild(node); + if (!node.textarea) { + var textarea = document.createElement('textarea'); + editor.appendChild(textarea); + node.textarea = textarea; + lib.setScroll(textarea); + } + node.textarea.value = node.code; + } + else { + if (!window.CodeMirror) { + import('../../game/codemirror.js').then(() => { + lib.codeMirrorReady(node, editor); + }); + lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); + } + else { + lib.codeMirrorReady(node, editor); + } + } + }; + + var container = ui.create.div('.popup-container.editor'); + var saveInput = function () { + var code; + if (container.editor) { + code = container.editor.getValue(); + } + else if (container.textarea) { + code = container.textarea.value; + } + try { + var card = null; + eval(code); + if (card == null || typeof card != 'object') { + throw ('err'); + } + } + catch (e) { + if (e == 'err') { + alert('代码格式有错误,请对比示例代码仔细检查'); + } + else { + var tip = lib.getErrorTip(e) || ''; + alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + } + window.focus(); + if (container.editor) { + container.editor.focus(); + } + else if (container.textarea) { + container.textarea.focus(); + } + return; + } + dash2.link.classList.add('active'); + ui.window.classList.remove('shortcutpaused'); + ui.window.classList.remove('systempaused'); + container.delete(); + container.code = code; + delete window.saveNonameInput; + }; + var editor = ui.create.editor(container, saveInput); + container.code = 'card={\n \n}\n\n/*\n示例:\ncard={\n type:"basic",\n enable:true,\n filterTarget:true,\n content:function(){\n target.draw()\n },\n ai:{\n order:1,\n result:{\n target:1\n }\n }\n}\n此例的效果为目标摸一张牌\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + + var editnode = ui.create.div('.menubutton.large.new_card.disabled', '创建卡牌', newCard, function () { + var name = page.querySelector('input.new_name').value; + if (!name) { + alert('请填写卡牌名\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); + return; + } + name = name.split('|'); + var translate = name[1] || name[0]; + var info = page.querySelector('input.new_description').value; + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.card[name] || page.content.pack.card[name]) { + alert('卡牌名与现有卡牌重复,请更改\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); + return; + } + var extname; + if (currentButton.classList.contains('fullskin')) { + extname = '.png'; + } + else { + extname = '.jpg'; + } + page.content.image[name + extname] = page.content.image[currentButton.link + extname]; + delete page.content.image[currentButton.link + extname]; + delete page.content.pack.card[currentButton.link]; + delete page.content.pack.translate[currentButton.link]; + delete page.content.pack.translate[currentButton.link + '_info']; + currentButton.link = name; + } + } + else { + if (lib.card[name] || page.content.pack.card[name]) { + alert('卡牌名与现有卡牌重复,请更改\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); + return; + } + } + if (fakeme.image) { + if (fakeme.classList.contains('fullskin')) { + page.content.image[name + '.png'] = fakeme.image; + delete page.content.image[name + '.jpg']; + } + else { + page.content.image[name + '.jpg'] = fakeme.image; + delete page.content.image[name + '.png']; + } + } + else if (!fakeme.classList.contains('inited')) { + alert('请选择一个卡牌背景'); + return; + } + page.content.pack.translate[name] = translate; + page.content.pack.translate[name + '_info'] = info; + try { + var card = null; + eval(container.code); + if (card == null || typeof card != 'object') { + throw ('err'); + } + page.content.pack.card[name] = card; + } + catch (e) { + page.content.pack.card[name] = {}; + } + if (fakeme.classList.contains('inited')) { + if (fakeme.classList.contains('fullskin')) { + page.content.pack.card[name].fullskin = true; + delete page.content.pack.card[name].fullimage; + } + else { + page.content.pack.card[name].fullimage = true; + delete page.content.pack.card[name].fullskin; + } + } + if (this.innerHTML == '创建卡牌') { + createButton(name, fakeme.image64, fakeme.classList.contains('fullskin')); + } + else if (currentButton) { + if (fakeme.image64) { + if (fakeme.classList.contains('fullskin')) { + currentButton.style.color = ''; + currentButton.style.textShadow = ''; + currentButton.imagenode.style.backgroundImage = 'url(' + fakeme.image64 + ')'; + currentButton.style.backgroundImage = ''; + currentButton.style.backgroundSize = ''; + currentButton.classList.add('fullskin'); + } + else { + currentButton.style.color = 'white'; + currentButton.style.textShadow = 'black 0 0 2px'; + currentButton.imagenode.style.backgroundImage = ''; + currentButton.style.backgroundImage = 'url(' + fakeme.image64 + ')'; + currentButton.style.backgroundSize = 'cover'; + currentButton.classList.remove('fullskin'); + } + } + currentButton.nodename.innerHTML = get.verticalStr(translate); + } + resetEditor(); + updatePile(); + dash2.link.classList.add('active'); + }); + var delnode = ui.create.div('.menubutton.large.new_card_delete', '取消', editnode.parentNode, function () { + if (this.innerHTML == '删除') { + this.button.remove(); + var name = this.button.link; + delete dash2.content.pack.card[name]; + delete dash2.content.pack.translate[name]; + delete dash2.content.pack.translate[name + '_info']; + delete dash2.content.image[name]; + updatePile(); + dash2.link.classList.add('active'); + } + resetEditor(); + }); + + var editPile; + var toggle2 = ui.create.div('.config.more', '编辑牌堆
      >
      ', page, function () { + this.classList.toggle('on'); + if (this.classList.contains('on')) { + editPile.style.display = ''; + } + else { + editPile.style.display = 'none'; + } + }); + + editPile = ui.create.div('.edit_pile', page); + editPile.style.display = 'none'; + + + var cardpileadd = ui.create.div('.config.toggle.cardpilecfg.cardpilecfgadd', editPile); + var pile = ui.create.div(editPile); + page.pile = pile; + var cardpileaddname = document.createElement('select'); + var updatePile = function () { + cardpileaddname.innerHTML = ''; + var list = []; + var list2 = []; + for (var i in page.content.pack.card) { + list.push([i, page.content.pack.translate[i]]); + list2.push(i); + } + if (list.length) { + toggle2.style.display = ''; + if (toggle2.classList.contains('on')) { + editPile.style.display = ''; + } + else { + editPile.style.display = 'none'; + } + for (var i = 0; i < list.length; i++) { + var option = document.createElement('option'); + option.value = list[i][0]; + option.innerHTML = list[i][1]; + cardpileaddname.appendChild(option); + } + for (var i = 0; i < pile.childNodes.length; i++) { + if (!list2.includes(pile.childNodes[i].name)) { + pile.childNodes[i].remove(); i--; + } + } + } + else { + toggle2.style.display = 'none'; + editPile.style.display = 'none'; + pile.innerHTML = ''; + } + }; + updatePile(); + cardpileadd.appendChild(cardpileaddname); + cardpileaddname.style.width = '75px'; + cardpileaddname.style.marginRight = '2px'; + cardpileaddname.style.marginLeft = '-1px'; + var cardpileaddsuit = ui.create.selectlist([ + ['heart', '红桃'], + ['diamond', '方片'], + ['club', '梅花'], + ['spade', '黑桃'], + ], null, cardpileadd); + cardpileaddsuit.style.width = '53px'; + cardpileaddsuit.style.marginRight = '2px'; + var cardpileaddnumber = ui.create.selectlist([ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 + ], null, cardpileadd); + cardpileaddnumber.style.width = '43px'; + cardpileaddnumber.style.marginRight = '2px'; + var button = document.createElement('button'); + button.innerHTML = '确定'; + button.style.width = '40px'; + button.onclick = function () { + var card = [ + cardpileaddsuit.value, + cardpileaddnumber.value, + cardpileaddname.value, + ]; + var node = document.createElement('button'); + node.innerHTML = page.content.pack.translate[card[2]] + ' ' + lib.translate[card[0]] + card[1]; + node.name = card[2]; + node.link = card; + pile.appendChild(node); + node.onclick = function () { + this.remove(); + }; + }; + cardpileadd.appendChild(button); + cardpileadd.style.whiteSpace = 'nowrap'; + cardpileadd.style.position = 'relative'; + cardpileadd.style.right = '-4px'; + + return page; + }()); + var dash3 = (function () { + var page = ui.create.div('.hidden.menu-buttons.new_skill'); + var updateButton = function () { + var name = page.querySelector('input.new_name').value; + if (!name) { + editnode.classList.add('disabled'); + return; + } + name = name.split('|'); + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.skill[name] || page.content.pack.skill[name]) { + editnode.classList.add('disabled'); + return; + } + } + } + else { + if (lib.skill[name] || page.content.pack.skill[name]) { + editnode.classList.add('disabled'); + return; + } + } + editnode.classList.remove('disabled'); + }; + page.init = function () { + if (!page.querySelector('.menubutton:not(.large)')) { + toggle.classList.add('on'); + newSkill.style.display = ''; + } + }; + page.reset = function (name) { + resetEditor(); + var buttons = page.querySelectorAll('.menubutton:not(.large)'); + var list = []; + for (var i = 0; i < buttons.length; i++) { + list.push(buttons[i]); + } + for (var i = 0; i < list.length; i++) { + list[i].remove(); + } + if (lib.extensionPack[name]) { + page.content.pack = lib.extensionPack[name].skill || { + skill: {}, + translate: {} + }; + page.content.audio = {}; + for (var i in page.content.pack.skill) { + createButton(i); + } + dash1.updateSkill(); + } + else { + page.content = { + pack: { + skill: {}, + translate: {} + }, + audio: {} + }; + toggle.classList.add('on'); + newSkill.style.display = ''; + } + }; + ui.create.div('.config.more.margin-bottom', '
      返回', page, function () { + ui.create.templayer(); + page.hide(); + if (page.fromchar) { + dash1.show(); + delete page.fromchar; + } + else { + pageboard.show(); + } + }); + var currentButton = null; + var clickButton = function () { + if (currentButton == this) { + resetEditor(); + return; + } + resetEditor(); + currentButton = this; + toggle.classList.add('on'); + newSkill.style.display = ''; + if (page.content.pack.translate[this.link] != this.link) { + newSkill.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; + } + else { + newSkill.querySelector('.new_name').value = this.link; + } + newSkill.querySelector('.new_description').value = page.content.pack.translate[this.link + '_info']; + var info = page.content.pack.skill[this.link]; + container.code = 'skill=' + get.stringify(Object.defineProperty({ ...info }, '_priority', { enumerable: false, writable: true, configurable: true })); + toggle.innerHTML = '编辑技能
      >
      '; + editnode.innerHTML = '编辑技能'; + editnode.classList.remove('disabled'); + delnode.button = this; + delnode.innerHTML = '删除'; + }; + var createButton = function (name) { + var button = ui.create.div('.menubutton'); + button.link = name; + button.innerHTML = page.content.pack.translate[name]; + button.listen(clickButton); + page.insertBefore(button, page.childNodes[1]); + }; + var newSkill; + var toggle = ui.create.div('.config.more.on', '创建技能
      >
      ', page, function () { + this.classList.toggle('on'); + if (this.classList.contains('on')) { + newSkill.style.display = ''; + } + else { + newSkill.style.display = 'none'; + } + }); + page.toggle = toggle; + var resetEditor = function () { + currentButton = null; + toggle.classList.remove('on'); + newSkill.style.display = 'none'; + var inputs = newSkill.querySelectorAll('input'); + for (var i = 0; i < inputs.length; i++) { + inputs[i].value = ''; + } + var inputs = newSkill.querySelectorAll('textarea'); + for (var i = 0; i < inputs.length; i++) { + inputs[i].value = ''; + } + toggle.innerHTML = '创建技能
      >
      '; + editnode.innerHTML = '创建技能'; + editnode.classList.add('disabled'); + delnode.innerHTML = '取消'; + delete delnode.button; + container.code = 'skill={\n \n}\n\n/*\n示例:\nskill={\n trigger:{player:"phaseJieshuBegin"},\n frequent:true,\n content:function(){\n player.draw()\n }\n}\n此例为闭月代码\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + if (page.fromchar == 'add') { + page.fromchar = true; + } + }; + + newSkill = ui.create.div('.new_character.new_skill', page); + page.newSkill = newSkill; + var namenode = ui.create.div('.config', '名称:', newSkill); + var descnode = ui.create.div('.config', '描述:', newSkill); + namenode.querySelector('input.new_name').onblur = updateButton; + var commandline = ui.create.div('.config', newSkill); + var editbutton = document.createElement('button'); + editbutton.innerHTML = '编辑代码'; + commandline.appendChild(editbutton); + editbutton.onclick = function () { + var node = container; + ui.window.classList.add('shortcutpaused'); + ui.window.classList.add('systempaused'); + window.saveNonameInput = saveInput; + if (node.aced) { + ui.window.appendChild(node); + node.editor.setValue(node.code, 1); + } + else if (lib.device == 'ios') { + ui.window.appendChild(node); + if (!node.textarea) { + var textarea = document.createElement('textarea'); + editor.appendChild(textarea); + node.textarea = textarea; + lib.setScroll(textarea); + } + node.textarea.value = node.code; + } + else { + if (!window.CodeMirror) { + import('../../game/codemirror.js').then(() => { + lib.codeMirrorReady(node, editor); + }); + lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); + } + else { + lib.codeMirrorReady(node, editor); + } + } + }; + + var container = ui.create.div('.popup-container.editor'); + var saveInput = function () { + var code; + if (container.editor) { + code = container.editor.getValue(); + } + else if (container.textarea) { + code = container.textarea.value; + } + try { + var skill = null; + eval(code); + if (skill == null || typeof skill != 'object') { + throw ('err'); + } + } + catch (e) { + if (e == 'err') { + alert('代码格式有错误,请对比示例代码仔细检查'); + } + else { + var tip = lib.getErrorTip(e) || ''; + alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + } + window.focus(); + if (container.editor) { + container.editor.focus(); + } + else if (container.textarea) { + container.textarea.focus(); + } + return; + } + dash3.link.classList.add('active'); + ui.window.classList.remove('shortcutpaused'); + ui.window.classList.remove('systempaused'); + container.delete(); + container.code = code; + delete window.saveNonameInput; + }; + var editor = ui.create.editor(container, saveInput); + container.code = 'skill={\n \n}\n\n/*\n示例:\nskill={\n trigger:{player:"phaseJieshuBegin"},\n frequent:true,\n content:function(){\n player.draw()\n }\n}\n此例为闭月代码\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + + var citebutton = document.createElement('button'); + citebutton.innerHTML = '引用代码'; + commandline.appendChild(citebutton); + citebutton.onclick = function () { + editbutton.style.display = 'none'; + citebutton.style.display = 'none'; + selectname.style.display = ''; + skillopt.style.display = ''; + addSkillButton.style.display = ''; + cancelSkillButton.style.display = ''; + }; + + var list = []; + for (var i in lib.character) { + if (lib.character[i][3].length) { + list.push([i, lib.translate[i]]); + } + } + list.sort(function (a, b) { + a = a[0]; b = b[0]; + var aa = a, bb = b; + if (aa.includes('_')) { + aa = aa.slice(aa.indexOf('_') + 1); + } + if (bb.includes('_')) { + bb = bb.slice(bb.indexOf('_') + 1); + } + if (aa != bb) { + return aa > bb ? 1 : -1; + } + return a > b ? 1 : -1; + }); + list.push(['others', '其它']); + var list2 = []; + var skills = lib.character[list[0][0]][3]; + for (var i = 0; i < skills.length; i++) { + list2.push([skills[i], lib.translate[skills[i]]]); + } + var selectname = ui.create.selectlist(list, list[0], commandline); + var list3 = []; + for (var i in lib.skill) { + if (i != 'global' && !get.is.empty(lib.skill[i]) && !lib.skilllist.includes(i)) { + list3.push(i); + } + } + list3.sort(function (a, b) { + return a > b ? 1 : -1; + }); + selectname.onchange = function () { + var skills; + skillopt.innerHTML = ''; + if (this.value == 'others') { + skills = list3; + for (var i = 0; i < skills.length; i++) { + var option = document.createElement('option'); + option.value = skills[i]; + option.innerHTML = skills[i]; + skillopt.appendChild(option); + } + } + else { + skills = lib.character[this.value][3]; + for (var i = 0; i < skills.length; i++) { + var option = document.createElement('option'); + option.value = skills[i]; + option.innerHTML = lib.translate[skills[i]]; + skillopt.appendChild(option); + } + } + }; + selectname.style.display = 'none'; + selectname.style.maxWidth = '80px'; + var skillopt = ui.create.selectlist(list2, list2[0], commandline); + skillopt.style.display = 'none'; + skillopt.style.maxWidth = '60px'; + var addSkillButton = document.createElement('button'); + addSkillButton.style.display = 'none'; + addSkillButton.innerHTML = '引用'; + commandline.appendChild(addSkillButton); + addSkillButton.onclick = function () { + editbutton.style.display = ''; + citebutton.style.display = ''; + selectname.style.display = 'none'; + skillopt.style.display = 'none'; + addSkillButton.style.display = 'none'; + cancelSkillButton.style.display = 'none'; + container.code = 'skill=' + get.stringify(Object.defineProperty({ ...lib.skill[skillopt.value] }, '_priority', { enumerable: false, writable: true, configurable: true })); + editbutton.onclick.call(editbutton); + if (lib.translate[skillopt.value + '_info']) { + newSkill.querySelector('input.new_description').value = lib.translate[skillopt.value + '_info']; + } + }; + var cancelSkillButton = document.createElement('button'); + cancelSkillButton.style.display = 'none'; + cancelSkillButton.innerHTML = '取消'; + commandline.appendChild(cancelSkillButton); + cancelSkillButton.onclick = function () { + editbutton.style.display = ''; + citebutton.style.display = ''; + selectname.style.display = 'none'; + skillopt.style.display = 'none'; + addSkillButton.style.display = 'none'; + cancelSkillButton.style.display = 'none'; + }; + + var editnode = ui.create.div('.menubutton.large.new_skill.disabled', '创建技能', function () { + var name = page.querySelector('input.new_name').value; + if (!name) { + alert('请填写技能名\n提示:技能名格式为id+|+中文名,其中id必须惟一'); + return; + } + name = name.split('|'); + var translate = name[1] || name[0]; + var info = page.querySelector('input.new_description').value; + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.skill[name] || page.content.pack.skill[name]) { + alert('技能名与现有技能重复,请更改\n提示:技能名格式为id+|+中文名,其中id必须惟一'); + return; + } + delete page.content.pack.skill[currentButton.link]; + delete page.content.pack.translate[currentButton.link]; + delete page.content.pack.translate[currentButton.link + '_info']; + currentButton.link = name; + } + } + else { + if (lib.skill[name] || page.content.pack.skill[name]) { + alert('技能名与现有技能重复,请更改\n提示:技能名格式为id+|+中文名,其中id必须惟一'); + return; + } + } + page.content.pack.translate[name] = translate; + page.content.pack.translate[name + '_info'] = info; + try { + var skill = null; + eval(container.code); + if (skill == null || typeof skill != 'object') { + throw ('err'); + } + page.content.pack.skill[name] = skill; + } + catch (e) { + page.content.pack.skill[name] = {}; + } + dash1.selectname.value = 'current_extension'; + dash1.selectname.onchange.call(dash1.selectname); + if (this.innerHTML == '创建技能') { + createButton(name); + if (page.fromchar == 'add') { + ui.create.templayer(); + page.hide(); + dash1.show(); + dash1.skillopt.value = name; + dash1.addSkillButton.onclick(); + delete page.fromchar; + } + } + else if (currentButton) { + currentButton.innerHTML = translate; + } + resetEditor(); + dash3.link.classList.add('active'); + dash1.updateSkill(); + }, newSkill); + var delnode = ui.create.div('.menubutton.large.new_card_delete', '取消', editnode.parentNode, function () { + if (this.innerHTML == '删除') { + this.button.remove(); + var name = this.button.link; + delete dash3.content.pack.skill[name]; + delete dash3.content.pack.translate[name]; + delete dash3.content.pack.translate[name + '_info']; + dash3.link.classList.add('active'); + if (get.is.empty(dash3.content.pack.skill)) { + dash1.selectname.value = dash1.selectname.childNodes[1].value; + } + dash1.selectname.onchange.call(dash1.selectname); + dash1.updateSkill(); + resetEditor(); + } + else if (page.fromchar == 'add') { + ui.create.templayer(); + page.hide(); + dash1.show(); + delete page.fromchar; + setTimeout(resetEditor, 600); + } + else { + resetEditor(); + } + }); + + page.content = { + pack: { + skill: {}, + translate: {} + }, + audio: {} + }; + return page; + }()); + var dash4 = (function () { + var page = ui.create.div('.hidden.menu-buttons'); + ui.create.div('.config.more.margin-bottom', '
      返回', page, function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + }); + page.reset = function (name) { + page.content = {}; + if (lib.extensionPack[name]) { + for (var i in dashes) { + dashes[i].node.code = ''; + } + for (var i in lib.extensionPack[name].code) { + switch (typeof lib.extensionPack[name].code[i]) { + case 'function': page.content[i] = lib.extensionPack[name].code[i].toString(); break; + case 'object': page.content[i] = i + '=' + get.stringify(lib.extensionPack[name].code[i]); break; + } + } + for (var i in page.content) { + dashes[i].node.code = page.content[i] || ''; + } + } + else { + dashes.content.node.code = 'function(config,pack){\n \n}\n\n/*\n函数执行时机为游戏数据加载之后、界面加载之前\n参数1扩展选项(见选项代码);参数2为扩展定义的武将、卡牌和技能等(可在此函数中修改)\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + dashes.precontent.node.code = 'function(){\n \n}\n\n/*\n函数执行时机为游戏数据加载之前,且不受禁用扩展的限制\n除添加模式外请慎用\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + dashes.config.node.code = 'config={\n \n}\n\n/*\n示例:\nconfig={\n switcher_example:{\n name:"示例列表选项",\n init:"3",\n item:{"1":"一","2":"二","3":"三"}\n },\n toggle_example:{\n name:"示例开关选项",\n init:true\n }\n}\n此例中传入的主代码函数的默认参数为{switcher_example:"3",toggle_example:true}\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + dashes.help.node.code = 'help={\n \n}\n\ns/*\n示例:\nhelp={\n "帮助条目":"
      • 列表1-条目1
      • 列表1-条目2
      1. 列表2-条目1
      2. 列表2-条目2"\n}\n帮助内容将显示在菜单-选项-帮助中\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + } + }; + var dashes = {}; + var createCode = function (str1, str2, sub, func, link, str) { + var dash = ui.create.div('.menubutton.large.dashboard'); + dashes[link] = dash; + sub.appendChild(dash); + dash.listen(func); + dash.link = link; + ui.create.div('', str1, dash); + ui.create.div('', str2, dash); + var container = ui.create.div('.popup-container.editor'); + var saveInput = function () { + var code; + if (container.editor) { + code = container.editor.getValue(); + } + else if (container.textarea) { + code = container.textarea.value; + } + try { + if (link == 'content' || link == 'precontent') { + var func = null; + eval('func=' + code); + if (typeof func != 'function') { + throw ('err'); + } + } + else if (link == 'config') { + var config = null; + eval(code); + if (config == null || typeof config != 'object') { + throw ('err'); + } + } + else if (link == 'help') { + var help = null; + eval(code); + if (help == null || typeof help != 'object') { + throw ('err'); + } + } + } + catch (e) { + if (e == 'err') { + alert('代码格式有错误,请对比示例代码仔细检查'); + } + else { + var tip = lib.getErrorTip(e) || ''; + alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + } + window.focus(); + if (container.editor) { + container.editor.focus(); + } + else if (container.textarea) { + container.textarea.focus(); + } + return; + } + dash4.link.classList.add('active'); + ui.window.classList.remove('shortcutpaused'); + ui.window.classList.remove('systempaused'); + container.delete(); + container.code = code; + page.content[link] = code; + delete window.saveNonameInput; + }; + var editor = ui.create.editor(container, saveInput); + container.code = str; + dash.editor = editor; + dash.node = container; + dash.saveInput = saveInput; + page.content[link] = str; + }; + var clickCode = function () { + var node = this.node; + ui.window.classList.add('shortcutpaused'); + ui.window.classList.add('systempaused'); + window.saveNonameInput = this.saveInput; + if (node.aced) { + ui.window.appendChild(node); + node.editor.setValue(node.code, 1); + } + else if (lib.device == 'ios') { + ui.window.appendChild(node); + if (!node.textarea) { + var textarea = document.createElement('textarea'); + this.editor.appendChild(textarea); + node.textarea = textarea; + lib.setScroll(textarea); + } + node.textarea.value = node.code; + } + else { + if (!window.CodeMirror) { + import('../../game/codemirror.js').then(() => { + lib.codeMirrorReady(node, editor); + }); + lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); + } + else { + lib.codeMirrorReady(node, this.editor); + } + } + }; + page.content = {}; + createCode('主', '主代码', page, clickCode, 'content', 'function(config,pack){\n \n}\n\n/*\n函数执行时机为游戏数据加载之后、界面加载之前\n参数1扩展选项(见选项代码);参数2为扩展定义的武将、卡牌和技能等(可在此函数中修改)\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); + createCode('启', '启动代码', page, clickCode, 'precontent', 'function(){\n \n}\n\n/*\n函数执行时机为游戏数据加载之前,且不受禁用扩展的限制\n除添加模式外请慎用\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); + createCode('选', '选项代码', page, clickCode, 'config', 'config={\n \n}\n\n/*\n示例:\nconfig={\n switcher_example:{\n name:"示例列表选项",\n init:"3",\n item:{"1":"一","2":"二","3":"三"}\n },\n toggle_example:{\n name:"示例开关选项",\n init:true\n }\n}\n此例中传入的主代码函数的默认参数为{switcher_example:"3",toggle_example:true}\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); + createCode('帮', '帮助代码', page, clickCode, 'help', 'help={\n \n}\n\n/*\n示例:\nhelp={\n "帮助条目":"
        • 列表1-条目1
        • 列表1-条目2
        1. 列表2-条目1
        2. 列表2-条目2"\n}\n帮助内容将显示在菜单-选项-帮助中\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); + + return page; + }()); + createDash('将', '编辑武将', dash1); + createDash('卡', '编辑卡牌', dash2); + createDash('技', '编辑技能', dash3); + createDash('码', '编辑代码', dash4); + }; + if (!get.config('menu_loadondemand')) node._initLink(); + }()); + (function () { + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', '获取扩展', start.firstChild, clickMode); + node.mode = 'get'; + var _thisUpdate = false; + node.update = function () { + _thisUpdate = true; + }; + node._initLink = function () { + node.link = page; + page.listen(function () { + if (!page.currenttimeout) { + var active = page.querySelector('.videonode.current'); + if (active) { + active.classList.remove('current'); + } + } + }); + var importextensionexpanded = false; + page.style.paddingBottom = '10px'; + var importExtension; + var extensionNode = ui.create.div('.config.more', '导入扩展
          >
          ', page, function () { + if (importextensionexpanded) { + this.classList.remove('on'); + importExtension.style.display = 'none'; + } + else { + this.classList.add('on'); + importExtension.style.display = ''; + } + importextensionexpanded = !importextensionexpanded; + }); + importExtension = ui.create.div('.new_character.export.import', page); + importExtension.style.marginLeft = '5px'; + importExtension.style.marginTop = '5px'; + importExtension.style.marginBottom = '5px'; + importExtension.style.display = 'none'; + importExtension.style.width = '100%'; + importExtension.style.textAlign = 'left'; + ui.create.div('', '', importExtension); + ui.create.div('.config', '修改下载地址', page, function () { + alert('您可以在“设置→通用→获取扩展地址”中,修改下载扩展时所采用的地址。'); + }); + + var extensionURL; + var source = lib.config.extension_sources, index = lib.config.extension_source; + if (source && source[index]) extensionURL = source[index]; + else extensionURL = lib.updateURL.replace(/noname/g, 'noname-extension') + '/master/'; + + var reloadnode = ui.create.div('.config.toggle.pointerdiv', '重新启动', page, game.reload); + reloadnode.style.display = 'none'; + var placeholder = ui.create.div('.config.toggle', page); + placeholder.style.height = 0; + placeholder.style.marginTop = '5px'; + + importExtension.firstChild.lastChild.onclick = function () { + const fileToLoad = this.previousSibling.files[0]; + if (!fileToLoad) return; + new Promise((resolve, reject) => { + const fileReader = new FileReader(); + fileReader.onerror = reject; + fileReader.onload = resolve; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + }).then(progressEvent => { + if (game.importExtension(progressEvent.target.result, () => { + extensionNode.innerHTML = '导入成功,3秒后将重启'; + new Promise(resolve => setTimeout(resolve, 1000)).then(() => { + extensionNode.innerHTML = '导入成功,2秒后将重启'; + return new Promise(resolve => setTimeout(resolve, 1000)); + }).then(() => { + extensionNode.innerHTML = '导入成功,1秒后将重启'; + return new Promise(resolve => setTimeout(resolve, 1000)); + }).then(game.reload); + }) !== false) importExtension.style.display = 'none'; + }); + }; + + var clickExtension = function () { + var active = this.parentNode.querySelector('.videonode.current'); + if (active && active != this) { + active.classList.remove('current'); + } + this.classList.add('current'); + clearTimeout(page.currenttimeout); + page.currenttimeout = setTimeout(function () { + delete page.currenttimeout; + }, 200); + }; + var downloadExtension = function (e) { + if ((this.innerHTML != '下载扩展' && this.innerHTML != '更新扩展') || !window.JSZip) return; + this.classList.remove('update'); + if (e) { + e.stopPropagation(); + } + node.updated = true; + var that = this; + var list = []; + var size = parseFloat(this.info.size) || 0; + if (size) { + if (this.info.size.includes('MB')) { + size *= 1024 * 1024; + } + else if (this.info.size.includes('KB')) { + size *= 1024; + } + } + + this.innerHTML = '正在下载
          正在下载
          '; + this.classList.add('nopointer'); + this.classList.add('button-downloading'); + var progress = ui.create.div('.button-progress', this); + ui.create.div(progress); + var url = extensionURL + this.info.name + '.zip'; + var onprogress = function (byte, total) { + if (total) { + size = total; + } + if (byte == -1) { + byte = size; + } + progress.firstChild.style.width = Math.round(100 * byte / size) + '%'; + }; + var files = this.info.files || []; + for (var i = 0; i < files.length; i++) { + files[i] = 'extension/' + that.info.name + '/' + files[i]; + } + game.checkFileList(files, function () { + files.unshift('extension/' + that.info.name + '/extension.js'); + for (var i = 0; i < files.length; i++) { + files[i] = extensionURL + that.info.name + '/' + files[i].slice(10 + that.info.name.length + 1); + } + var n1 = 0, n2 = files.length; + game.multiDownload(files, function () { + n1++; + onprogress(n1, n2); + }, function (e) { + game.print('下载失败:' + e.source); + }, function () { + onprogress(-1); + _status.importingExtension = true; + window.game = game; + lib.init.js(lib.assetURL + 'extension/' + that.info.name, 'extension', function () { + if (!lib.config.dev) delete window.game; + if (game.importedPack) { + var extname = game.importedPack.name; + if (lib.config.extensions.includes(extname)) { + game.removeExtension(extname, true); + } + lib.config.extensions.add(extname); + game.saveConfig('extensions', lib.config.extensions); + game.saveConfig('extension_' + extname + '_enable', true); + game.saveConfig('extension_' + extname + '_version', that.info.version); + for (var i in game.importedPack.config) { + if (game.importedPack.config[i] && 'init' in game.importedPack.config[i]) { + game.saveConfig('extension_' + extname + '_' + i, game.importedPack.config[i].init); + } + } + reloadnode.style.display = ''; + that.childNodes[0].innerHTML = '安装成功'; + that.childNodes[1].innerHTML = '安装成功'; + that.classList.remove('active'); + that.classList.remove('highlight'); + delete game.importedPack; + } + else { + that.innerHTML = '安装失败'; + that.classList.add('nopointer'); + } + _status.importingExtension = false; + }, function () { + that.innerHTML = '下载失败'; + that.classList.add('nopointer'); + _status.importingExtension = false; + }); + }, function (current) { + return 'extension/' + current.slice(extensionURL.length); + }); + }); + }; + + node.update = function () { + if (this.updated) return; + if (!window.JSZip) { + lib.init.js(lib.assetURL + 'game', 'jszip'); + } + var toremove = []; + for (var i = 0; i < page.childElementCount; i++) { + if (page.childNodes[i].classList.contains('menubutton') || page.childNodes[i].classList.contains('loading')) { + toremove.push(page.childNodes[i]); + } + } + for (var i = 0; i < toremove.length; i++) { + toremove[i].remove(); + } + + var loading = ui.create.div('.loading.config.toggle', '载入中...', page); + var loaded = function () { + var list = []; + var extension = window.extension; + for (var i in extension) { + extension[i].name = i; + list.push(extension[i]); + } + list.randomSort(); + delete window.extension; + loading.style.display = 'none'; + for (var i = 0; i < list.length; i++) { + var node = ui.create.div('.videonode.menubutton.extension.large', page, clickExtension); + ui.create.div('.caption', list[i].name, node); + ui.create.div('.text.author', '作者:' + list[i].author + '(' + list[i].size + ')', node); + ui.create.div('.text', '更新日期:' + list[i].date, node); + ui.create.div('.text', list[i].intro, node); + var download = ui.create.div('.menubutton.text.active', '下载扩展', node.firstChild, { 'zIndex': '5' }); + if (game.download) { + if (list[i].netdisk) { + var linknode = ui.create.div('.text', node); + ui.create.node('span.hrefnode', '网盘链接', function () { + game.open(this.link); + }, linknode).link = list[i].netdisk; + if (list[i].forum) { + ui.create.node('span', linknode).style.marginRight = '10px'; + ui.create.node('span.hrefnode', '参与讨论', function () { + game.open(this.link); + }, linknode).link = list[i].forum; + } + } + else if (list[i].forum) { + var linknode = ui.create.div('.text', node); + ui.create.node('span.hrefnode', '参与讨论', function () { + game.open(this.link); + }, linknode).link = list[i].forum; + } + download.listen(downloadExtension); + if (lib.config.extensions.includes(list[i].name)) { + download.classList.remove('active'); + if (lib.extensionPack[list[i].name] && lib.extensionPack[list[i].name].version == list[i].version) { + download.classList.add('transparent2'); + download.classList.remove('active'); + download.innerHTML = '已安装'; + } + else if (lib.config['extension_' + list[i].name + '_version'] != list[i].version) { + download.innerHTML = '更新扩展'; + download.classList.add('highlight'); + download.classList.add('update'); + } + else { + download.classList.add('transparent2'); + download.classList.remove('active'); + download.innerHTML = '已安装'; + } + } + download.info = list[i]; + } + else { + if (list[i].forum) { + var linknode = ui.create.div('.text', node); + ui.create.node('span', linknode); + ui.create.node('span.hrefnode', '参与讨论', function () { + game.open(this.link); + }, linknode).link = list[i].forum; + } + download.listen(function () { + game.open(this.link); + }); + download.link = list[i].netdisk; + } + } + }; + window.extension = {}; + fetch(`${extensionURL}catalog.js`, { + referrerPolicy: 'no-referrer' + }).then(response => response.text()).then(eval).then(loaded).catch(reason => { + console.log(reason); + delete window.extension; + loading.innerHTML = '连接失败:' + (reason instanceof Error ? reason.message : String(reason)); + }); + }; + if (_thisUpdate) node.update(); + }; + if (!get.config('menu_loadondemand')) node._initLink(); + }()); + var active = start.firstChild.querySelector('.active'); + if (!active) { + active = start.firstChild.firstChild; + active.classList.add('active'); + } + if (!active.link) active._initLink(); + rightPane.appendChild(active.link); + updateNodes(); + }()); + + (function () { + if (connectMenu) return; + var start = menuxpages.shift(); + var rightPane = start.lastChild; + var cheatButton = ui.create.div('.menubutton.round.highlight', '作', start); + cheatButton.style.display = 'none'; + var runButton = ui.create.div('.menubutton.round.highlight', '执', start); + runButton.style.display = 'none'; + var clearButton = ui.create.div('.menubutton.round.highlight', '清', start); + clearButton.style.display = 'none'; + clearButton.style.left = '275px'; + var playButton = ui.create.div('.menubutton.round.highlight.hidden', '播', start); + playButton.style.display = 'none'; + playButton.style.left = '215px'; + playButton.style.transition = 'opacity 0.3s'; + var deleteButton = ui.create.div('.menubutton.round.highlight.hidden', '删', start); + deleteButton.style.display = 'none'; + deleteButton.style.left = '275px'; + deleteButton.style.transition = 'opacity 0.3s'; + var saveButton = ui.create.div('.menubutton.round.highlight.hidden', '存', start); + saveButton.style.display = 'none'; + saveButton.style.transition = 'opacity 0.3s'; + + + var clickMode = function () { + if (this.classList.contains('off')) return; + var active = this.parentNode.querySelector('.active'); + if (active === this) { + return; + } + if (active) { + active.classList.remove('active'); + active.link.remove(); + } + active = this; + this.classList.add('active'); + if (this.link) rightPane.appendChild(this.link); + else { + this._initLink(); + rightPane.appendChild(this.link); + } + if (this.type == 'cheat') { + cheatButton.style.display = ''; + } + else { + cheatButton.style.display = 'none'; + } + if (this.type == 'cmd') { + runButton.style.display = ''; + clearButton.style.display = ''; + } + else { + runButton.style.display = 'none'; + clearButton.style.display = 'none'; + } + if (this.type == 'video') { + playButton.style.display = ''; + saveButton.style.display = ''; + deleteButton.style.display = ''; + } + else { + playButton.style.display = 'none'; + saveButton.style.display = 'none'; + deleteButton.style.display = 'none'; + } + }; + + ui.click.consoleMenu = function () { + ui.click.menuTab('其它'); + clickMode.call(ui.commandnode); + }; + //更新菜单有本体函数赋值,就不要懒加载了 + (function () { + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', '更新', start.firstChild, clickMode); + node.link = page; + page.classList.add('menu-help'); + var ul = document.createElement('ul'); + var li1 = document.createElement('li'); + var li2 = document.createElement('li'); + var li3 = document.createElement('li'); + const trimURL = url => { + const updateURLS = lib.updateURLS; + for (const key in updateURLS) { + const updateURL = updateURLS[key]; + if (url == updateURL) return lib.configMenu.general.config.update_link.item[key]; + } + let index = url.indexOf('://'); + if (index != -1) url = url.slice(index + 3); + index = url.indexOf('/'); + if (index != -1) url = url.slice(0, index); + if (url.length > 15) { + const list = url.split('.'); + if (list.length > 1) list.shift(); + url = list.join('.'); + } + if (url.length > 15) { + const list = url.split('.'); + if (list.length > 1) list.pop(); + url = list.join('.'); + } + return url; + }; + li1.innerHTML = '游戏版本:' + lib.version + '

          '; + li2.innerHTML = '素材版本:' + (lib.config.asset_version || '无') + '

          '; + li3.innerHTML = '更新地址:' + trimURL(lib.config.updateURL || lib.updateURL) + '

          '; + li3.style.whiteSpace = 'nowrap'; + li3.style.display = 'none';// coding + + var button1, button2, button3, button4, button5; + + game.checkForUpdate = function (forcecheck, dev) { + if (!dev && button1.disabled) { + return; + } + else if (dev && button3.disabled) { + return; + } + else if (!game.download) { + alert('此版本不支持游戏内更新,请手动更新'); + return; + } + else { + if (dev) { + button3.innerHTML = '正在检查更新'; + } + else { + button1.innerHTML = '正在检查更新'; + } + button3.disabled = true; + button1.disabled = true; + + var goupdate = function (files, update) { + lib.version = update.version; + if (update.dev && !lib.config.debug) { + dev = 'nodev'; + } + lib.init.req('game/source.js', function () { + try { + eval(this.responseText); + if (!window.noname_source_list) { + throw ('err'); + } + } + catch (e) { + alert('更新地址有误'); + console.log(e); + return; + } + + var updates = window.noname_source_list; + delete window.noname_source_list; + if (Array.isArray(files)) { + files.add('game/update.js'); + var files2 = []; + for (var i = 0; i < files.length; i++) { + var str = files[i].indexOf('*'); + if (str != -1) { + str = files[i].slice(0, str); + files.splice(i--, 1); + for (var j = 0; j < updates.length; j++) { + if (updates[j].startsWith(str)) { + files2.push(updates[j]); + } + } + } + } + updates = files.concat(files2); + } + for (var i = 0; i < updates.length; i++) { + if (updates[i].startsWith('theme/') && !updates[i].includes('.css')) { + updates.splice(i--, 1); + } + else if (updates[i].startsWith('node_modules/') && !update.node) { + updates.splice(i--, 1); + } + } + + if (!ui.arena.classList.contains('menupaused')) { + ui.click.configMenu(); + ui.click.menuTab('其它'); + } + var p = button1.parentNode; + button1.remove(); + button3.remove(); + var span = document.createElement('span'); + var n1 = 0; + var n2 = updates.length; + span.innerHTML = '正在下载文件(' + n1 + '/' + n2 + ')'; + p.appendChild(span); + var finish = function () { + span.innerHTML = '游戏更新完毕(' + n1 + '/' + n2 + ')'; + p.appendChild(document.createElement('br')); + var button = document.createElement('button'); + button.innerHTML = '重新启动'; + button.onclick = game.reload; + button.style.marginTop = '8px'; + p.appendChild(button); + }; + game.multiDownload(updates, function () { + n1++; + span.innerHTML = '正在下载文件(' + n1 + '/' + n2 + ')'; + }, function (e) { + game.print('下载失败:' + e.source); + }, function () { + setTimeout(finish, 500); + }, null, dev); + }, function () { + alert('更新地址有误'); + }, true); + }; + + lib.init.req('game/update.js', function () { + try { + eval(this.responseText); + if (!window.noname_update) { + throw ('err'); + } + } + catch (e) { + alert('更新地址有误'); + console.log(e); + return; + } + + var update = window.noname_update; + delete window.noname_update; + if (forcecheck === false) { + if (update.version == lib.config.check_version) { + return; + } + } + game.saveConfig('check_version', update.version); + var goon = true; + if (!dev) { + if (update.version.includes('beta') || update.version == lib.version) { + goon = false; + } + } + if (goon) { + var files = null; + var version = lib.version; + if (Array.isArray(update.dev) && dev) { + files = update.dev; + } + else if (Array.isArray(update.files) && update.update && !dev) { + var version1 = version.split('.'); + var version2 = update.update.split('.'); + for (var i = 0; i < version1.length && i < version2.length; i++) { + if (version2[i] > version1[i]) { + files = false; break; + } + else if (version1[i] > version2[i]) { + files = update.files.slice(0); break; + } + } + if (files === null) { + if (version1.length >= version2.length) { + files = update.files.slice(0); + } + } + } + var str; + if (dev) { + str = '开发版仅供测试使用,可能存在风险,是否确定更新?'; + } + else { + str = '有新版本' + update.version + '可用,是否下载?'; + } + if (navigator.notification && navigator.notification.confirm) { + var str2; + if (dev) { + str2 = str; + str = '更新到开发版'; + } + else { + str2 = update.changeLog[0]; + for (var i = 1; i < update.changeLog.length; i++) { + if (update.changeLog[i].indexOf('://') == -1) { + str2 += ';' + update.changeLog[i]; + } + } + } + navigator.notification.confirm( + str2, + function (index) { + if (index == 1) { + goupdate(files, update); + } + else { + button1.disabled = false; + button1.innerHTML = '检查游戏更新'; + button3.disabled = false; + button3.innerHTML = '更新到开发版'; + } + }, + str, + ['确定', '取消'] + ); + } + else { + if (confirm(str)) { + goupdate(files, update); + } + else { + button1.disabled = false; + button1.innerHTML = '检查游戏更新'; + button3.disabled = false; + button3.innerHTML = '更新到开发版'; + } + } + } + else { + alert('当前版本已是最新'); + button1.disabled = false; + button1.innerHTML = '检查游戏更新'; + button3.disabled = false; + button3.innerHTML = '更新到开发版'; + } + }, function () { + if (forcecheck === false) { + return; + } + alert('连接失败'); + button1.disabled = false; + button1.innerHTML = '检查游戏更新'; + button3.disabled = false; + button3.innerHTML = '更新到开发版'; + }, true); + } + }; + game.checkForAssetUpdate = function (type) { + if (button2.disabled) { + return; + } + else if (game.download) { + button2.innerHTML = '正在检查更新'; + button2.disabled = true; + lib.init.req('game/asset.js', function () { + try { + eval(this.responseText); + if (!window.noname_asset_list || !window.noname_skin_list) { + throw ('err'); + } + } + catch (e) { + alert('更新地址有误'); + console.log(e); + return; + } + + var updates = window.noname_asset_list; + delete window.noname_asset_list; + var skins = window.noname_skin_list; + delete window.noname_skin_list; + var asset_version = updates.shift(); + + var skipcharacter = [], skipcard = ['tiesuo_mark', 'shield']; + if (!lib.config.asset_full) { + for (var i = 0; i < lib.config.all.sgscharacters.length; i++) { + var pack = lib.characterPack[lib.config.all.sgscharacters[i]]; + for (var j in pack) { + skipcharacter.add(j); + } + } + for (var i = 0; i < lib.config.all.sgscards.length; i++) { + var pack = lib.cardPack[lib.config.all.sgscards[i]]; + if (pack) { + skipcard = skipcard.concat(pack); + } + } + } + for (var i = 0; i < updates.length; i++) { + switch (updates[i].slice(0, 5)) { + case 'image': { + if (!lib.config.asset_full) { + if (!lib.config.asset_image) { + updates.splice(i--, 1); + } + else { + if (updates[i].startsWith('image/character')) { + if (updates[i].indexOf('jun_') != 16 && updates[i].indexOf('gz_') != 16 && !skipcharacter.includes(updates[i].slice(16, updates[i].lastIndexOf('.')))) { + updates.splice(i--, 1); + } + } + else if (updates[i].startsWith('image/card')) { + let cardname = updates[i].slice(11, updates[i].lastIndexOf('.')); + if (lib.card[cardname] && !skipcard.includes(cardname)) { + updates.splice(i--, 1); + } + } + else if (updates[i].startsWith('image/mode/stone')) { + updates.splice(i--, 1); + } + } + } + break; + } + case 'audio': { + if (!lib.config.asset_audio) { + updates.splice(i--, 1); + } + break; + } + case 'font/': { + if (!lib.config.asset_font) { + updates.splice(i--, 1); + } + } + } + } + if (lib.config.asset_skin) { + for (var i in skins) { + for (var j = 1; j <= skins[i]; j++) { + updates.push('image/skin/' + i + '/' + j + '.jpg'); + } + } + } + if (!ui.arena.classList.contains('menupaused')) { + ui.click.configMenu(); + ui.click.menuTab('其它'); + } + + var proceed = function () { + if (updates.length == 0) { + game.print(updates); + game.saveConfig('asset_version', asset_version); + alert('素材已是最新'); + button2.disabled = false; + button2.innerHTML = '检查素材更新'; + return; + } + var p = button2.parentNode; + button2.remove(); + var span = document.createElement('span'); + span.style.whiteSpace = 'nowrap'; + var n1 = 0; + var n2 = updates.length; + span.innerHTML = '正在下载素材(' + n1 + '/' + n2 + ')'; + span1.remove(); + span2.remove(); + span2_check.remove(); + span3.remove(); + span3_check.remove(); + span4.remove(); + span4_check.remove(); + span5.remove(); + span5_check.remove(); + span6.remove(); + span6_check.remove(); + span2_br.remove(); + span3_br.remove(); + span4_br.remove(); + span5_br.remove(); + span6_br.remove(); + p.appendChild(span); + + var br6 = ui.create.node('br'); + var span7 = ui.create.div('.hrefnode', '详细信息'); + span7.style.marginTop = '6px'; + span7.listen(ui.click.consoleMenu); + p.appendChild(br6); + p.appendChild(span7); + + var finish = function () { + if (n1 == n2) { + game.saveConfig('asset_version', asset_version); + } + span.innerHTML = '素材更新完毕(' + n1 + '/' + n2 + ')'; + p.appendChild(document.createElement('br')); + var button = document.createElement('button'); + button.innerHTML = '重新启动'; + button.onclick = game.reload; + button.style.marginTop = '8px'; + p.appendChild(button); + }; + game.multiDownload(updates, function () { + n1++; + span.innerHTML = '正在下载素材(' + n1 + '/' + n2 + ')'; + }, function (e) { + game.print('下载失败:' + e.source); + }, function () { + setTimeout(finish, 500); + }); + }; + game.checkFileList(updates, proceed); + }, function () { + alert('连接失败'); + button2.disabled = false; + button2.innerHTML = '检查素材更新'; + }, true); + } + else { + alert('此版本不支持游戏内更新素材,请手动更新'); + } + }; + + button1 = document.createElement('button'); + button1.innerHTML = '检查游戏更新'; + button1.onclick = game.checkForUpdate; + li1.lastChild.appendChild(button1); + + button3 = document.createElement('button'); + button3.innerHTML = '更新到开发版'; + button3.style.marginLeft = '5px'; + button3.onclick = function () { + game.checkForUpdate(null, true); + }; + // if(lib.config.dev){ + // li1.lastChild.appendChild(button3); + // } + + (function () { + var updatep1 = li1.querySelector('p'); + var updatep2 = li2; + var updatep3 = li3; + var updatep4 = node; + var updatepx = ui.create.node('p'); + li1.appendChild(updatepx); + updatepx.style.display = 'none'; + updatepx.style.whiteSpace = 'nowrap'; + updatepx.style.marginTop = '8px'; + var buttonx = ui.create.node('button', '访问项目主页', function () { + window.open('https://github.com/libccy/noname'); + }); + updatepx.appendChild(buttonx); + ui.updateUpdate = function () { + if (!game.download) { + updatep1.style.display = 'none'; + updatep2.style.display = 'none'; + updatep3.style.display = 'none'; + updatepx.style.display = ''; + updatep4.innerHTML = '关于'; + } + else { + updatep1.style.display = ''; + updatep2.style.display = ''; + updatep3.style.display = 'none'; // coding + updatepx.style.display = 'none'; + updatep4.innerHTML = '更新'; + } + }; + ui.updateUpdate(); + }()); + + button4 = document.createElement('button'); + button4.innerHTML = '设置更新地址'; + button4.onclick = function () { + game.prompt('设置更新地址', function (str) { + if (str) { + game.saveConfig('updateURL', str); + li3.querySelector('span').innerHTML = trimURL(str); + button5.style.display = ''; + button6.style.display = 'none'; + } + }); + }; + // li3.lastChild.appendChild(button4); + + var button6 = document.createElement('button'); + button6.innerHTML = '设为备用镜像'; + button6.style.display = 'none';// coding + // button6.style.marginLeft='5px'; + button6.onclick = function () { + game.saveConfig('updateURL', lib.mirrorURL); + button5.style.display = ''; + button6.style.display = 'none'; + li3.querySelector('span').innerHTML = trimURL(lib.mirrorURL); + }; + li3.lastChild.appendChild(button6); + + button5 = document.createElement('button'); + button5.innerHTML = '设为默认镜像'; + // button5.style.marginLeft='5px'; + button5.onclick = function () { + game.saveConfig('updateURL'); + button5.style.display = 'none'; + button6.style.display = ''; + li3.querySelector('span').innerHTML = trimURL(lib.updateURL); + }; + li3.lastChild.appendChild(button5); + if (!lib.config.updateURL) { + button5.style.display = 'none'; + } + else { + button6.style.display = 'none'; + } + + button2 = document.createElement('button'); + button2.innerHTML = '检查素材更新'; + button2.onclick = game.checkForAssetUpdate; + li2.lastChild.appendChild(button2); + + var span1 = ui.create.div('.config.more', '选项
          >
          '); + span1.style.fontSize = 'small'; + span1.style.display = 'inline'; + span1.toggle = function () { + if (!this.classList.toggle('on')) { + game.saveConfig('asset_toggle_off', true); + span2.style.display = 'none'; + span2_br.style.display = 'none'; + span2_check.style.display = 'none'; + span3.style.display = 'none'; + span3_br.style.display = 'none'; + span3_check.style.display = 'none'; + span4.style.display = 'none'; + span4_br.style.display = 'none'; + span4_check.style.display = 'none'; + span5.style.display = 'none'; + span5_br.style.display = 'none'; + span5_check.style.display = 'none'; + span6.style.display = 'none'; + span6_br.style.display = 'none'; + span6_check.style.display = 'none'; + } + else { + game.saveConfig('asset_toggle_off'); + span2.style.display = ''; + span2_br.style.display = ''; + span2_check.style.display = ''; + span3.style.display = ''; + span3_br.style.display = ''; + span3_check.style.display = ''; + span4.style.display = ''; + span4_br.style.display = ''; + span4_check.style.display = ''; + span5.style.display = ''; + span5_br.style.display = ''; + span5_check.style.display = ''; + span6.style.display = ''; + span6_br.style.display = ''; + span6_check.style.display = ''; + } + }; + span1.listen(span1.toggle); + li2.lastChild.appendChild(span1); + + var span6_br = ui.create.node('br'); + li2.lastChild.appendChild(span6_br); + + var span5 = ui.create.div('', '图片素材(精简,126MB)'); + span5.style.fontSize = 'small'; + span5.style.lineHeight = '16px'; + var span5_check = document.createElement('input'); + span5_check.type = 'checkbox'; + span5_check.style.marginLeft = '5px'; + if (lib.config.asset_image) { + span5_check.checked = true; + } + span5_check.onchange = function () { + game.saveConfig('asset_image', this.checked); + }; + var span2_br = ui.create.node('br'); + + var span4 = ui.create.div('', '字体素材(48MB)'); + span4.style.fontSize = 'small'; + span4.style.lineHeight = '16px'; + li2.lastChild.appendChild(span4); + var span4_check = document.createElement('input'); + span4_check.type = 'checkbox'; + span4_check.style.marginLeft = '5px'; + if (lib.config.asset_font) { + span4_check.checked = true; + } + span4_check.onchange = function () { + game.saveConfig('asset_font', this.checked); + }; + li2.lastChild.appendChild(span4_check); + var span3_br = ui.create.node('br'); + li2.lastChild.appendChild(span3_br); + + var span3 = ui.create.div('', '音效素材(125MB)'); + span3.style.fontSize = 'small'; + span3.style.lineHeight = '16px'; + li2.lastChild.appendChild(span3); + var span3_check = document.createElement('input'); + span3_check.type = 'checkbox'; + span3_check.style.marginLeft = '5px'; + if (lib.config.asset_audio) { + span3_check.checked = true; + } + span3_check.onchange = function () { + game.saveConfig('asset_audio', this.checked); + }; + li2.lastChild.appendChild(span3_check); + var span4_br = ui.create.node('br'); + li2.lastChild.appendChild(span4_br); + + var span2 = ui.create.div('', '皮肤素材(351MB)'); + span2.style.fontSize = 'small'; + span2.style.lineHeight = '16px'; + li2.lastChild.appendChild(span2); + var span2_check = document.createElement('input'); + span2_check.type = 'checkbox'; + span2_check.style.marginLeft = '5px'; + if (lib.config.asset_skin) { + span2_check.checked = true; + } + span2_check.onchange = function () { + game.saveConfig('asset_skin', this.checked); + }; + li2.lastChild.appendChild(span2_check); + var span5_br = ui.create.node('br'); + li2.lastChild.appendChild(span5_br); + + + li2.lastChild.appendChild(span5); + li2.lastChild.appendChild(span5_check); + li2.lastChild.appendChild(span2_br); + + var span6 = ui.create.div('', '图片素材(完整,203MB)'); + span6.style.fontSize = 'small'; + span6.style.lineHeight = '16px'; + li2.lastChild.appendChild(span6); + var span6_check = document.createElement('input'); + span6_check.type = 'checkbox'; + span6_check.style.marginLeft = '5px'; + if (lib.config.asset_full) { + span6_check.checked = true; + } + span6_check.onchange = function () { + game.saveConfig('asset_full', this.checked); + }; + li2.lastChild.appendChild(span6_check); + + span2.style.display = 'none'; + span2_br.style.display = 'none'; + span2_check.style.display = 'none'; + span3.style.display = 'none'; + span3_br.style.display = 'none'; + span3_check.style.display = 'none'; + span4.style.display = 'none'; + span4_br.style.display = 'none'; + span4_check.style.display = 'none'; + span5.style.display = 'none'; + span5_br.style.display = 'none'; + span5_check.style.display = 'none'; + span6.style.display = 'none'; + span6_br.style.display = 'none'; + span6_check.style.display = 'none'; + + ul.appendChild(li1); + ul.appendChild(li2); + ul.appendChild(li3); + page.appendChild(ul); + + + if (!lib.config.asset_toggle_off) { + span1.toggle(); + } + }()); + (function () { + var norow2 = function () { + var node = currentrow1; + if (!node) return false; + return node.innerHTML == '横置' || node.innerHTML == '翻面' || node.innerHTML == '换人' || node.innerHTML == '复活'; + }; + var checkCheat = function () { + if (norow2()) { + for (var i = 0; i < row2.childElementCount; i++) { + row2.childNodes[i].classList.remove('selectedx'); + row2.childNodes[i].classList.add('unselectable'); + } + } + else { + for (var i = 0; i < row2.childElementCount; i++) { + row2.childNodes[i].classList.remove('unselectable'); + } + } + if (currentrow1 && currentrow1.innerHTML == '复活') { + for (var i = 0; i < row3.childNodes.length; i++) { + if (row3.childNodes[i].dead) { + row3.childNodes[i].style.display = ''; + } + else { + row3.childNodes[i].style.display = 'none'; + row3.childNodes[i].classList.remove('glow'); + } + row3.childNodes[i].classList.remove('unselectable'); + } + } + else { + for (var i = 0; i < row3.childElementCount; i++) { + if (currentrow1 && currentrow1.innerHTML == '换人' && row3.childNodes[i].link == game.me) { + row3.childNodes[i].classList.add('unselectable'); + } + else { + row3.childNodes[i].classList.remove('unselectable'); + } + if (!row3.childNodes[i].dead) { + row3.childNodes[i].style.display = ''; + } + else { + row3.childNodes[i].style.display = 'none'; + row3.childNodes[i].classList.remove('glow'); + } + } + } + if (currentrow1 && (currentrow2 || norow2()) && row3.querySelector('.glow')) { + cheatButton.classList.add('glowing'); + return true; + } + else { + cheatButton.classList.remove('glowing'); + return false; + } + }; + cheatButton.listen(function () { + if (checkCheat()) { + var num; + if (currentrow2) { + switch (currentrow2.innerHTML) { + case '一': num = 1; break; + case '二': num = 2; break; + case '三': num = 3; break; + case '四': num = 4; break; + case '五': num = 5; break; + } + } + var targets = []; + var buttons = row3.querySelectorAll('.glow'); + for (var i = 0; i < buttons.length; i++) { + targets.push(buttons[i].link); + } + while (targets.length) { + var target = targets.shift(); + switch (currentrow1.innerHTML) { + case '伤害': target.damage(num, 'nosource'); break; + case '回复': target.recover(num, 'nosource'); break; + case '摸牌': target.draw(num); break; + case '弃牌': target.discard(target.getCards('he').randomGets(num)); break; + case '横置': target.link(); break; + case '翻面': target.turnOver(); break; + case '复活': target.revive(target.maxHp); break; + case '换人': { + if (_status.event.isMine()) { + if (!ui.auto.classList.contains('hidden')) { + setTimeout(function () { + ui.click.auto(); + setTimeout(function () { + ui.click.auto(); + game.swapPlayer(target); + }, 500); + }); + } + } + else { + game.swapPlayer(target); + } + break; + } + } + } + if (ui.coin) { + game.changeCoin(-20); + } + clickContainer.call(menuContainer); + } + }); + + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', '控制', start.firstChild, clickMode); + node.link = page; + node.type = 'cheat'; + page.classList.add('menu-sym'); + + var currentrow1 = null; + var row1 = ui.create.div('.menu-cheat', page); + var clickrow1 = function () { + if (this.classList.contains('unselectable')) return; + if (currentrow1 == this) { + this.classList.remove('selectedx'); + currentrow1 = null; + } + else { + this.classList.add('selectedx'); + if (currentrow1) { + currentrow1.classList.remove('selectedx'); + } + currentrow1 = this; + if (this.innerHTML == '换人') { + for (var i = 0; i < row3.childNodes.length; i++) { + row3.childNodes[i].classList.remove('glow'); + } + } + } + checkCheat(); + }; + var nodedamage = ui.create.div('.menubutton', '伤害', row1, clickrow1); + var noderecover = ui.create.div('.menubutton', '回复', row1, clickrow1); + var nodedraw = ui.create.div('.menubutton', '摸牌', row1, clickrow1); + var nodediscard = ui.create.div('.menubutton', '弃牌', row1, clickrow1); + var nodelink = ui.create.div('.menubutton', '横置', row1, clickrow1); + var nodeturnover = ui.create.div('.menubutton', '翻面', row1, clickrow1); + var noderevive = ui.create.div('.menubutton', '复活', row1, clickrow1); + var nodereplace = ui.create.div('.menubutton', '换人', row1, clickrow1); + if (!game.canReplaceViewpoint || !game.canReplaceViewpoint()) { + nodereplace.classList.add('unselectable'); + } + + var currentrow2 = null; + var row2 = ui.create.div('.menu-cheat', page); + var clickrow2 = function () { + if (this.classList.contains('unselectable')) return; + if (currentrow2 == this) { + this.classList.remove('selectedx'); + currentrow2 = null; + } + else { + this.classList.add('selectedx'); + if (currentrow2) { + currentrow2.classList.remove('selectedx'); + } + currentrow2 = this; + } + checkCheat(); + }; + var nodex1 = ui.create.div('.menubutton', '一', row2, clickrow2); + var nodex2 = ui.create.div('.menubutton', '二', row2, clickrow2); + var nodex3 = ui.create.div('.menubutton', '三', row2, clickrow2); + var nodex4 = ui.create.div('.menubutton', '四', row2, clickrow2); + var nodex5 = ui.create.div('.menubutton', '五', row2, clickrow2); + + var row3 = ui.create.div('.menu-buttons.leftbutton.commandbutton', page); + row3.style.marginTop = '3px'; + var clickrow3 = function () { + if (this.classList.contains('unselectable')) return; + this.classList.toggle('glow'); + if (currentrow1 && currentrow1.innerHTML == '换人' && this.classList.contains('glow')) { + if (this.link == game.me) { + this.classList.remove('glow'); + } + for (var i = 0; i < row3.childElementCount; i++) { + if (row3.childNodes[i] != this) { + row3.childNodes[i].classList.remove('glow'); + } + } + } + checkCheat(); + }; + menuUpdates.push(function () { + if (_status.video || _status.connectMode) { + node.classList.add('off'); + if (node.classList.contains('active')) { + node.classList.remove('active'); + node.link.remove(); + active = start.firstChild.firstChild; + active.classList.add('active'); + rightPane.appendChild(active.link); + } + + page.remove(); + cheatButton.remove(); + if (_status.video) node.remove(); + return; + } + var list = []; + for (var i = 0; i < game.players.length; i++) { + if (lib.character[game.players[i].name] || game.players[i].name1) { + list.push(game.players[i]); + } + } + for (var i = 0; i < game.dead.length; i++) { + if (lib.character[game.dead[i].name] || game.dead[i].name1) { + list.push(game.dead[i]); + } + } + if (list.length) { + row1.show(); + row2.show(); + row3.innerHTML = ''; + var buttons = ui.create.buttons(list, 'player', row3, true); + for (var i = 0; i < buttons.length; i++) { + buttons[i].listen(clickrow3); + if (game.dead.includes(buttons[i].link)) { + buttons[i].dead = true; + } + } + checkCheat(); + } + else { + row1.hide(); + row2.hide(); + } + if (lib.config.mode == 'identity' || lib.config.mode == 'guozhan' || lib.config.mode == 'doudizhu') { + if (game.notMe || (game.me && (game.me._trueMe || game.hasPlayer(function (current) { + return current._trueMe == game.me; + }))) || !game.phaseNumber || _status.qianlidanji) { + nodereplace.classList.add('unselectable'); + } + else if (_status.event.isMine() && ui.auto.classList.contains('hidden')) { + nodereplace.classList.add('unselectable'); + } + else { + nodereplace.classList.remove('unselectable'); + } + } + if (game.dead.length == 0) { + noderevive.classList.add('unselectable'); + } + else { + noderevive.classList.remove('unselectable'); + } + checkCheat(); + }); + }()); + (function () { + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', '命令', start.firstChild, clickMode); + ui.commandnode = node; + node.type = 'cmd'; + menuUpdates.push(function () { + if (_status.connectMode) { + node.classList.add('off'); + if (node.classList.contains('active')) { + node.classList.remove('active'); + if (node.link) node.link.remove(); + active = start.firstChild.firstChild; + active.classList.add('active'); + rightPane.appendChild(active.link); + } + } + }); + node._initLink = function () { + node.link = page; + page.classList.add('menu-sym'); + + const text = document.createElement('div'); + text.css({ + 'width': '194px', + 'height': '124px', + 'padding': '3px', + 'borderRadius': '2px', + 'boxShadow': 'rgba(0, 0, 0, 0.2) 0 0 0 1px', + 'textAlign': 'left', + 'webkitUserSelect': 'initial', + 'overflow': 'scroll', + 'position': 'absolute', + 'left': '30px', + 'top': '50px', + 'wordBreak': 'break-all' + }); + + const pre = ui.create.node('pre.fullsize', text); + text.css.call(pre, { + 'margin': '0', + 'padding': '0', + 'position': 'relative', + 'webkitUserSelect': 'text', + 'userSelect': 'text' + }); + lib.setScroll(pre); + page.appendChild(text); + + const text2 = document.createElement('input'); + text.css.call(text2, { + 'width': '200px', + 'height': '20px', + 'padding': '0', + 'position': 'absolute', + 'top': '15px', + 'left': '30px', + 'resize': 'none', + 'border': 'none', + 'borderRadius': '2px', + 'boxShadow': 'rgba(0, 0, 0, 0.2) 0 0 0 1px' + }); + + const g = {}; + const logs = []; + let logindex = -1; + let proxyWindow = Object.assign({}, window, { + _status: _status, + lib: lib, + game: game, + ui: ui, + get: get, + ai: ai, + cheat: lib.cheat + }); + Object.defineProperties(proxyWindow, { + '_status': { + configurable: false, + enumerable: true, + writable: false + }, + 'lib': { + configurable: false, + enumerable: true, + writable: false + }, + 'game': { + configurable: false, + enumerable: true, + writable: false + }, + 'ui': { + configurable: false, + enumerable: true, + writable: false + }, + 'get': { + configurable: false, + enumerable: true, + writable: false + }, + 'ai': { + configurable: false, + enumerable: true, + writable: false + }, + 'cheat': { + configurable: false, + enumerable: true, + writable: false + } + }); + proxyWindow = new Proxy(proxyWindow, { + set(target, prop, newValue) { + if (!['_status', 'lib', 'game', 'ui', 'get', 'ai', 'cheat'].includes(prop)) { + Reflect.set(window, prop, newValue); + } + return Reflect.set(target, prop, newValue); + } + }); + //使用new Function隔绝作用域,避免在控制台可以直接访问到runCommand等变量 + /** + * @type { (value:string)=>any } + */ + const fun = (new Function('window', ` + const _status=window._status; + const lib=window.lib; + const game=window.game; + const ui=window.ui; + const get=window.get; + const ai=window.ai; + const cheat=window.lib.cheat; + //使用正则匹配绝大多数的普通obj对象,避免解析成代码块。 + const reg=${/^\{([^{}]+:\s*([^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\)))(?:,\s*([^{}]+:\s*(?:[^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\))))*\}$/}; + return function(value){ + "use strict"; + return eval(reg.test(value)?('('+value+')'):value); + } + `))(proxyWindow); + const runCommand = () => { + if (text2.value && !['up', 'down'].includes(text2.value)) { + logindex = -1; + logs.unshift(text2.value); + } + if (text2.value == 'cls') { + pre.innerHTML = ''; + text2.value = ''; + } + else if (text2.value == 'up') { + if (logindex + 1 < logs.length) { + text2.value = logs[++logindex]; + } + else { + text2.value = ''; + } + } + else if (text2.value == 'down') { + if (logindex >= 0) { + logindex--; + if (logindex < 0) { + text2.value = ''; + } + else { + text2.value = logs[logindex]; + } + } + else { + text2.value = ''; + } + } + else if (text2.value.includes('无天使') && (text2.value.includes('无神佛') || text2.value.includes('无神') && text2.value.includes('无佛'))) { + game.print('密码正确!欢迎来到死后世界战线!'); + _status.keyVerified = true; + text2.value = ''; + } + else { + if (!game.observe && !game.online) { + try { + let value = text2.value.trim(); + if (value.endsWith(";")) value = value.slice(0, -1).trim(); + game.print(fun(value)); + } + catch (e) { + game.print(e); + } + } + text2.value = ''; + } + }; + text2.addEventListener('keydown', e => { + if (e.keyCode == 13) { + runCommand(); + } + else if (e.keyCode == 38) { + if (logindex + 1 < logs.length) { + text2.value = logs[++logindex]; + } + } + else if (e.keyCode == 40) { + if (logindex >= 0) { + logindex--; + if (logindex < 0) { + text2.value = ''; + } + else { + text2.value = logs[logindex]; + } + } + } + }); + page.appendChild(text2); + game.print = function () { + const args = [...arguments]; + const printResult = args.map(arg => { + if (typeof arg != 'string') { + const parse = (obj) => { + if (Array.isArray(obj)) { + return `[${obj.map(v => parse(v))}]`; + } else if (typeof obj == 'function') { + return `[Function ${obj.name}]`; + } else if (typeof obj != 'string') { + if (obj instanceof Error) { + return `${String(obj)}`; + } + return String(obj); + } else { + return `'${String(obj)}'`; + } + }; + if (typeof arg == 'function') { + let argi; + try { + argi = get.stringify(arg); + if (argi === '') argi = arg.toString(); + } catch (_) { + argi = arg.toString(); + } + return argi.replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + else if (typeof arg == 'object') { + let msg = ''; + for (const name of Object.getOwnPropertyNames(arg)) { + msg += `${name}: ${parse(arg[name])}
          `; + } + return `
          ${parse(arg)}${msg}
          `; + } else { + return parse(arg); + } + } else { + const str = String(arg); + if (!/<[a-zA-Z]+[^>]*?\/?>.*?(?=<\/[a-zA-Z]+[^>]*?>|$)/.exec(str)) return str + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + else return str; + } + }).join(' '); + pre.innerHTML += printResult + '
          '; + text.scrollTop = text.scrollHeight; + }; + if (_status.toprint) { + game.print(..._status.toprint); + delete _status.toprint; + } + runButton.listen(runCommand); + clearButton.listen(() => { + pre.innerHTML = ''; + }); + }; + if (!get.config('menu_loadondemand')) node._initLink(); + }()); + (function () { + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', '战绩', start.firstChild, clickMode); + node.type = 'rec'; + node._initLink = function () { + node.link = page; + page.style.paddingBottom = '10px'; + var reset = function () { + if (this.innerHTML == '重置') { + this.innerHTML = '确定'; + var that = this; + setTimeout(function () { + that.innerHTML = '重置'; + }, 1000); + } + else { + this.parentNode.previousSibling.remove(); + this.parentNode.remove(); + lib.config.gameRecord[this.parentNode.link] = { data: {} }; + game.saveConfig('gameRecord', lib.config.gameRecord); + } + }; + for (var i = 0; i < lib.config.all.mode.length; i++) { + if (!lib.config.gameRecord[lib.config.all.mode[i]]) continue; + if (lib.config.gameRecord[lib.config.all.mode[i]].str) { + ui.create.div('.config.indent', lib.translate[lib.config.all.mode[i]], page).style.marginBottom = '-5px'; + var item = ui.create.div('.config.indent', lib.config.gameRecord[lib.config.all.mode[i]].str + '重置', page); + item.style.height = 'auto'; + item.lastChild.addEventListener('click', reset); + item.lastChild.classList.add('pointerdiv'); + item.link = lib.config.all.mode[i]; + } + } + }; + if (!get.config('menu_loadondemand')) node._initLink(); + }()); + (function () { + if (!window.indexedDB || window.nodb) return; + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', '录像', start.firstChild, clickMode); + node.type = 'video'; + lib.videos = []; + ui.create.videoNode = (video, before) => { + lib.videos.remove(video); + lib.videos[before === true ? 'unshift' : 'push'](video); + }; + node._initLink = function () { + node.link = page; + var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); + store.openCursor().onsuccess = function (e) { + var cursor = e.target.result; + if (cursor) { + lib.videos.push(cursor.value); + cursor.continue(); + } + else { + lib.videos.sort(function (a, b) { + return parseInt(b.time) - parseInt(a.time); + }); + var clickcapt = function () { + var current = this.parentNode.querySelector('.videonode.active'); + if (current && current != this) { + current.classList.remove('active'); + } + if (this.classList.toggle('active')) { + playButton.show(); + deleteButton.show(); + saveButton.show(); + } + else { + playButton.hide(); + deleteButton.hide(); + saveButton.hide(); + } + }; + var staritem = function () { + this.parentNode.classList.toggle('starred'); + var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); + if (this.parentNode.classList.contains('starred')) { + this.parentNode.link.starred = true; + } + else { + this.parentNode.link.starred = false; + } + store.put(this.parentNode.link); + }; + var createNode = function (video, before) { + var node = ui.create.div('.videonode.menubutton.large', clickcapt); + node.link = video; + var nodename1 = ui.create.div('.menubutton.videoavatar', node); + nodename1.setBackground(video.name1, 'character'); + if (video.name2) { + var nodename2 = ui.create.div('.menubutton.videoavatar2', node); + nodename2.setBackground(video.name2, 'character'); + } + var date = new Date(video.time); + var str = date.getFullYear() + '.' + (date.getMonth() + 1) + '.' + (date.getDate()) + ' ' + + date.getHours() + ':'; + var minutes = date.getMinutes(); + if (minutes < 10) { + str += '0'; + } + str += minutes; + ui.create.div('.caption', video.name[0], node); + ui.create.div('.text', str + '
          ' + video.name[1], node); + if (video.win) { + ui.create.div('.victory', '胜', node); + } + + if (before) { + page.insertBefore(node, page.firstChild); + } + else { + page.appendChild(node); + } + ui.create.div('.video_star', '★', node, staritem); + if (video.starred) { + node.classList.add('starred'); + } + }; + for (var i = 0; i < lib.videos.length; i++) { + createNode(lib.videos[i]); + } + ui.create.videoNode = createNode; + var importVideoNode = ui.create.div('.config.switcher.pointerspan', + '导入录像...', function () { + this.nextSibling.classList.toggle('hidden'); + }, page); + importVideoNode.style.marginLeft = '12px'; + importVideoNode.style.marginTop = '3px'; + var importVideo = ui.create.div('.config.hidden', page); + importVideo.style.whiteSpace = 'nowrap'; + importVideo.style.marginBottom = '80px'; + importVideo.style.marginLeft = '13px'; + importVideo.style.width = 'calc(100% - 30px)'; + importVideo.innerHTML = '' + + ''; + importVideo.lastChild.onclick = function () { + var fileToLoad = importVideo.firstChild.files[0]; + var fileReader = new FileReader(); + fileReader.onload = function (fileLoadedEvent) { + var data = fileLoadedEvent.target.result; + if (!data) return; + try { + data = JSON.parse(lib.init.decode(data)); + } + catch (e) { + console.log(e); + alert('导入失败'); + return; + } + var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); + var videos = lib.videos.slice(0); + for (var i = 0; i < videos.length; i++) { + if (videos[i].starred) { + videos.splice(i--, 1); + } + } + for (var deletei = 0; deletei < 5; deletei++) { + if (videos.length >= parseInt(lib.config.video) && videos.length) { + var toremove = videos.pop(); + lib.videos.remove(toremove); + store.delete(toremove.time); + for (var i = 0; i < page.childNodes.length; i++) { + if (page.childNodes[i].link == toremove) { + page.childNodes[i].remove(); + break; + } + } + } + else { + break; + } + } + for (var i = 0; i < lib.videos.length; i++) { + if (lib.videos[i].time == data.time) { + alert('录像已存在'); + return; + } + } + lib.videos.unshift(data); + store.put(data); + createNode(data, true); + }; + fileReader.readAsText(fileToLoad, "UTF-8"); + }; + + playButton.listen(function () { + var current = this.parentNode.querySelector('.videonode.active'); + if (current) { + game.playVideo(current.link.time, current.link.mode); + } + }); + deleteButton.listen(function () { + var current = this.parentNode.querySelector('.videonode.active'); + if (current) { + lib.videos.remove(current.link); + var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); + store.delete(current.link.time); + current.remove(); + } + }); + saveButton.listen(function () { + var current = this.parentNode.querySelector('.videonode.active'); + if (current) { + game.export(lib.init.encode(JSON.stringify(current.link)), + '无名杀 - 录像 - ' + current.link.name[0] + ' - ' + current.link.name[1]); + } + }); + + ui.updateVideoMenu = function () { + var active = start.firstChild.querySelector('.active'); + if (active) { + active.classList.remove('active'); + active.link.remove(); + } + node.classList.add('active'); + rightPane.appendChild(page); + playButton.style.display = ''; + deleteButton.style.display = ''; + saveButton.style.display = ''; + }; + } + }; + }; + if (!get.config('menu_loadondemand')) node._initLink(); + }()); + + + for (var i in lib.help) { + var page = ui.create.div(''); + var node = ui.create.div('.menubutton.large', i, start.firstChild, clickMode); + node.type = 'help'; + node.link = page; + node.style.display = 'none'; + page.classList.add('menu-help'); + page.innerHTML = lib.help[i]; + } + + if (!connectMenu) { + var node = ui.create.div('.menubutton.large', '帮助', start.firstChild, function () { + var activex = start.firstChild.querySelector('.active'); + if (this.innerHTML == '帮助') { + cheatButton.style.display = 'none'; + runButton.style.display = 'none'; + clearButton.style.display = 'none'; + playButton.style.display = 'none'; + saveButton.style.display = 'none'; + deleteButton.style.display = 'none'; + + this.innerHTML = '返回'; + for (var i = 0; i < start.firstChild.childElementCount; i++) { + var nodex = start.firstChild.childNodes[i]; + if (nodex == node) continue; + if (nodex.type == 'help') { + nodex.style.display = ''; + if (activex && activex.type != 'help') { + activex.classList.remove('active'); + activex.link.remove(); + activex = null; + nodex.classList.add('active'); + rightPane.appendChild(nodex.link); + } + } + else { + nodex.style.display = 'none'; + } + } + } + else { + this.innerHTML = '帮助'; + for (var i = 0; i < start.firstChild.childElementCount; i++) { + var nodex = start.firstChild.childNodes[i]; + if (nodex == node) continue; + if (nodex.type != 'help') { + nodex.style.display = ''; + if (activex && activex.type == 'help') { + activex.classList.remove('active'); + activex.link.remove(); + activex = null; + clickMode.call(nodex); + } + } + else { + nodex.style.display = 'none'; + } + } + } + }); + } + + var active = start.firstChild.querySelector('.active'); + if (!active) { + active = start.firstChild.firstChild; + active.classList.add('active'); + } + if (!active.link) active._initLink(); + rightPane.appendChild(active.link); + }()); + + if (menuTimeout) { + clearTimeout(menuTimeout); + delete window.resetExtension; + localStorage.removeItem(lib.configprefix + 'disable_extension', true); + } + } + static statictable() { + var str, row, col, position, position2, fixed, style, divposition; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == 'string') str = arguments[i]; + else if (typeof arguments[i] == 'number') { + if (typeof row == 'number') { + if (typeof col == 'number') position2 = arguments[i]; + else col = arguments[i]; + } + else row = arguments[i]; + } + else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; + else if (typeof arguments[i] == 'boolean') fixed = arguments[i]; + else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; + else if (typeof arguments[i] == 'object') style = arguments[i]; + } + if (str == undefined) str = ''; + var node = document.createElement('table'); + for (var i = 0; i < str.length; i++) { + if (str[i] == '.') { + if (node.className.length != 0) { + node.className += ' '; + } + while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + node.className += str[i + 1]; + i++; + } + } + else if (str[i] == '#') { + while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + node.id += str[i + 1]; + i++; + } + } + } + var tr, td; + for (var i = 0; i < row; i++) { + tr = document.createElement('tr'); + if (fixed) tr.style.height = (100 / row) + '%'; + node.appendChild(tr); + for (var j = 0; j < col; j++) { + td = document.createElement('td'); + tr.appendChild(td); + } + } + if (position) { + if (typeof position2 == 'number' && position.childNodes.length > position2) { + position.insertBefore(node, position.childNodes[position2]); + } + else { + position.appendChild(node); + } + } + return node; + } + static giveup() { + if (ui.giveup) return; + if (!lib.config.show_giveup) return; + ui.giveup = ui.create.system('投降', function () { + var player = game.me; + this.remove(); + if (game.online) { + game.send('giveup', player); + } + else { + _status.event.next.length = 0; + game.createEvent('giveup', false).set('includeOut', true).setContent(function () { + game.log(player, '投降'); + player.popup('投降'); + player.die('nosource').includeOut = true; + }).player = player; + } + if (_status.paused && _status.imchoosing && !_status.auto) { + ui.click.auto(); + } + }, true, true); + } + static groupControl(dialog) { + return ui.create.control('wei', 'shu', 'wu', 'qun', 'jin', 'western', 'key', function (link, node) { + if (link == '全部') { + dialog.currentcapt = ''; + dialog.currentgroup = ''; + for (var i = 0; i < dialog.buttons.length; i++) { + dialog.buttons[i].style.display = ''; + } + } + else { + if (node.classList.contains('thundertext')) { + dialog.currentgroup = null; + dialog.currentgroupnode = null; + node.classList.remove('thundertext'); + for (var i = 0; i < dialog.buttons.length; i++) { + if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + dialog.buttons[i].classList.remove('nodisplay'); + } + } + } + else { + if (dialog.currentgroupnode) { + dialog.currentgroupnode.classList.remove('thundertext'); + } + dialog.currentgroup = link; + dialog.currentgroupnode = node; + node.classList.add('thundertext'); + for (var i = 0; i < dialog.buttons.length; i++) { + if (dialog.buttons[i].group != link || + (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt))) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + dialog.buttons[i].classList.remove('nodisplay'); + } + } + } + } + }); + } + static cardDialog() { + var args = ['thisiscard']; + for (var i = 0; i < arguments.length; i++) { + args.push(arguments[i]); + } + return ui.create.characterDialog.apply(this, args); + } + static characterDialog2(filter) { + var list = []; + for (var i in lib.character) { + if (lib.character[i][4].includes('minskin')) continue; + if (lib.character[i][4].includes('boss') || lib.character[i][4].includes('hiddenboss')) { + if (lib.config.mode == 'boss') continue; + if (!lib.character[i][4].includes('bossallowed')) continue; + } + + if (lib.character[i][4].includes('stonehidden')) continue; + if (lib.config.banned.includes(i)) continue; + if (filter && filter(i)) continue; + list.push(i); + } + var dialog = ui.create.dialog('hidden'); + dialog.classList.add('noupdate'); + dialog.classList.add('scroll1'); + dialog.classList.add('scroll2'); + dialog.classList.add('scroll3'); + list.sort(lib.sort.character); + dialog.classList.add('character'); + dialog.classList.add('choose-character'); + var getPack = function (name) { + for (var i in lib.characterPack) { + if (lib.characterPack[i][name]) return i; + } + return null; + }; + var packs = {}; + var packnode = ui.create.div('.packnode', dialog); + lib.setScroll(packnode); + var clickCapt = function () { + var active = this.parentNode.querySelector('.active'); + if (active) { + active.classList.remove('active'); + } + this.classList.add('active'); + for (var i = 0; i < dialog.buttons.length; i++) { + if (this.pack && !this.pack.includes(dialog.buttons[i].link)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + dialog.buttons[i].classList.remove('nodisplay'); + } + } + }; + var createNode = function (packname) { + var translate; + var pack = null; + if (packname == '最近') { + pack = get.config('recentCharacter') || []; + } + else if (packname == '收藏') { + pack = lib.config.favouriteCharacter; + } + var node = ui.create.div('.dialogbutton.menubutton.large', packname, packnode, clickCapt); + node.pack = pack; + return node; + }; + dialog.add([list, 'character']); + var bool = true; + var node; + var recent = get.config('recentCharacter'); + if (recent && recent.length) { + node = createNode('最近'); + if (lib.config.character_dialog_tool == '最近') { + clickCapt.call(node); + bool = false; + } + } + if (lib.config.favouriteCharacter.length) { + node = createNode('收藏'); + if (lib.config.character_dialog_tool == '收藏') { + clickCapt.call(node); + bool = false; + } + } + var node = createNode('全部'); + if (lib.config.character_dialog_tool == 'all') { + clickCapt.call(node); + bool = false; + } + if (bool) { + clickCapt.call(packnode.firstChild); + } + + var node = ui.create.div('.dialogbutton.menubutton.large', '筛选', packnode); + return dialog; + } + static characterDialog() { + // if(lib.config.character_dialog_style=='newstyle'){ + // for(var i=0;i b ? 1 : -1; + }); + groups.sort(lib.sort.group); + if (!thisiscard) { + namecapt.remove('自定义'); + namecapt.push('newline'); + for (var i in lib.characterDialogGroup) { + namecapt.push(i); + } + } + var newlined = false; + var newlined2; + var packsource; + var clickCapt = function (e) { + if (_status.dragged) return; + if (dialog.currentcapt2 == '最近' && dialog.currentcaptnode2 != this && !dialog.currentcaptnode2.inited) { + dialog.currentcapt2 = null; + dialog.currentcaptnode2.classList.remove('thundertext'); + dialog.currentcaptnode2.inited = true; + dialog.currentcaptnode2 = null; + } + if (this.alphabet) { + if (this.classList.contains('thundertext')) { + dialog.currentcapt = null; + dialog.currentcaptnode = null; + this.classList.remove('thundertext'); + if (this.touchlink) { + this.touchlink.classList.remove('active'); + } + for (var i = 0; i < dialog.buttons.length; i++) { + if (dialog.currentgroup && dialog.buttons[i].group != dialog.currentgroup) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentcapt2 && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + dialog.buttons[i].classList.remove('nodisplay'); + } + } + } + else { + if (dialog.currentcaptnode) { + dialog.currentcaptnode.classList.remove('thundertext'); + if (dialog.currentcaptnode.touchlink) { + dialog.currentcaptnode.touchlink.classList.remove('active'); + } + } + dialog.currentcapt = this.link; + dialog.currentcaptnode = this; + this.classList.add('thundertext'); + if (this.touchlink) { + this.touchlink.classList.add('active'); + } + for (var i = 0; i < dialog.buttons.length; i++) { + if (dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentcapt2 && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentgroup && dialog.buttons[i].group != dialog.currentgroup) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + dialog.buttons[i].classList.remove('nodisplay'); + } + } + } + } + else { + if (newlined2) { + newlined2.style.display = 'none'; + if (!packsource.onlypack) { + packsource.classList.remove('thundertext'); + if (!get.is.phoneLayout() || !lib.config.filternode_button) { + packsource.innerHTML = '武将包'; + } + } + } + if (this.classList.contains('thundertext')) { + dialog.currentcapt2 = null; + dialog.currentcaptnode2 = null; + this.classList.remove('thundertext'); + if (this.touchlink) { + this.touchlink.classList.remove('active'); + } + for (var i = 0; i < dialog.buttons.length; i++) { + if (dialog.currentgroup && dialog.buttons[i].group != dialog.currentgroup) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + dialog.buttons[i].classList.remove('nodisplay'); + } + } + } + else { + if (dialog.currentcaptnode2) { + dialog.currentcaptnode2.classList.remove('thundertext'); + if (dialog.currentcaptnode2.touchlink) { + dialog.currentcaptnode2.touchlink.classList.remove('active'); + } + } + dialog.currentcapt2 = this.link; + dialog.currentcaptnode2 = this; + this.classList.add('thundertext'); + if (this.touchlink) { + this.touchlink.classList.add('active'); + } + else if (this.parentNode == newlined2) { + packsource.innerHTML = this.innerHTML; + packsource.classList.add('thundertext'); + } + for (var i = 0; i < dialog.buttons.length; i++) { + if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentgroup && dialog.buttons[i].group != dialog.currentgroup) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + if (dialog.buttons[i].activate) { + dialog.buttons[i].activate(); + } + dialog.buttons[i].classList.remove('nodisplay'); + } + } + } + } + if (dialog.seperate) { + for (var i = 0; i < dialog.seperate.length; i++) { + if (!dialog.seperate[i].nextSibling.querySelector('.button:not(.nodisplay)')) { + dialog.seperate[i].style.display = 'none'; + dialog.seperate[i].nextSibling.style.display = 'none'; + } + else { + dialog.seperate[i].style.display = ''; + dialog.seperate[i].nextSibling.style.display = ''; + } + } + } + if (filternode) { + if (filternode.querySelector('.active')) { + packsource.classList.add('thundertext'); + } + else { + packsource.classList.remove('thundertext'); + } + } + if (e) e.stopPropagation(); + }; + for (i = 0; i < namecapt.length; i++) { + if (namecapt[i] == 'newline') { + newlined = document.createElement('div'); + newlined.style.marginTop = '5px'; + newlined.style.display = 'block'; + // newlined.style.fontFamily='xinwei'; + if (get.is.phoneLayout()) { + newlined.style.fontSize = '32px'; + } + else { + newlined.style.fontSize = '22px'; + } + newlined.style.textAlign = 'center'; + node.appendChild(newlined); + } + else if (newlined) { + var span = ui.create.div('.tdnode.pointerdiv.shadowed.reduce_radius'); + span.style.margin = '3px'; + span.style.width = 'auto'; + span.innerHTML = ' ' + namecapt[i].toUpperCase() + ' '; + span.link = namecapt[i]; + span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); + newlined.appendChild(span); + node[namecapt[i]] = span; + if (namecapt[i] == '收藏') { + span._nature = 'fire'; + } + else { + span._nature = 'wood'; + } + } + else { + var span = document.createElement('span'); + span.innerHTML = ' ' + namecapt[i].toUpperCase() + ' '; + span.link = namecapt[i]; + span.alphabet = true; + span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); + node.appendChild(span); + } + } + if (!thisiscard) { + var natures = ['water', 'soil', 'wood', 'metal']; + var span = document.createElement('span'); + newlined.appendChild(span); + span.style.margin = '8px'; + var clickGroup = function () { + if (_status.dragged) return; + if (dialog.currentcapt2 == '最近' && dialog.currentcaptnode2 != this && !dialog.currentcaptnode2.inited) { + dialog.currentcapt2 = null; + dialog.currentcaptnode2.classList.remove('thundertext'); + dialog.currentcaptnode2.inited = true; + dialog.currentcaptnode2 = null; + } + var node = this, link = this.link; + if (node.classList.contains('thundertext')) { + dialog.currentgroup = null; + dialog.currentgroupnode = null; + node.classList.remove('thundertext'); + for (var i = 0; i < dialog.buttons.length; i++) { + if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentcapt2 && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + dialog.buttons[i].classList.remove('nodisplay'); + } + } + } + else { + if (dialog.currentgroupnode) { + dialog.currentgroupnode.classList.remove('thundertext'); + } + dialog.currentgroup = link; + dialog.currentgroupnode = node; + node.classList.add('thundertext'); + for (var i = 0; i < dialog.buttons.length; i++) { + if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentcapt2 && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt, true)) { + dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentgroup == 'double') { + if (dialog.buttons[i]._changeGroup) dialog.buttons[i].classList.remove('nodisplay'); + else dialog.buttons[i].classList.add('nodisplay'); + } + else if (dialog.currentgroup == 'ye') { + if (dialog.buttons[i].group == 'ye') dialog.buttons[i].classList.remove('nodisplay'); + else dialog.buttons[i].classList.add('nodisplay'); + } + else { + if (dialog.buttons[i]._changeGroup || dialog.buttons[i].group != dialog.currentgroup) { + dialog.buttons[i].classList.add('nodisplay'); + } + else { + dialog.buttons[i].classList.remove('nodisplay'); + } + } + } + } + }; + for (var i = 0; i < groups.length; i++) { + var span = ui.create.div('.tdnode.pointerdiv.shadowed.reduce_radius.reduce_margin'); + span.style.margin = '3px'; + newlined.appendChild(span); + span.innerHTML = get.translation(groups[i]); + span.link = groups[i]; + span._nature = natures[i]; + span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickGroup); + } + + var span = document.createElement('span'); + newlined.appendChild(span); + span.style.margin = '8px'; + + packsource = ui.create.div('.tdnode.pointerdiv.shadowed.reduce_radius.reduce_margin'); + packsource.style.margin = '3px'; + newlined.appendChild(packsource); + var filternode = null; + var clickCaptNode = function (e) { + delete _status.filterCharacter; + ui.window.classList.remove('shortcutpaused'); + filternode.delete(); + filternode.classList.remove('shown'); + clickCapt.call(this.link, e); + }; + if (get.is.phoneLayout() && lib.config.filternode_button) { + newlined.style.marginTop = ''; + packsource.innerHTML = '筛选'; + filternode = ui.create.div('.popup-container.filter-character.modenopause'); + ui.create.div(filternode); + filternode.listen(function (e) { + if (this.classList.contains('removing')) return; + delete _status.filterCharacter; + ui.window.classList.remove('shortcutpaused'); + this.delete(); + this.classList.remove('shown'); + e.stopPropagation(); + }); + for (var i = 0; i < node.childElementCount; i++) { + if (node.childNodes[i].tagName.toLowerCase() == 'span') { + node.childNodes[i].style.display = 'none'; + node.childNodes[i].touchlink = ui.create.div(filternode.firstChild, clickCaptNode, '.menubutton.large.capt', node.childNodes[i].innerHTML); + node.childNodes[i].touchlink.link = node.childNodes[i]; + } + } + ui.create.node('br', filternode.firstChild); + } + else { + if (onlypack) { + packsource.onlypack = true; + packsource.innerHTML = get.translation(onlypack + '_character_config'); + packsource.style.display = 'none'; + packsource.previousSibling.style.display = 'none'; + } + else { + packsource.innerHTML = '武将包'; + } + } + + newlined2 = document.createElement('div'); + newlined2.style.marginTop = '5px'; + newlined2.style.display = 'none'; + newlined2.style.fontFamily = 'xinwei'; + newlined2.classList.add('pointernode'); + if (get.is.phoneLayout()) { + newlined2.style.fontSize = '32px'; + } + else { + newlined2.style.fontSize = '22px'; + } + newlined2.style.textAlign = 'center'; + node.appendChild(newlined2); + + packsource.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function () { + if (packsource.onlypack) return; + if (_status.dragged) return; + if (get.is.phoneLayout() && lib.config.filternode_button && filternode) { + _status.filterCharacter = true; + ui.window.classList.add('shortcutpaused'); + ui.window.appendChild(filternode); + ui.refresh(filternode); + filternode.classList.add('shown'); + var dh = filternode.offsetHeight - filternode.firstChild.offsetHeight; + if (dh > 0) { + filternode.firstChild.style.top = (dh / 2) + 'px'; + } + else { + filternode.firstChild.style.top = ''; + } + } + else { + if (newlined2.style.display == 'none') { + newlined2.style.display = 'block'; + } + else { + newlined2.style.display = 'none'; + } + } + }); + var packlist = []; + for (var i = 0; i < lib.config.all.characters.length; i++) { + if (!lib.config.characters.includes(lib.config.all.characters[i])) continue; + packlist.push(lib.config.all.characters[i]); + } + for (var i in lib.characterPack) { + if (!lib.config.all.characters.includes(i)) { + packlist.push(i); + } + } + for (var i = 0; i < packlist.length; i++) { + var span = document.createElement('div'); + span.style.display = 'inline-block'; + span.style.width = 'auto'; + span.style.margin = '5px'; + if (get.is.phoneLayout()) { + span.style.fontSize = '32px'; + } + else { + span.style.fontSize = '22px'; + } + span.innerHTML = lib.translate[packlist[i] + '_character_config']; + span.link = packlist[i]; + span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); + newlined2.appendChild(span); + if (filternode && !onlypack) { + span.touchlink = ui.create.div(filternode.firstChild, clickCaptNode, '.menubutton.large', span.innerHTML); + span.touchlink.link = span; + } + } + } + + var groupSort; + if (thisiscard) { + groupSort = function (name) { + var type = lib.card[name[2]].type; + if (lib.cardType[type]) { + return lib.cardType[type]; + } + switch (type) { + case 'basic': return 0; + case 'chess': return 1.5; + case 'trick': return 2; + case 'delay': return 3; + case 'equip': return 4; + case 'zhenfa': return 5; + default: return 6; + } + }; + list.sort(function (a, b) { + var del = groupSort(a) - groupSort(b); + if (del != 0) return del; + var aa = a, bb = b; + if (a.includes('_')) { + a = a.slice(a.lastIndexOf('_') + 1); + } + if (b.includes('_')) { + b = b.slice(b.lastIndexOf('_') + 1); + } + if (a != b) { + return a > b ? 1 : -1; + } + return aa > bb ? 1 : -1; + }); + } + else { + list.sort(lib.sort.character); + } + dialog = ui.create.dialog('hidden'); + dialog.classList.add('noupdate'); + dialog.classList.add('scroll1'); + dialog.classList.add('scroll2'); + dialog.classList.add('scroll3'); + dialog.addEventListener(lib.config.touchscreen ? 'touchend' : 'mouseup', function () { + _status.clicked2 = true; + }); + if (heightset) { + dialog.style.height = ((game.layout == 'long2' || game.layout == 'nova') ? 380 : 350) + 'px'; + dialog._scrollset = true; + } + dialog.getCurrentCapt = function (link, capt, noalph) { + var currentcapt = noalph ? this.currentcapt2 : this.currentcapt; + if (this.seperatelist && noalph) { + if (this.seperatelist[currentcapt].includes(link)) return capt; + return null; + } + if (lib.characterDialogGroup[currentcapt]) { + return lib.characterDialogGroup[currentcapt](link, capt); + } + if (lib.characterPack[currentcapt]) { + if (lib.characterPack[currentcapt][link]) { + return capt; + } + return null; + } + return this.currentcapt; + }; + if (str) { + dialog.add(str); + } + dialog.add(node); + if (thisiscard) { + if (seperate) { + seperate = seperate(list); + dialog.seperate = []; + dialog.seperatelist = seperate.list; + if (dialog.seperatelist) { + newlined = document.createElement('div'); + newlined.style.marginTop = '5px'; + newlined.style.display = 'block'; + newlined.style.fontFamily = 'xinwei'; + if (get.is.phoneLayout()) { + newlined.style.fontSize = '32px'; + } + else { + newlined.style.fontSize = '22px'; + } + newlined.style.textAlign = 'center'; + node.appendChild(newlined); + for (var i in dialog.seperatelist) { + var span = document.createElement('span'); + span.style.margin = '3px'; + span.innerHTML = i; + span.link = i; + span.seperate = true; + span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); + newlined.appendChild(span); + } + } + for (var i in seperate) { + if (i == 'list') continue; + var link = ''; + var linkcontent = seperate[i]; + if (i.includes('_link:')) { + link = i.slice(i.indexOf('_link:') + 6); + i = i.slice(0, i.indexOf('_link:')); + } + var nodesep = dialog.add(i); + nodesep.link = link; + dialog.seperate.push(nodesep); + dialog.add([linkcontent, 'vcard'], noclick); + } + } + else { + dialog.add([list, 'vcard'], noclick); + } + } + else { + if (precharacter) { + dialog.add([list, 'precharacter'], noclick); + } + else if (characterx) { + dialog.add([list, 'characterx'], noclick); + } + else { + dialog.add([list, 'character'], noclick); + } + } + dialog.add(ui.create.div('.placeholder')); + for (i = 0; i < dialog.buttons.length; i++) { + if (thisiscard) { + dialog.buttons[i].capt = getCapt(dialog.buttons[i].link[2]); + } + else { + dialog.buttons[i].group = lib.character[dialog.buttons[i].link][1]; + dialog.buttons[i].capt = getCapt(dialog.buttons[i].link); + } + } + if (!expandall) { + if (!thisiscard && (lib.characterDialogGroup[lib.config.character_dialog_tool] || + lib.config.character_dialog_tool == '自创')) { + clickCapt.call(node[lib.config.character_dialog_tool]); + } + } + return dialog; + } + static dialog() { + let dialog = new lib.element.Dialog(...arguments); + if (!Array.from(arguments).includes('hidden')) { + dialog.open(); + } + return dialog; + } + static line2() { + var node = ui.create.line.apply(this, arguments); + node.classList.add('line2'); + return node; + } + static line() { + var two = false, func; + var node = ui.create.div('.config'); + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == 'string' || typeof arguments[i] == 'number') { + if (two) ui.create.div('.toggle', node).innerHTML = arguments[i]; + else { + ui.create.div(node).innerHTML = arguments[i]; + two = true; + } + } + else if (typeof arguments[i] == 'function') func = arguments[i]; + } + if (func) { + for (var i = 0; i < node.childNodes.length; i++) node.childNodes[i].listen(func); + } + return node; + } + static switcher(name, current, current2) { + var func; + var node = ui.create.div('.config'); + ui.create.div(node).innerHTML = get.translation(name + '_config'); + var switcher = ui.create.div('.toggle.pointerdiv', node); + switcher.name = name; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == 'function') { + func = arguments[i]; break; + } + } + if (typeof current == 'string') { + switcher.link = current; + switcher.innerHTML = get.translation(current); + switcher.contentEditable = true; + switcher.style.webkitUserSelect = 'text'; + switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.editor); + } + else if (typeof current == 'object') { + switcher.link = current2 || current[0]; + switcher.innerHTML = get.translation(switcher.link); + switcher.choice = current; + switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.switcher); + } + else { + if (current) { + switcher.classList.add('on'); + } + switcher.classList.add('onoff'); + ui.create.div(ui.create.div(switcher)); + switcher.link = current ? true : false; + switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.toggle); + } + if (func) switcher.additionalCommand = func; + return node; + } + static caption(str, position) { + var caption = ui.create.div('.caption', position); + caption.innerHTML = str; + return caption; + } + static control() { + return new lib.element.Control(...arguments); + } + static confirm(str, func) { + if (ui.confirm && ui.confirm.str == str) { + return; + } + if (str == 'o') { + if (ui.confirm) { + ui.confirm.replace('ok'); + } + else { + ui.confirm = ui.create.control('ok'); + } + } + else if (str == 'oc' || str == 'co') { + if (ui.confirm) { + ui.confirm.replace('ok', 'cancel'); + } + else { + ui.confirm = ui.create.control('ok', 'cancel'); + } + } + else if (str == 'c') { + if (ui.confirm) { + ui.confirm.replace('cancel'); + } + else { + ui.confirm = ui.create.control('cancel'); + } + } + else if (ui.confirm) { + ui.confirm.close(); + delete ui.confirm; + } + if (ui.confirm) { + ui.confirm.str = str; + if (func) ui.confirm.custom = func; + else delete ui.confirm.custom; + } + } + static skills(skills) { + var i, same; + if (ui.skills) { + if (ui.skills.skills.length == skills.length && ui.skills.style.display != 'none') { + same = true; + for (i = 0; i < skills.length; i++) { + if (ui.skills.skills.includes(skills[i]) == false) { + same = false; + break; + } + } + } + if (same) return; + ui.skills.close(); + delete ui.skills; + } + if (skills == undefined || skills.length == 0) return; + if (!_status.event.isMine()) { + _status.noupdatec = true; + } + ui.skills = ui.create.control(skills.concat([ui.click.skill])); + for (var i = 0; i < ui.skills.childNodes.length; i++) { + ui.skills.childNodes[i].innerHTML = get.skillTranslation(ui.skills.childNodes[i].link, _status.event.player); + } + if (!_status.event.isMine()) { + ui.skills.style.display = 'none'; + } + else { + ui.updatec(); + } + _status.noupdatec = false; + ui.skills.skills = skills; + return ui.skills; + } + static skills2(skills) { + var i, same; + if (ui.skills2) { + if (ui.skills2.skills.length == skills.length && ui.skills2.style.display != 'none') { + same = true; + for (i = 0; i < skills.length; i++) { + if (ui.skills2.skills.includes(skills[i]) == false) { + same = false; + break; + } + } + } + if (same) return; + ui.skills2.close(); + delete ui.skills2; + } + if (skills == undefined || skills.length == 0) return; + if (!_status.event.isMine()) { + _status.noupdatec = true; + } + ui.skills2 = ui.create.control(skills.concat([ui.click.skill])); + for (var i = 0; i < ui.skills2.childNodes.length; i++) { + ui.skills2.childNodes[i].innerHTML = get.skillTranslation(ui.skills2.childNodes[i].link, _status.event.player); + } + if (!_status.event.isMine()) { + ui.skills2.style.display = 'none'; + } + else { + ui.updatec(); + } + _status.noupdatec = false; + ui.skills2.skills = skills; + return ui.skills2; + } + static skills3(skills) { + var i, same; + if (ui.skills3) { + if (ui.skills3.skills.length == skills.length && ui.skills3.style.display != 'none') { + same = true; + for (i = 0; i < skills.length; i++) { + if (ui.skills3.skills.includes(skills[i]) == false) { + same = false; + break; + } + } + } + if (same) return; + ui.skills3.close(); + delete ui.skills3; + } + if (skills == undefined || skills.length == 0) return; + if (!_status.event.isMine()) { + _status.noupdatec = true; + } + ui.skills3 = ui.create.control(skills.concat([ui.click.skill])); + for (var i = 0; i < ui.skills3.childNodes.length; i++) { + ui.skills3.childNodes[i].innerHTML = get.skillTranslation(ui.skills3.childNodes[i].link, _status.event.player); + } + if (!_status.event.isMine()) { + ui.skills3.style.display = 'none'; + } + else { + ui.updatec(); + } + _status.noupdatec = false; + ui.skills3.skills = skills; + return ui.skills3; + } + static arena() { + var i, j; + ui.window = ui.create.div('#window.hidden', document.body); + ui.create.div('#statusbg', document.body); + ui.refresh(ui.window); + if (!localStorage.getItem(lib.configprefix + 'playback')) { + ui.window.show(); + } + else { + setTimeout(function () { + ui.window.show(); + }, 1000); + } + // lib.setPressure(ui.window,ui.click.pressurepause); + if (window.isNonameServer) { + ui.window.classList.add('server'); + var serverinfo = ui.create.div('.serverinfo', ui.window); + ui.create.div('', '服务器正在运行', serverinfo); + var serverinfotable = ui.create.table(2, 2, ui.create.div(serverinfo)); + serverinfotable.style.display = 'inline-block'; + serverinfotable.firstChild.firstChild.innerHTML = '房间人数:'; + serverinfotable.firstChild.lastChild.id = 'server_count'; + serverinfotable.firstChild.lastChild.innerHTML = '0'; + serverinfotable.lastChild.firstChild.innerHTML = '房间状态:'; + serverinfotable.lastChild.lastChild.id = 'server_status'; + serverinfotable.lastChild.lastChild.innerHTML = '空闲'; + ui.create.div('.menubutton.large', '关闭服务器', function () { + if (_status.gameStarted && !confirm('关闭服务器当前进行的游戏将终止且不可恢复,是否确定关闭?')) { + return; + } + localStorage.removeItem(lib.configprefix + 'asserver'); + game.reload(); + }, ui.create.div('', serverinfo)); + } + + ui.window.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.window); + ui.system = ui.create.div("#system.", ui.window); + ui.arena = ui.create.div('#arena.nome', ui.window); + if (lib.device == 'ios' && !get.is.phoneLayout()) { + ui.arena.classList.add('ipad'); + } + ui.arena.setNumber = function (num) { + this.dataset.number = num; + ui.updatePlayerPositions(); + // if(game.layout=='nova'&&parseInt(num)<7){ + // ui.arena.classList.add('player_autolong'); + // } + // else if(lib.config.player_height_nova!='long'){ + // ui.arena.classList.remove('player_autolong'); + // } + // if(game.layout=='long'&&parseInt(num)= 3600) { + var num1 = Math.floor(num / 3600); + var num2 = Math.floor((num - num1 * 3600) / 60); + if (num2 < 10) { + num2 = '0' + num2.toString(); + } + var num3 = num - num1 * 3600 - parseInt(num2) * 60; + if (num3 < 10) { + num3 = '0' + num3.toString(); + } + ui.time3.innerHTML = num1 + ':' + num2 + ':' + num3; + } + else { + var num1 = Math.floor(num / 60); + var num2 = num - num1 * 60; + if (num2 < 10) { + num2 = '0' + num2.toString(); + } + ui.time3.innerHTML = num1 + ':' + num2; + } + }, 1000); + } + if (get.is.nomenu()) { + if (!['menu', 'system'].includes(lib.config.round_menu_func)) { + lib.config.round_menu_func = 'system'; + } + } + else if (!lib.config.show_round_menu) { + ui.roundmenu.style.display = 'none'; + } + + var resetround = function (e) { + _status.draggingroundmenu = false; + ui.roundmenu.style.transform = ''; + ui.roundmenu._dragtransform = [0, 0]; + ui.roundmenu.style.transition = 'all 0.3s'; + delete ui.roundmenu._dragtouches; + delete ui.roundmenu._dragorigin; + delete ui.roundmenu._dragorigintransform; + setTimeout(function () { + ui.roundmenu.style.transition = ''; + }, 500); + game.saveConfig('roundmenu_transform', [0, 0]); + if (e) e.stopPropagation(); + return false; + }; + ui.click.resetround = resetround; + if (lib.config.touchscreen) { + ui.roundmenu.addEventListener('touchstart', function (e) { + _status.draggingroundmenu = true; + ui.roundmenu._dragorigin = { + clientX: e.touches[0].clientX, + clientY: e.touches[0].clientY, + }; + if (!ui.roundmenu._dragtransform) { + ui.roundmenu._dragtransform = [0, 0]; + } + ui.roundmenu._dragorigintransform = ui.roundmenu._dragtransform.slice(0); + ui.roundmenu._resetTimeout = setTimeout(function () { + resetround(); + delete ui.roundmenu._resetTimeout; + }, 1000); + }); + } + else { + ui.roundmenu.oncontextmenu = resetround; + } + if (!lib.config.remember_round_button) { + game.saveConfig('roundmenu_transform'); + } + if (lib.config.roundmenu_transform) { + var translate = lib.config.roundmenu_transform; + ui.roundmenu._dragtransform = translate; + ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; + ui.click.checkroundtranslate(); + } + if (get.is.phoneLayout()) { + ui.arena.classList.add('phone'); + } + + ui.sidebar = ui.create.div('#sidebar'); + ui.sidebar3 = ui.create.div('#sidebar3'); + ui.canvas = document.createElement('canvas'); + + ui.arena.appendChild(ui.canvas); + ui.canvas.id = 'canvas'; + ui.ctx = ui.canvas.getContext('2d'); + + ui.sidebar.ontouchstart = ui.click.touchStart; + ui.sidebar.ontouchmove = ui.click.touchScroll; + ui.sidebar.style.webkitOverflowScrolling = 'touch'; + + var zoom; + switch (lib.config.ui_zoom) { + case 'esmall': zoom = 0.8; break; + case 'vsmall': zoom = 0.9; break; + case 'small': zoom = 0.93; break; + case 'big': zoom = 1.05; break; + case 'vbig': zoom = 1.1; break; + case 'ebig': zoom = 1.2; break; + case 'eebig': zoom = 1.5; break; + case 'eeebig': zoom = 1.8; break; + case 'eeeebig': zoom = 2; break; + default: zoom = 1; + } + game.documentZoom = game.deviceZoom * zoom; + if (zoom != 1) { + ui.updatez(); + } + + ui.system1 = ui.create.div('#system1', ui.system); + ui.system2 = ui.create.div('#system2', ui.system); + + ui.replay = ui.create.system('重来', game.reload, true); + ui.replay.id = 'restartbutton'; + ui.config2 = ui.create.system('选项', ui.click.config); + ui.pause = ui.create.system('暂停', ui.click.pause); + ui.pause.id = 'pausebutton'; + if (!_status.video) { + ui.pause.hide(); + } + if (!lib.config.touchscreen) { + lib.setPopped(ui.pause, ui.click.pausehistory, 220, 400, null, true); + } + if (!lib.config.show_pause) { + ui.pause.style.display = 'none'; + } + ui.cardPileButton = ui.create.system('牌堆', null, true); + ui.cardPileButton.style.display = 'none'; + lib.setPopped(ui.cardPileButton, ui.click.cardPileButton, 220); + ui.wuxie = ui.create.system('不询问无懈', ui.click.wuxie, true); + if (!lib.config.touchscreen) { + lib.setPopped(ui.config2, ui.click.pauseconfig, 170); + } + ui.auto = ui.create.system('托管', ui.click.auto); + if (!game.syncMenu) { + ui.config2.classList.add('hidden'); + ui.config2.style.transition = 'all 0.5s'; + ui.roundmenu.classList.add('transparent2'); + + ui.auto.style.opacity = 0.5; + ui.auto.style.transition = 'all 0.5s'; + lib.onfree.push(function () { + ui.auto.style.opacity = ''; + setTimeout(function () { + ui.auto.style.transition = ''; + }, 500); + }); + } + ui.auto.id = 'autobutton'; + ui.autonode = ui.create.div('#autonode', '
          托管中...
          ', ui.arena); + ui.autonode.listen(ui.click.auto); + if (lib.config.mode == 'connect') { + ui.auto.hide(); + ui.pause.hide(); + } + + if (lib.forcehide) { + if (lib.forcehide.includes('replay')) ui.replay.classList.add('forcehide'); + if (lib.forcehide.includes('auto')) ui.auto.classList.add('forcehide'); + if (lib.forcehide.includes('pause')) ui.pause.classList.add('forcehide'); + if (lib.forcehide.includes('wuxie')) ui.wuxie.classList.add('forcehide'); + if (lib.forcehide.includes('cardPileButton')) ui.cardPileButton.classList.add('forcehide'); + } + ui.volumn = ui.create.system('♫'); + lib.setPopped(ui.volumn, ui.click.volumn, 200); + // if(lib.config.show_pause) ui.auto.style.marginLeft='10px'; + if (!lib.config.show_volumn) { + ui.volumn.style.display = 'none'; + } + if (!lib.config.show_auto) { + ui.auto.style.display = 'none'; + } + if (!lib.config.show_wuxie) { + ui.wuxie.style.display = 'none'; + } + // if(!lib.config.show_cardpile||_status.connectMode){ + // ui.cardPileButton.style.display='none'; + // } + + ui.sortCard = ui.create.system('整理手牌', function () { + if (!game.me) return; + var hs = game.me.getCards('h'); + if (!hs.length) return; + game.addVideo('lose', game.me, [get.cardsInfo(hs), [], [], []]); + for (var i = 0; i < hs.length; i++) { + hs[i].goto(ui.special); + } + if (game.me.hasSkillTag('sortCardByNum')) { + var getn = function (card) { + var num = get.number(card, game.me); + if (num < 3) return 13 + num; + return num; + }; + hs.sort((a, b) => (getn(b) - getn(a))); + } + else hs.sort(function (b, a) { + if (a.name != b.name) return lib.sort.card(a.name, b.name); + else if (a.suit != b.suit) return lib.suit.indexOf(a) - lib.suit.indexOf(b); + else return a.number - b.number; + }); + game.me.directgain(hs, false); + }); + if (!lib.config.show_sortcard) { + ui.sortCard.style.display = 'none'; + } + ui.playerids = ui.create.system('显示身份', function () { + if (game.showIdentity) { + game.showIdentity(); + _status.identityShown = true; + } + }, true); + if (!lib.config.show_playerids || !game.showIdentity) { + ui.playerids.style.display = 'none'; + } + if (!lib.config.show_replay) { + ui.replay.style.display = 'none'; + } + ui.control = ui.create.div('#control', ui.arena).addTempClass('nozoom'); + ui.cardPile = ui.create.div('#cardPile'); + ui.discardPile = ui.create.div('#discardPile'); + ui.special = ui.create.div('#special'); + ui.ordering = ui.create.div('#ordering'); + ui.dialogs = []; + ui.controls = []; + ui.style = {}; + + ui.time = ui.create.div(ui.gameinfo); + var timeInterval = function () { + var date = new Date(); + var hours = date.getHours(); + var minutes = date.getMinutes(); + if (lib.config.watchface == 'simple') { + ui.roundmenu.childNodes[13].style.transform = 'rotate(' + get.round((hours + 9) * 30, 2) + 'deg)'; + } + else { + ui.roundmenu.childNodes[13].style.transform = 'rotate(' + get.round((hours + minutes / 60 + 9) * 30, 2) + 'deg)'; + } + ui.roundmenu.childNodes[12].style.transform = 'rotate(' + (minutes + 45) * 6 + 'deg)'; + if (minutes < 10) { + minutes = '0' + minutes.toString(); + } + ui.time.innerHTML = hours + ':' + minutes; + }; + _status.timeInterval = setInterval(timeInterval, 30000); + timeInterval(); + if (!lib.config.show_time) { + ui.time.style.display = 'none'; + } + + ui.timer = ui.create.div('.skillbar.shadowed.playerbg.hidden'); + ui.timer.id = 'timer'; + ui.create.div('.skillbarshadow', ui.timer); + ui.create.div('.skillbarfill', ui.timer); + ui.timer.fillnode = ui.create.div(ui.timer.lastChild); + ui.timer.popnode = ui.create.div('.skillbartext', ui.timer); + ui.timer.popnode.style.opacity = 1; + ui.timer.position = 4; + ui.timer.style.zIndex = 5; + ui.timer.set = function (text, percentage) { + if (typeof text == 'string' || typeof text == 'number') { + ui.timer.popnode.innerHTML = text; + } + ui.timer.fillnode.style.top = ((1 - percentage) * 100) + '%'; + }; + var setTimerPosition = function (e) { + this.position++; + if (this.position > 4) { + this.position = 1; + } + var left1 = '180px'; + var left2 = 'calc(100% - 245px)'; + var top1 = '210px'; + var top2 = 'calc(100% - 245px)'; + if (game.layout == 'default') { + left1 = '265px'; + top1 = '160px'; + left2 = 'calc(100% - 330px)'; + top2 = 'calc(100% - 235px)'; + } + if (this.position == 1 || this.position == 2) { + this.style.top = top2; + } + else { + this.style.top = top1; + } + if (this.position == 1 || this.position == 4) { + this.style.left = left2; + } + else { + this.style.left = left1; + } + }; + ui.timer.listen(setTimerPosition); + + ui.shortcut = ui.create.div('#shortcut.hidden', ui.window); + ui.shortcut.listen(ui.click.shortcut); + ui.create.div(ui.shortcut, function (e) { e.stopPropagation(); }); + ui.create.div('.menubutton.round', '重来', ui.shortcut, game.reload).dataset.position = 1; + ui.create.div('.menubutton.round', '退出', ui.shortcut, game.exit).dataset.position = 3; + ui.create.div('.menubutton.round', '记录', ui.shortcut, ui.click.pause).dataset.position = 4; + ui.shortcut.autobutton = ui.create.div('.menubutton.round', '托管', ui.shortcut, ui.click.auto); + ui.shortcut.autobutton.dataset.position = 2; + ui.favmodelist = ui.create.div('.favmodelist', ui.shortcut); + ui.favmodelist.update = function () { + const favouriteMode = lib.config.favouriteMode; + let removed = false; + for (let index = 0; index < favouriteMode.length; index++) { + if (typeof favouriteMode[index] == 'string') continue; + favouriteMode.splice(index--, 1); + if (!removed) removed = true; + } + if (removed) game.saveConfigValue('favouriteMode'); + this.innerHTML = ''; + favouriteMode.slice(0, 6).forEach((value, index) => this.add(value, index)); + let mode = lib.config.mode; + const config = get.config(`${mode}_mode`); + if (typeof config == 'string') mode += `|${config}`; + if (favouriteMode.includes(mode)) ui.favmode.classList.add('glow'); + else ui.favmode.classList.remove('glow'); + }; + ui.favmodelist.add = function (name, index) { + const info = name.split('|'), mode = info[0], submode = info[1], node = ui.create.div('.menubutton.large', this), dataset = node.dataset; + dataset.type = Math.min(6, lib.config.favouriteMode.length) % 2 == 0 ? 'even' : 'odd'; + dataset.position = index; + let str = lib.translate[name] || lib.translate[mode] || ''; + if (str.length == 2) str += '模式'; + node.innerHTML = str; + node.listen(() => { + game.saveConfig('mode', mode); + if (submode) game.saveConfig(`${mode}_mode`, submode, mode); + game.reload(); + }); + }; + ui.favmode = ui.create.system('收藏', function () { + const mode = typeof _status.mode == 'string' ? `${lib.config.mode}|${_status.mode}` : lib.config.mode; + if (this.classList.contains('glow')) { + this.classList.remove('glow'); + lib.config.favouriteMode.remove(mode); + } + else { + this.classList.add('glow'); + lib.config.favouriteMode.add(mode); + } + game.saveConfig('favouriteMode', lib.config.favouriteMode); + ui.favmodelist.update(); + _status.clicked = true; + }); + ui.favmode.style.display = 'none'; + ui.favmodelist.update(); + // ui.create.div('.menubutton.round','菜单',ui.shortcut,ui.click.config).dataset.position=5; + + + if (_status.connectMode) { + ui.playerids.remove(); + ui.pause.innerHTML = '记录'; + } + setTimerPosition.call(ui.timer); + ui.arena.appendChild(ui.timer); + + if (!game.syncMenu) { + lib.onfree.push(function () { + ui.create.menu(); + ui.config2.classList.remove('hidden'); + ui.roundmenu.classList.remove('transparent2'); + setTimeout(function () { + ui.config2.style.transition = ''; + }, 500); + }); + } + else { + ui.create.menu(); + } + + lib.status.date = new Date(); + lib.status.dateDelayed = 0; + + while (lib.arenaReady.length) { + (lib.arenaReady.shift())(); + } + delete lib.arenaReady; + if (lib.config.auto_check_update) { + setTimeout(function () { + game.checkForUpdate(false); + }, 3000); + } + if (!lib.config.asset_version) { + lib.onfree.push(function () { + setTimeout(function () { + if (!game.download) { + game.saveConfig('asset_version', '无'); + } + else { + var func = function () { + if (confirm('是否下载图片和字体素材?(约175MB)')) { + if (!ui.arena.classList.contains('menupaused')) { + ui.click.configMenu(); + ui.click.menuTab('其它'); + } + setTimeout(game.checkForAssetUpdate, 500); + } + else { + game.saveConfig('asset_version', '无'); + } + }; + if (_status.new_tutorial) { + _status.new_tutorial = func; + } + else { + func(); + } + } + }, 3000); + }); + } + if (localStorage.getItem(lib.configprefix + 'playback')) { + setTimeout(lib.init.onfree); + } + + if (lib.config.test_game) { + ui.window.classList.add('testing'); + lib.config.game_speed = 'vfast'; + lib.config.low_performance = true; + lib.config.animation = false; + _status.auto = true; + ui.auto.classList.add('glow'); + setTimeout(function () { + var node = ui.create.pause().addTempClass('start'); + node.appendChild(ui.sidebar); + node.firstChild.innerHTML = '正在测试'; + node.removeEventListener('click', ui.click.resume); + }, 500); + } + } + static system(str, func, right, before) { + var parent = right ? ui.system2 : ui.system1; + var node = ui.create.div(); + if (before) { + parent.insertBefore(node, parent.firstChild); + } + else { + parent.appendChild(node); + } + node.innerHTML = str; + if (func) { + node.listen(func); + } + if (lib.config.button_press) { + node.addEventListener(lib.config.touchscreen ? 'touchstart' : 'mousedown', function (e) { + if (!node.classList.contains('hidden')) node.classList.add('pressdown'); + }); + node.addEventListener(lib.config.touchscreen ? 'touchend' : 'mouseup', function (e) { + node.classList.remove('pressdown'); + }); + node.addEventListener(lib.config.touchscreen ? 'touchmove' : 'mousemove', function (e) { + node.classList.remove('pressdown'); + }); + } + return node; + } + static pause() { + if (_status.pausing) return; + ui.click.shortcut(false); + var node = ui.create.div(".pausedbg", ui.window); + _status.pausing = true; + setTimeout(function () { + _status.pausing = false; + }, 500); + if (lib.config.touchscreen) { + setTimeout(function () { + node.addEventListener('touchend', ui.click.resume); + }, 500); + } + else { + node.addEventListener('click', ui.click.resume); + } + if (!lib.config.touchscreen) { + node.oncontextmenu = ui.click.resume; + } + + var node2 = ui.create.div(node); + if (_status.connectMode) { + node2.innerHTML = ''; + } + else { + node2.innerHTML = '已暂停'; + } + + // node2.listen(function(){ + // _status.clicked=true; + // if(ui.sidebar.classList.contains('hidden')){ + // ui.sidebar.show(); + // ui.sidebar3.show(); + // } + // else{ + // ui.sidebar.hide(); + // ui.sidebar3.hide(); + // } + // }); + return node; + } + static prebutton(item, type, position, noclick) { + var node = ui.create.div(position); + node.style.display = 'none'; + node.link = item; + node.activate = function () { + ui.create.button(item, type, position, noclick, node); + delete node.activate; + }; + _status.prebutton.push(node); + return node; + } + static buttonPresets = { + /** + * @returns { import("../library/index.js").Button } + */ + tdnodes: (item, type, position, noclick, node) => { + node = ui.create.div('.shadowed.reduce_radius.pointerdiv.tdnode.tdnodes', position); + if (Array.isArray(item)) { + node.innerHTML = '' + (item[1]) + ''; + node.link = item[0]; + } + else { + node.innerHTML = '' + (item) + ''; + node.link = item; + } + return node; + }, + /** + * @returns { import("../library/index.js").Button } + */ + blank: (item, type, position, noclick, node) => { + node = ui.create.div('.button.card', position); + node.link = item; + return node; + }, + /** + * @returns { import("../library/index.js").Button } + */ + card: (item, type, position, noclick, node) => { + if (typeof item.copy == 'function') { + node = item.copy(false); + } + else { + node = item.cloneNode(true); + } + node.classList.add('button'); + if (position) position.appendChild(node); + node.link = item; + if (item.style.backgroundImage) { + node.style.backgroundImage = item.style.backgroundImage; + node.style.backgroundSize = 'cover'; + } + if (item.style.color) { + node.style.color = item.style.color; + } + if (item.nature) { + let natures = get.natureList(item.nature); + natures.forEach(n => node.classList.add(n)); + } + if (!noclick) { + lib.setIntro(node); + } + if (get.position(item) == 'j' && item.viewAs && item.viewAs != item.name && lib.config.cardtempname != 'off') { + ui.create.cardTempName(item, node); + } + return node; + }, + /** + * @returns { import("../library/index.js").Button } + */ + vcard: (item, type, position, noclick, node) => { + if (typeof item == 'string') { + item = [get.type(item), '', item]; + } + node = ui.create.card(position, 'noclick', noclick); + node.classList.add('button'); + node.init(item); + node.link = item; + return node; + }, + /** + * @returns { import("../library/index.js").Button } + */ + character: (item, type, position, noclick, node) => { + if (node) { + node.classList.add('button'); + node.classList.add('character'); + node.style.display = ''; + } + else { + node = ui.create.div('.button.character', position); + } + node._link = item; + if (_status.noReplaceCharacter && type == 'characterx') type = 'character'; + if (type == 'characterx') { + if (lib.characterReplace[item] && lib.characterReplace[item].length) item = lib.characterReplace[item].randomGet(); + } + node.link = item; + + var double = get.is.double(node._link, true); + if (double) node._changeGroup = true; + if (type == 'characterx' && lib.characterReplace[node._link] && lib.characterReplace[node._link].length > 1) node._replaceButton = true; + var func = function (node, item) { + node.setBackground(item, 'character'); + if (node.node) { + node.node.name.remove(); + node.node.hp.remove(); + node.node.group.remove(); + node.node.intro.remove(); + if (node.node.replaceButton) node.node.replaceButton.remove(); + } + node.node = { + name: ui.create.div('.name', node), + hp: ui.create.div('.hp', node), + group: ui.create.div('.identity', node), + intro: ui.create.div('.intro', node), + }; + var infoitem = lib.character[item]; + if (!infoitem) { + for (var itemx in lib.characterPack) { + if (lib.characterPack[itemx][item]) { + infoitem = lib.characterPack[itemx][item]; break; + } + } + } + node.node.name.innerHTML = get.slimName(item); + if (lib.config.buttoncharacter_style == 'default' || lib.config.buttoncharacter_style == 'simple') { + if (lib.config.buttoncharacter_style == 'simple') { + node.node.group.style.display = 'none'; + } + node.classList.add('newstyle'); + node.node.name.dataset.nature = get.groupnature(get.bordergroup(infoitem)); + node.node.group.dataset.nature = get.groupnature(get.bordergroup(infoitem), 'raw'); + ui.create.div(node.node.hp); + var hp = get.infoHp(infoitem[2]), maxHp = get.infoMaxHp(infoitem[2]), hujia = get.infoHujia(infoitem[2]); + var str = get.numStr(hp); + if (hp != maxHp) { + str += '/'; + str += get.numStr(maxHp); + } + var textnode = ui.create.div('.text', str, node.node.hp); + if (infoitem[2] == 0) { + node.node.hp.hide(); + } + else if (get.infoHp(infoitem[2]) <= 3) { + node.node.hp.dataset.condition = 'mid'; + } + else { + node.node.hp.dataset.condition = 'high'; + } + if (hujia > 0) { + ui.create.div(node.node.hp, '.shield'); + ui.create.div('.text', get.numStr(hujia), node.node.hp); + } + } + else { + var hp = get.infoHp(infoitem[2]); + var maxHp = get.infoMaxHp(infoitem[2]); + var shield = get.infoHujia(infoitem[2]); + if (maxHp > 14) { + if (typeof infoitem[2] == 'string') node.node.hp.innerHTML = infoitem[2]; + else node.node.hp.innerHTML = get.numStr(infoitem[2]); + node.node.hp.classList.add('text'); + } + else { + for (var i = 0; i < maxHp; i++) { + var next = ui.create.div('', node.node.hp); + if (i >= hp) next.classList.add('exclude'); + } + for (var i = 0; i < shield; i++) { + ui.create.div(node.node.hp, '.shield'); + } + } + } + if (node.node.hp.childNodes.length == 0) { + node.node.name.style.top = '8px'; + } + if (node.node.name.querySelectorAll('br').length >= 4) { + node.node.name.classList.add('long'); + if (lib.config.buttoncharacter_style == 'old') { + node.addEventListener('mouseenter', ui.click.buttonnameenter); + node.addEventListener('mouseleave', ui.click.buttonnameleave); + } + } + node.node.intro.innerHTML = lib.config.intro; + if (!noclick) { + lib.setIntro(node); + } + if (infoitem[1]) { + if (double) { + node.node.group.innerHTML = double.reduce((previousValue, currentValue) => `${previousValue}
          ${get.translation(currentValue)}
          `, ''); + if (double.length > 4) if (new Set([5, 6, 9]).has(double.length)) node.node.group.style.height = '48px'; + else node.node.group.style.height = '64px'; + } + else node.node.group.innerHTML = `
          ${get.translation(infoitem[1])}
          `; + node.node.group.style.backgroundColor = get.translation(`${get.bordergroup(infoitem)}Color`); + } + else { + node.node.group.style.display = 'none'; + } + if (node._replaceButton) { + var intro = ui.create.div('.button.replaceButton', node); + node.node.replaceButton = intro; + intro.innerHTML = '切换'; + intro._node = node; + intro.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function () { + _status.tempNoButton = true; + var node = this._node; + var list = lib.characterReplace[node._link]; + var link = node.link; + var index = list.indexOf(link); + if (index == list.length - 1) index = 0; + else index++; + link = list[index]; + node.link = link; + node.refresh(node, link); + setTimeout(function () { + delete _status.tempNoButton; + }, 200); + }); + } + }; + node.refresh = func; + node.refresh(node, item); + + return node; + }, + /** + * @returns { import("../library/index.js").Button } + */ + characterx: (item, type, position, noclick, node) => { + return ui.create.buttonPresets.character(item, type, position, noclick, node); + }, + /** + * @returns { import("../library/index.js").Button } + */ + player: (item, type, position, noclick, node) => { + if (node) { + node.classList.add('button'); + node.classList.add('character'); + node.style.display = ''; + } + else { + node = ui.create.div('.button.character', position); + } + node._link = item; + node.link = item; + node.node = { + name: ui.create.div('.name', node), + intro: ui.create.div('.intro', node) + }; + if (item.name && item.name.startsWith('unknown')) { + if (item.node && item.node.name_seat) { + node.classList.add('cardbg'); + ui.create.div('.avatar_name', node, get.translation(item.name)); + } + else { + node.setBackground(item.name1, 'character'); + } + } + else { + node.setBackground(item.name, 'character'); + } + return node; + } + }; + static button(item, type, position, noClick, button) { return new lib.element.Button(item, type, position, noClick, button); } + static buttons(list, type, position, noclick, zoom) { + var buttons = []; + var pre = (typeof type == 'string' && type.slice(0, 3) == 'pre'); + if (pre) { + if (!_status.prebutton) { + _status.prebutton = []; + lib.onfree.push(function () { + for (var i = 0; i < _status.prebutton.length; i++) { + if (_status.prebutton[i].activate) { + _status.prebutton[i].activate(); + } + } + delete _status.prebutton; + }); + } + } + var fragment = document.createDocumentFragment(); + for (var i = 0; i < list.length; i++) { + if (pre) { + buttons.push(ui.create.prebutton(list[i], type.slice(3), fragment, noclick)); + } + else { + buttons.push(ui.create.button(list[i], type, fragment, noclick)); + } + } + if (position) position.appendChild(fragment); + return buttons; + } + static textbuttons(list, dialog, noclick) { + for (var item of list) { + var str, link; + if (Array.isArray(item)) { + str = item[1]; + link = item[0]; + } + else { + str = item; + link = item; + } + if (!str.startsWith(''; + var next = dialog.add(str); + if (!noclick) next.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.button); + next.firstChild.link = link; + Object.setPrototypeOf(next, lib.element.Button.prototype); + dialog.buttons.add(next.firstChild); + } + } + static player(position, noclick) { return new lib.element.Player(position).build(noclick); } + static connectPlayers(ip) { + ui.updateConnectPlayerPositions(); + game.connectPlayers = []; + const configOL = lib.configOL; + const numberOfPlayers = parseInt(configOL.player_number) || configOL.number; + for (let position = 0; position < numberOfPlayers; position++) { + const player = ui.create.player(ui.window); + player.dataset.position = position; + player.classList.add('connect'); + game.connectPlayers.push(player); + } + + var bar = ui.create.div(ui.window); + bar.style.height = '20px'; + bar.style.width = '80%'; + bar.style.left = '10%'; + bar.style.top = 'calc(200% / 7 - 120px + 5px)'; + bar.style.textAlign = 'center'; + var ipbar = ui.create.div('.shadowed', ip, bar); + ipbar.style.padding = '4px'; + ipbar.style.borderRadius = '2px'; + ipbar.style.position = 'relative'; + + var button = ui.create.div('.menubutton.large.highlight.connectbutton.connectbutton1.pointerdiv', game.online ? '退出联机' : '开始游戏', ui.window, function () { + if (button.clicked) return; + if (game.online) { + if (game.onlinezhu) { + game.send('startGame'); + } + else { + game.saveConfig('tmp_owner_roomId'); + game.saveConfig('tmp_user_roomId'); + game.saveConfig('reconnect_info'); + game.reload(); + } + } + else { + var num = 0; + for (var i of game.connectPlayers) { + if (!i.nickname && !i.classList.contains('unselectable2')) num++; + } + if (num >= lib.configOL.number - 1) { + alert('至少要有两名玩家才能开始游戏!'); + return; + } + game.resume(); + } + button.delete(); + bar.delete(); + shareButton.delete(); + delete ui.connectStartButton; + delete ui.connectStartBar; + delete ui.connectShareButton; + button.clicked = true; + }); + + var shareButton = ui.create.div('.menubutton.large.highlight.connectbutton.connectbutton2.pointerdiv', '分享房间', ui.window, function () { + var text = `无名杀-联机-${lib.translate[get.mode()]}-${game.connectPlayers.filter(p => p.avatar).length}/${game.connectPlayers.filter(p => !p.classList.contains('unselectable2')).length}\n${get.connectNickname()}邀请你加入${game.roomId}房间\n联机地址:${game.ip}\n请先通过游戏内菜单-开始-联机中启用“读取邀请链接”选项`; + window.focus(); + if (navigator.clipboard && lib.node) { + navigator.clipboard.writeText(text).then(() => { + game.alert(`分享内容复制成功`); + }).catch(e => { + game.alert(`分享内容复制失败${e || ''}`); + }); + } else { + var input = ui.create.node('textarea', ui.window, { opacity: '0' }); + input.value = text; + input.focus(); + input.select(); + var result = document.execCommand('copy'); + input.blur(); + ui.window.removeChild(input); + game.alert(`分享内容复制${result ? '成功' : '失败'}`); + } + }); + + ui.connectStartButton = button; + ui.connectStartBar = bar; + ui.connectShareButton = shareButton; + } + static players(numberOfPlayers) { + if (numberOfPlayers === 0) { + return; + } + if (numberOfPlayers == undefined) numberOfPlayers = lib.configOL.number; + if (numberOfPlayers == undefined) numberOfPlayers = get.playerNumber(); + if (typeof numberOfPlayers == 'string') { + numberOfPlayers = parseInt(numberOfPlayers); + } + if (!numberOfPlayers) numberOfPlayers = 5; + for (let ordinal = 0; ordinal < numberOfPlayers; ordinal++) { + const player = ui.create.player().addTempClass('start'); + game.players.push(player); + player.dataset.position = ordinal; + } + const players = game.players; + for (let ordinal = 0; ordinal < players.length; ordinal++) { + if (ordinal > 0) { + players[ordinal].previous = players[ordinal - 1]; + players[ordinal].previousSeat = players[ordinal - 1]; + } + if (ordinal < players.length - 1) { + players[ordinal].next = players[ordinal + 1]; + players[ordinal].nextSeat = players[ordinal + 1]; + } + } + players[0].previous = players[players.length - 1]; + players[0].previousSeat = players[players.length - 1]; + players[players.length - 1].next = players[0]; + players[players.length - 1].nextSeat = players[0]; + ui.arena.setNumber(numberOfPlayers); + players.forEach(player => ui.arena.appendChild(player)); + return players; + } + static me(hasme) { + ui.mebg = ui.create.div('#mebg', ui.arena); + ui.me = ui.create.div('#me', ui.arena).addTempClass('start'); + ui.handcards1Container = ui.create.div('#handcards1', ui.me); + ui.handcards2Container = ui.create.div('#handcards2', ui.me); + ui.arena.classList.remove('nome'); + if (lib.config.mousewheel && !lib.config.touchscreen) { + ui.handcards1Container.onmousewheel = ui.click.mousewheel; + ui.handcards2Container.onmousewheel = ui.click.mousewheel; + } + ui.handcards1Container.ontouchstart = ui.click.touchStart; + ui.handcards2Container.ontouchstart = ui.click.touchStart; + ui.handcards1Container.ontouchmove = ui.click.touchScroll; + ui.handcards2Container.ontouchmove = ui.click.touchScroll; + ui.handcards1Container.style.webkitOverflowScrolling = 'touch'; + ui.handcards2Container.style.webkitOverflowScrolling = 'touch'; + + if (hasme && game.me) { + ui.handcards1 = game.me.node.handcards1; + ui.handcards2 = game.me.node.handcards2; + ui.handcards1Container.appendChild(ui.handcards1); + ui.handcards2Container.appendChild(ui.handcards2); + // ui.updatehl(); + } + else if (game.players.length) { + game.me = game.players[0]; + ui.handcards1 = game.me.node.handcards1; + ui.handcards2 = game.me.node.handcards2; + ui.handcards1Container.appendChild(ui.handcards1); + ui.handcards2Container.appendChild(ui.handcards2); + // ui.updatehl(); + } + } + static card(position, info, noclick) { return new lib.element.Card(position).build(info, noclick); } + static cardsAsync() { + if (lib.onfree) { + _status.waitingForCards = Array.from(arguments); + lib.onfree.push(function () { + if (_status.waitingForCards) { + ui.create.cards.apply(ui.create, _status.waitingForCards); + delete _status.waitingForCards; + } + }); + } + else { + ui.create.cards.apply(ui.create, arguments); + } + } + static cards(ordered) { + if (_status.brawl) { + if (_status.brawl.cardPile) { + lib.card.list = _status.brawl.cardPile(lib.card.list); + } + if (_status.brawl.orderedPile) { + ordered = true; + } + } + if (!ordered) { + lib.card.list.randomSort(); + } + for (var i = 0; i < lib.card.list.length; i++) { + if (lib.card[lib.card.list[i][2]]) { + if (!lib.card.list[i]._replaced) { + if (!_status.connectMode) { + if (lib.config.bannedcards.includes(lib.card.list[i][2])) continue; + } + else { + if (lib.configOL.bannedcards.includes(lib.card.list[i][2])) continue; + } + if (game.bannedcards && game.bannedcards.includes(lib.card.list[i][2])) continue; + } + lib.inpile.add(lib.card.list[i][2]); + if (lib.card.list[i][2] == 'sha' && lib.card.list[i][3]) lib.inpile_nature.add(lib.card.list[i][3]); + ui.create.card(ui.cardPile).init(lib.card.list[i]); + } + } + lib.inpile.sort(lib.sort.card); + const natures = Array.from(lib.nature.keys()); + lib.inpile_nature.sort(function (a, b) { + return natures.indexOf(a) - natures.indexOf(b); + }); + for (var i in _status.cardtag) { + if (!_status.cardtag[i].length) delete _status.cardtag[i]; + } + game.broadcastAll(function (num, pile, top, cardtag, inpile2) { + if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = '0轮 剩余牌: ' + num; + lib.inpile = pile; + _status.pileTop = top; + _status.cardtag = cardtag; + lib.inpile_nature = inpile2; + }, ui.cardPile.childNodes.length, lib.inpile, ui.cardPile.firstChild, _status.cardtag, lib.inpile_nature); + } + +} + +class Click extends Uninstantable { + static identitycircle() { + var list = []; + this.classList.toggle('transparent'); + for (var i = 0; i < this.parentNode.childNodes.length; i++) { + if (!this.parentNode.childNodes[i].classList.contains('transparent')) { + list.add(this.parentNode.childNodes[i].link[2]); + } + } + var info = this.link; + if (list.length == 1) { + for (var i = 0; i < this.parentNode.childNodes.length; i++) { + if (!this.parentNode.childNodes[i].classList.contains('transparent')) { + var info2 = this.parentNode.childNodes[i].link; + info[0].firstChild.innerHTML = info2[1]; + info[0].dataset.color = info2[2]; + } + } + } + else { + info[0].firstChild.innerHTML = ''; + info[0].dataset.color = ''; + ui.create.identitycircle(list, info[0].firstChild); + } + this._source._guozhanguess = list; + } + static connectEvents() { + if (this.info) { + var button = this; + var layer = ui.create.div('.poplayer', ui.window); + var uiintro = ui.create.dialog('hidden', 'notouchscroll'); + this.classList.add('active'); + if (lib.config.touchscreen) { + lib.setScroll(uiintro.contentContainer); + } + layer.listen(function () { + if (this.clicked) { + this.clicked = false; + return; + } + button.classList.remove('active'); + uiintro.delete(); + this.delete(); + }); + uiintro.listen(function () { + _status.clicked = true; + }); + uiintro.style.zIndex = 21; + uiintro.classList.add('popped'); + uiintro.classList.add('static'); + uiintro.classList.add('onlineclient'); + uiintro.style.width = '180px'; + uiintro.style.height = '300px'; + uiintro.style.left = 'auto'; + uiintro.style.right = '20px'; + uiintro.style.top = 'auto'; + uiintro.style.bottom = '75px'; + + uiintro.refresh = function () { + if (button.focused) return; + uiintro.content.innerHTML = ''; + uiintro.addText('创建约战'); + button.textnode = uiintro.content.lastChild.lastChild; + uiintro.add(''); + uiintro.content.lastChild.style.paddingTop = 0; + button.input = uiintro.content.lastChild.lastChild; + button.input.onfocus = function () { + button.focused = true; + }; + button.input.onblur = function () { + delete button.focused; + }; + if (button.interval) { + button.input.disabled = true; + button.input.style.opacity = 0.6; + if (button.intervaltext) { + button.textnode.innerHTML = button.intervaltext; + } + } + var datenode = ui.create.div(uiintro.content); + datenode.style.marginTop = 0; + datenode.style.whiteSpace = 'nowrap'; + var date = new Date(); + var days = []; + var currentDay = date.getDay(); + if (currentDay == 0) currentDay = 7; + for (var i = 1; i <= 7; i++) { + if (i < currentDay) { + days.push([i.toString(), '下周' + get.cnNumber(i, true)]); + } + else if (i == 7) { + days.push([i.toString(), '周日']); + } + else if (i == currentDay) { + days.push([i.toString(), '今天']); + } + else { + days.push([i.toString(), '周' + get.cnNumber(i, true)]); + } + } + days = days.concat(days.splice(0, currentDay - 1)); + var initday = currentDay + 1; + if (initday > 7) { + initday -= 7; + } + var daysselect = ui.create.selectlist(days, initday.toString(), datenode); + daysselect.style.width = '55px'; + var hours = []; + for (var i = 0; i < 24; i++) { + hours.push([i.toString(), i.toString() + '点']); + } + var hoursselect = ui.create.selectlist(hours, date.getHours().toString(), datenode); + hoursselect.style.marginLeft = '5px'; + hoursselect.style.width = '55px'; + var timeconfirm = ui.create.node('button', '确定', datenode); + timeconfirm.style.marginLeft = '5px'; + timeconfirm.onclick = function () { + if (!button.input.value) { + alert('请填写约战标题'); + return; + } + var date2 = new Date(); + date2.setHours(parseInt(hoursselect.value)); + date2.setMinutes(0); + date2.setSeconds(0); + var deltaday = parseInt(daysselect.value) - currentDay; + if (deltaday < 0) { + deltaday += 7; + } + var utc = date2.getTime() + deltaday * 24 * 3600000; + if (utc < date.getTime()) { + alert('创建失败,时间已过'); + return; + } + if (get.is.banWords(button.input.value)) { + var eventnode = ui.create.div('.menubutton.videotext.onlineevent.pointerdiv', function () { + var that = this; + setTimeout(function () { + if (that.classList.contains('active')) { + if (confirm('确定要离开' + that.info.content + '?')) { + that.classList.remove('active'); + } + } + else { + if (confirm('确定要加入' + that.info.content + '?')) { + that.classList.add('active'); + } + } + }); + }, uiintro.content, 4); + var fakeinfo = { + utc: utc, + day: parseInt(daysselect.value), + hour: parseInt(hoursselect.value), + nickname: get.connectNickname(), + avatar: lib.config.connect_avatar, + content: button.input.value, + create: game.onlineKey, + members: [game.onlineKey], + }; + eventnode.info = fakeinfo; + ui.create.div('.title', fakeinfo.content, eventnode); + var str; + if (fakeinfo.day < currentDay) { + str = '下周'; + } + else { + str = '周'; + } + if (fakeinfo.day == 7) { + str += '日'; + } + else { + str += get.cnNumber(fakeinfo.day, true); + } + str += ' '; + var hour = fakeinfo.hour; + if (hour <= 12) { + if (hour <= 5) { + str += '凌晨'; + } + else if (hour < 12) { + str += '上午'; + } + else { + str += '中午'; + } + str += fakeinfo.hour + '点'; + } + else { + if (hour <= 17) { + str += '下午'; + } + else { + str += '晚上'; + } + str += (fakeinfo.hour - 12) + '点'; + } + ui.create.div('', '已有' + (fakeinfo.members.length) + '人加入', eventnode); + ui.create.div('', '时间:' + str, eventnode); + if (fakeinfo.members.includes(game.onlineKey)) { + eventnode.classList.add('active'); + } + button.input.value = ''; + return; + } + game.send('server', 'events', { + utc: utc, + day: parseInt(daysselect.value), + hour: parseInt(hoursselect.value), + nickname: get.connectNickname(), + avatar: lib.config.connect_avatar, + content: button.input.value + }, game.onlineKey); + }; + + var num = 0; + for (var i = 0; i < button.info.length; i++) { + if (typeof button.info[i].creator == 'string' && button.info[i].creator != game.onlineKey && get.is.banWords(button.info[i].content)) continue; + if (button.info[i].creator == game.onlineKey) { + num++; + } + var eventnode = ui.create.div('.menubutton.videotext.onlineevent.pointerdiv', function () { + var that = this; + if (typeof that.info.creator != 'string') return; + setTimeout(function () { + if (that.classList.contains('active')) { + if (confirm('确定要离开' + that.info.content + '?')) { + game.send('server', 'events', that.info.id, game.onlineKey, 'leave'); + } + } + else { + if (confirm('确定要加入' + that.info.content + '?')) { + game.send('server', 'events', that.info.id, game.onlineKey, 'join'); + } + } + }); + }, uiintro.content); + eventnode.info = button.info[i]; + if (typeof button.info[i].creator == 'string') { + ui.create.div('.title', button.info[i].content, eventnode); + var str; + if (button.info[i].day < currentDay) { + str = '下周'; + } + else { + str = '周'; + } + if (button.info[i].day == 7) { + str += '日'; + } + else { + str += get.cnNumber(button.info[i].day, true); + } + str += ' '; + var hour = button.info[i].hour; + if (hour <= 12) { + if (hour <= 5) { + str += '凌晨'; + } + else if (hour < 12) { + str += '上午'; + } + else { + str += '中午'; + } + str += button.info[i].hour + '点'; + } + else { + if (hour <= 17) { + str += '下午'; + } + else { + str += '晚上'; + } + str += (button.info[i].hour - 12) + '点'; + } + ui.create.div('', '创建者:' + (button.info[i].nickname), eventnode); + //ui.create.div('','创建者:'+(button.info[i].nickname)+'
          ID:'+button.info[i].creator,eventnode); + ui.create.div('', '已有' + (button.info[i].members.length) + '人加入', eventnode); + ui.create.div('', '时间:' + str, eventnode); + if (button.info[i].members.includes(game.onlineKey)) { + eventnode.classList.add('active'); + } + } + else { + ui.create.div('.title', button.info[i].title, eventnode); + ui.create.div('', button.info[i].content, eventnode); + ui.create.div('', '创建者:' + (button.info[i].nickname), eventnode); + } + } + if (num >= 3) { + button.input.disabled = true; + button.input.style.opacity = 0.6; + hoursselect.disabled = true; + daysselect.disabled = true; + timeconfirm.disabled = true; + } + }; + uiintro.refresh(); + ui.window.appendChild(uiintro); + _status.connectEventsCallback = function () { + if (uiintro.parentNode == ui.window) { + uiintro.refresh(); + } + }; + } + } + static connectClients() { + if (this.info) { + var button = this; + var layer = ui.create.div('.poplayer', ui.window); + var uiintro = ui.create.dialog('hidden', 'notouchscroll'); + this.classList.add('active'); + if (lib.config.touchscreen) { + lib.setScroll(uiintro.contentContainer); + } + layer.listen(function () { + if (this.clicked) { + this.clicked = false; + return; + } + button.classList.remove('active'); + uiintro.delete(); + this.delete(); + }); + uiintro.listen(function () { + _status.clicked = true; + }); + uiintro.style.zIndex = 21; + uiintro.classList.add('popped'); + uiintro.classList.add('static'); + uiintro.classList.add('onlineclient'); + uiintro.style.width = '180px'; + uiintro.style.height = '300px'; + uiintro.style.left = 'auto'; + uiintro.style.right = '20px'; + uiintro.style.top = 'auto'; + uiintro.style.bottom = '75px'; + + uiintro.refresh = function () { + if (button.focused) return; + uiintro.content.innerHTML = ''; + uiintro.addText('发状态'); + button.textnode = uiintro.content.lastChild.lastChild; + uiintro.add(''); + uiintro.content.lastChild.style.paddingTop = 0; + button.input = uiintro.content.lastChild.lastChild; + button.input.onfocus = function () { + button.focused = true; + }; + button.input.onblur = function () { + delete button.focused; + }; + if (button.interval) { + button.input.disabled = true; + button.input.style.opacity = 0.6; + if (button.intervaltext) { + button.textnode.innerHTML = button.intervaltext; + } + } + button.input.onkeydown = function (e) { + if (e.keyCode == 13 && !this.disabled) { + game.send('server', 'status', this.value); + this.blur(); + this.disabled = true; + this.style.opacity = 0.6; + button.textnode.innerHTML = '发状态(10)'; + button.intervaltext = button.textnode.innerHTML; + var num = 10; + var that = this; + button.input.disabled = true; + button.input.style.opacity = 0.6; + this.value = ''; + button.interval = setInterval(function () { + num--; + if (num > 0) { + button.textnode.innerHTML = '发状态(' + num + ')'; + button.intervaltext = button.textnode.innerHTML; + } + else { + button.textnode.innerHTML = '发状态'; + button.input.disabled = false; + button.input.style.opacity = ''; + clearInterval(button.interval); + delete button.interval; + delete button.intervaltext; + } + }, 1000); + } + }; + + for (var i = 0; i < button.info.length; i++) { + var node = ui.create.div('.menubutton.videonode.pointerdiv', uiintro.content); + ui.create.div('.menubutton.videoavatar', node).setBackground(button.info[i][1] || 'caocao', 'character'); + if (button.info[i][4] == game.wsid) { + ui.create.div('.name', '' + (button.info[i][0] || '无名玩家'), node); node.isme = true; + } + else if (button.info[i][2]) { + ui.create.div('.name', (button.info[i][0] || '无名玩家'), node); + } + else { + ui.create.div('.name', '' + (button.info[i][0] || '无名玩家'), node); + } + //show ID + //ui.create.div('.videostatus',node,button.info[i][5]); + //node.classList.add('videonodestatus'); + if (button.info[i][3]) { + ui.create.div('.videostatus', node, button.info[i][3].slice(0, 80)); + node.classList.add('videonodestatus'); + } + } + }; + + uiintro.refresh(); + ui.window.appendChild(uiintro); + _status.connectClientsCallback = function () { + if (uiintro.parentNode == ui.window) { + uiintro.refresh(); + } + }; + } + } + static autoskin() { + if (!lib.config.change_skin) return; + var players = game.filterPlayer(); + var change = function (player, num, callback) { + if (num == '1') { + ui.click.skin(player.node.avatar, player.name, callback); + } + else { + ui.click.skin(player.node.avatar2, player.name2, callback); + } + }; + var finish = function () { + if (lib.config.change_skin_auto != 'off') { + _status.skintimeout = setTimeout(ui.click.autoskin, parseInt(lib.config.change_skin_auto)); + } + }; + var autoskin = function () { + if (players.length) { + var player = players.randomRemove(); + var list = []; + if (player.name && !player.isUnseen(0)) { + list.push('1'); + } + if (player.name2 && !player.isUnseen(1)) { + list.push('2'); + } + if (list.length) { + change(player, list.randomRemove(), function (bool) { + if (bool) { + finish(); + } + else if (list.length) { + change(player, list[0], function (bool) { + if (bool) { + finish(); + } + else { + autoskin(); + } + }); + } + else { + autoskin(); + } + }); + } + else { + autoskin(); + } + } + }; + autoskin(); + } + static skin(avatar, name, callback) { + var num = 1; + if (name.startsWith('gz_')) { + name = name.slice(3); + } + if (lib.config.skin[name]) { + num = lib.config.skin[name] + 1; + } + var fakeavatar = avatar.cloneNode(true); + var finish = function (bool) { + var player = avatar.parentNode; + if (bool) { + fakeavatar.style.boxShadow = 'none'; + player.insertBefore(fakeavatar, avatar.nextSibling); + setTimeout(function () { + fakeavatar.delete(); + }, 100); + } + if (bool && lib.config.animation && !lib.config.low_performance) { + player.$rare(); + } + if (callback) { + callback(bool); + } + }; + var img = new Image(); + img.onload = function () { + lib.config.skin[name] = num; + game.saveConfig('skin', lib.config.skin); + avatar.style.backgroundImage = 'url("' + img.src + '")'; + finish(true); + }; + img.onerror = function () { + if (lib.config.skin[name]) { + finish(true); + } + else { + finish(false); + } + delete lib.config.skin[name]; + game.saveConfig('skin', lib.config.skin); + avatar.setBackground(name, 'character'); + }; + img.src = lib.assetURL + 'image/skin/' + name + '/' + num + '.jpg'; + } + static touchpop(forced) { + if (lib.config.touchscreen || forced) { + _status.touchpopping = true; + clearTimeout(_status.touchpoppingtimeout); + _status.touchpoppingtimeout = setTimeout(function () { + _status.touchpopping = false; + }, 600); + } + } + static exit() { + if (game.servermode && lib.config.reconnect_info && _status.over) { + if (!_status.roomtimeout) { + lib.config.reconnect_info[2] = game.roomId; + game.saveConfig('reconnect_info', lib.config.reconnect_info); + } + game.reload(); + return; + } + else { + if (typeof game.roomId != 'string') { + game.saveConfig('reconnect_info'); + } + } + if (!ui.exit || !ui.exit.stay) { + if (lib.config.reconnect_info) { + lib.config.reconnect_info.length = 1; + game.saveConfig('reconnect_info', lib.config.reconnect_info); + } + game.saveConfig('tmp_user_roomId', undefined, false, function () { + game.reload(); + }); + } + else { + game.reload(); + } + } + static shortcut(show) { + if (show === false) { + ui.shortcut.classList.add('hidden'); + } + else { + ui.shortcut.classList.toggle('hidden'); + } + if (ui.shortcut.classList.contains('hidden')) { + ui.favmode.style.display = 'none'; + if (window.StatusBar && lib.config.show_statusbar_ios == 'auto') { + document.body.classList.remove('statusbar'); + window.StatusBar.hide(); + } + ui.window.classList.remove('shortcutpaused'); + } + else { + if (lib.config.show_favmode) { + ui.favmode.style.display = ''; + } + if (window.StatusBar && lib.config.show_statusbar_ios == 'auto') { + document.body.classList.add('statusbar'); + window.StatusBar.overlaysWebView(true); + window.StatusBar.backgroundColorByName('black'); + window.StatusBar.show(); + } + if (_status.auto) { + ui.shortcut.autobutton.classList.add('active'); + } + else { + ui.shortcut.autobutton.classList.remove('active'); + } + ui.window.classList.add('shortcutpaused'); + } + } + static favouriteCharacter(e) { + if (typeof this.link == 'string') { + if (this.innerHTML == '添加收藏') { + this.innerHTML = '移除收藏'; + lib.config.favouriteCharacter.add(this.link); + } + else { + this.innerHTML = '添加收藏'; + lib.config.favouriteCharacter.remove(this.link); + } + if (ui.favouriteCharacter) { + if (lib.config.favouriteCharacter.includes(this.link)) { + for (var i = 0; i < ui.favouriteCharacter.childElementCount; i++) { + if (ui.favouriteCharacter.childNodes[i].link == this.link) { + break; + } + } + if (i == ui.favouriteCharacter.childElementCount) { + ui.create.button(this.link, 'character', ui.favouriteCharacter).listen(function (e) { + this._banning = 'offline'; + ui.click.touchpop(); + ui.click.intro.call(this, e); + _status.clicked = false; + delete this._banning; + }).classList.add('noclick'); + } + } + else { + for (var i = 0; i < ui.favouriteCharacter.childElementCount; i++) { + if (ui.favouriteCharacter.childNodes[i].link == this.link) { + ui.favouriteCharacter.childNodes[i].remove(); + break; + } + } + } + var shownode = false; + for (var i = 0; i < lib.config.favouriteCharacter.length; i++) { + var favname = lib.config.favouriteCharacter[i]; + if (lib.character[favname]) { + shownode = true; break; + } + } + if (shownode) { + ui.favouriteCharacter.node.style.display = ''; + } + else { + ui.favouriteCharacter.node.style.display = 'none'; + } + } + game.saveConfig('favouriteCharacter', lib.config.favouriteCharacter); + } + e.stopPropagation(); + } + static buttonnameenter() { + if (this.buttonscrollinterval) { + clearInterval(this.buttonscrollinterval); + } + var node = this.node.name; + if (node.offsetHeight < node.scrollHeight) { + var that = this; + var num = 40; + that.buttonscrollinterval = setInterval(function () { + if (node.scrollTop + node.offsetHeight >= node.scrollHeight) { + clearInterval(that.buttonscrollinterval); + delete that.buttonscrollinterval; + } + else { + if (num > 0) { + num--; + } + else { + node.scrollTop += 2; + } + } + }, 16); + } + } + static buttonnameleave() { + if (this.buttonscrollinterval) { + clearInterval(this.buttonscrollinterval); + } + var node = this.node.name; + if (node.offsetHeight < node.scrollHeight) { + var that = this; + that.buttonscrollinterval = setInterval(function () { + if (node.scrollTop == 0) { + clearInterval(that.buttonscrollinterval); + delete that.buttonscrollinterval; + } + else { + node.scrollTop -= 2; + } + }, 16); + } + } + static dragtouchdialog(e) { + if (e.touches.length > 1 && + !this.classList.contains('popped') && + !this.classList.contains('fixed')) { + _status.draggingtouchdialog = this; + this._dragorigin = { + clientX: e.touches[0].clientX, + clientY: e.touches[0].clientY, + }; + if (!this._dragtransform) { + this._dragtransform = [0, 0]; + } + this._dragorigintransform = this._dragtransform.slice(0); + e.preventDefault(); + e.stopPropagation(); + } + } + static identity(e) { + if (_status.dragged) return; + _status.clicked = true; + if (!game.getIdentityList) return; + if (_status.video) return; + if (this.parentNode.forceShown) return; + if (!_status.connectMode && this.parentNode.ai.stratagem_camouflage && get.config('nei_auto_mark_camouflage') && game.me.identity == 'nei') return; + if (_status.clickingidentity) { + for (var i = 0; i < _status.clickingidentity[1].length; i++) { + _status.clickingidentity[1][i].delete(); + _status.clickingidentity[1][i].style.transform = ''; + } + if (_status.clickingidentity[0] == this.parentNode) { + delete _status.clickingidentity; + return; + } + } + var list = game.getIdentityList(this.parentNode); + if (!list) return; + if (lib.config.mark_identity_style == 'click') { + var list2 = []; + for (var i in list) { + list2.push(i); + } + list2.push(list2[0]); + for (var i = 0; i < list2.length; i++) { + if (this.firstChild.innerHTML == list[list2[i]]) { + this.firstChild.innerHTML = list[list2[i + 1]]; + this.dataset.color = list2[i + 1]; + break; + } + } + } + else { + if (get.mode() == 'guozhan') { + list = { wei: '魏', shu: '蜀', wu: '吴', qun: '群', jin: '晋' }; + if (_status.forceKey) list.key = '键'; + } + var list2 = get.copy(list); + if (game.getIdentityList2) { + game.getIdentityList2(list2); + } + var rect = this.parentNode.getBoundingClientRect(); + this._customintro = function (uiintro) { + if (get.mode() == 'guozhan') { + uiintro.clickintro = true; + } + else { + uiintro.touchclose = true; + } + // if(lib.config.theme!='woodden'){ + uiintro.classList.add('woodbg'); + // } + if (get.is.phoneLayout()) { + uiintro.style.width = '100px'; + } + else { + uiintro.style.width = '85px'; + } + var source = this.parentNode; + for (var i in list) { + var node = ui.create.div(); + node.classList.add('guessidentity'); + node.classList.add('pointerdiv'); + ui.create.div('.menubutton.large', list2[i], node); + if (!get.is.phoneLayout()) { + node.firstChild.style.fontSize = '24px'; + node.firstChild.style.lineHeight = '24px'; + } + if (get.mode() == 'guozhan') { + if (source._guozhanguess) { + if (!source._guozhanguess.includes(i)) { + node.classList.add('transparent'); + } + } + node._source = source; + node.listen(ui.click.identitycircle); + } + else { + node.listen(function () { + var info = this.link; + info[0].firstChild.innerHTML = info[1]; + info[0].dataset.color = info[2]; + _status.clicked = false; + }); + } + + node.link = [this, list[i], i]; + uiintro.add(node); + } + }; + ui.click.touchpop(); + ui.click.intro.call(this, { + clientX: (rect.left + rect.width), + clientY: (rect.top) + }); + // var nodes=[]; + // _status.clickingidentity=[this.parentNode,nodes]; + // var num=1; + // var dy=30; + // if(get.is.phoneLayout()){ + // dy=45; + // } + // for(var i in list){ + // if(this.firstChild.innerHTML!=list[i]){ + // var node=ui.create.div('.identity.hidden.pointerdiv',this.parentNode,ui.click.identity2); + // ui.create.div(node).innerHTML=list[i]; + // node.dataset.color=i; + // ui.refresh(node); + // node.show(); + // var transstr='translateY('+((num++)*dy)+'px)'; + // if(get.is.phoneLayout()){ + // transstr+=' scale(1.3)'; + // } + // if(get.is.newLayout()&&this.parentNode.classList.contains('linked')){ + // transstr+=' rotate(90deg)'; + // } + // node.style.transform=transstr; + // nodes.push(node); + // } + // } + } + } + static identity2() { + if (_status.clickingidentity) { + _status.clicked = true; + var player = _status.clickingidentity[0]; + var nodes = _status.clickingidentity[1]; + player.node.identity.dataset.color = this.dataset.color; + player.node.identity.firstChild.innerHTML = this.firstChild.innerHTML; + for (var i = 0; i < nodes.length; i++) { + nodes[i].delete(); + nodes[i].style.transform = ''; + } + delete _status.clickingidentity; + } + } + static roundmenu() { + game.closeConnectMenu(); + switch (lib.config.round_menu_func) { + case 'system': + game.closePopped(); + ui.system1.classList.add('shown'); + ui.system2.classList.add('shown'); + game.closeMenu(); + ui.click.shortcut(); + break; + case 'menu': + if (ui.click.configMenu) { + game.closePopped(); + game.pause2(); + ui.click.configMenu(); + ui.system1.classList.remove('shown'); + ui.system2.classList.remove('shown'); + } + break; + case 'pause': + ui.click.pause(); + break; + case 'auto': + ui.click.auto(); + break; + } + _status.clicked = true; + } + static pausehistory() { + if (!lib.config.auto_popped_history) return; + if (!ui.sidebar.childNodes.length) return; + var uiintro = ui.create.dialog('hidden'); + uiintro.style.maxHeight = '400px'; + uiintro.add(ui.sidebar); + return uiintro; + } + static pauseconfig() { + if (!lib.config.auto_popped_config) return; + if (get.is.phoneLayout()) return; + var uiintro = ui.create.dialog('hidden'); + uiintro.listen(function (e) { + e.stopPropagation(); + }); + + var rows = Math.floor(lib.config.all.mode.length / 3); + uiintro.type = 'config'; + var modes = lib.config.modeorder || lib.config.all.mode.slice(0); + for (var i = 0; i < modes.length; i++) { + if (!lib.config.all.mode.includes(modes[i])) { + modes.splice(i--, 1); + } + } + for (var k = 0; k < rows; k++) { + var node = ui.create.div('.newgame.pointernode'); + for (var i = 0; i < 3 && i + k * 3 < modes.length; i++) { + var thismode = modes[i + k * 3]; + var div = ui.create.div(thismode == (_status.sourcemode || lib.config.mode) ? '.underlinenode.on' : '.underlinenode', node); + div.innerHTML = lib.translate[thismode]; + div.link = thismode; + div.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function () { + game.saveConfig('mode', this.link); + localStorage.setItem(lib.configprefix + 'directstart', true); + game.reload(); + }); + } + uiintro.add(node); + } + + return uiintro; + } + static cardPileButton() { + var uiintro = ui.create.dialog('hidden'); + uiintro.listen(function (e) { + e.stopPropagation(); + }); + var num; + if (game.online) { + num = _status.cardPileNum || 0; + } + else { + num = ui.cardPile.childNodes.length; + } + uiintro.add('剩余 ' + num); + + if (_status.connectMode) return uiintro; + uiintro.add('
          轮数 ' + game.roundNumber + '    洗牌 ' + game.shuffleNumber + '
          '); + uiintro.add('
          弃牌堆
          '); + if (ui.discardPile.childNodes.length) { + var list = []; + for (var i = 0; i < ui.discardPile.childNodes.length; i++) { + list.unshift(ui.discardPile.childNodes[i]); + } + uiintro.addSmall([list, 'card']); + } + else { + uiintro.add('
          '); + } + return uiintro; + } + static chat() { + ui.system1.classList.add('shown'); + ui.system2.classList.add('shown'); + + var uiintro = ui.create.dialog('hidden'); + uiintro.listen(function (e) { + e.stopPropagation(); + }); + + var list = ui.create.div('.caption'); + if (get.is.phoneLayout()) { + list.style.maxHeight = '110px'; + } + else { + list.style.maxHeight = '220px'; + } + list.style.overflow = 'scroll'; + lib.setScroll(list); + uiintro.contentContainer.style.overflow = 'hidden'; + + var input; + var addEntry = function (info, clear) { + if (list._chatempty) { + list.innerHTML = ''; + delete list._chatempty; + } + var node = ui.create.div('.text.chat'); + node.innerHTML = info[0] + ': ' + info[1]; + list.appendChild(node); + list.scrollTop = list.scrollHeight; + uiintro.style.height = uiintro.content.scrollHeight + 'px'; + }; + _status.addChatEntry = addEntry; + _status.addChatEntry._origin = uiintro; + if (lib.chatHistory.length) { + for (var i = 0; i < lib.chatHistory.length; i++) { + addEntry(lib.chatHistory[i]); + } + } + else { + list._chatempty = true; + list.appendChild(ui.create.div('.text.center', '无聊天记录')); + } + uiintro.add(list); + uiintro.style.height = uiintro.content.offsetHeight + 'px'; + list.scrollTop = list.scrollHeight; + + if (!_status.chatValue) _status.chatValue = ''; + var node = uiintro.add(''); + node.style.paddingTop = 0; + node.style.marginBottom = '16px'; + input = node.firstChild; + input.style.width = 'calc(100% - 20px)'; + input.onchange = function () { + _status.chatValue = input.value; + }; + input.onkeydown = function (e) { + if (e.keyCode == 13 && input.value) { + var player = game.me; + var str = input.value; + if (!player) { + if (game.connectPlayers) { + if (game.online) { + for (var i = 0; i < game.connectPlayers.length; i++) { + if (game.connectPlayers[i].playerid == game.onlineID) { + player = game.connectPlayers[i]; break; + } + } + } + else { + player = game.connectPlayers[0]; + } + } + } + if (!player) return; + if (get.is.banWords(input.value)) { + player.say(input.value); + input.value = ''; + _status.chatValue = ''; + } + else { + if (game.online) { + game.send('chat', game.onlineID, str); + } + else { + player.chat(str); + } + input.value = ''; + _status.chatValue = ''; + } + } + e.stopPropagation(); + }; + uiintro._onopen = function () { + input.focus(); + list.scrollTop = list.scrollHeight; + }; + uiintro._heightfixed = true; + var emotionTitle = ui.create.div('.text.center', '聊天表情', function () { + if (emotionTitle.innerHTML == '快捷语音') { + emotionTitle.innerHTML = '聊天表情'; + list2.remove(); + list3.remove(); + uiintro.add(list1); + while (list2.childNodes.length) { + list2.firstChild.remove(); + } + } + else { + emotionTitle.innerHTML = '快捷语音'; + list1.remove(); + list2.remove(); + uiintro.add(list3); + } + }); + uiintro.add(emotionTitle); + var list1 = ui.create.div(''); + if (get.is.phoneLayout()) { + list1.style.height = '110px'; + } + else { + list1.style.height = '150px'; + } + list1.style.overflow = 'scroll'; + lib.setScroll(list1); + uiintro.add(list1); + uiintro.style.height = uiintro.content.scrollHeight + 'px'; + var list2 = ui.create.div(''); + if (get.is.phoneLayout()) { + list2.style.height = '110px'; + } + else { + list2.style.height = '150px'; + } + list2.style.overflow = 'scroll'; + lib.setScroll(list2); + //uiintro.add(list2); + for (var i in lib.emotionList) { + var emotionPack = ui.create.div('.card.fullskin', '', function () { + emotionTitle.innerHTML = get.translation(this.pack); + for (var j = 1; j <= lib.emotionList[this.pack]; j++) { + var emotionButton = ui.create.div('.card.fullskin', '', function () { + var player = game.me; + if (!player) { + if (game.connectPlayers) { + if (game.online) { + for (var i = 0; i < game.connectPlayers.length; i++) { + if (game.connectPlayers[i].playerid == game.onlineID) { + player = game.connectPlayers[i]; break; + } + } + } + else { + player = game.connectPlayers[0]; + } + } + } + if (!player) return; + if (game.online) { + game.send('emotion', game.onlineID, this.pack, this.emotionID); + } + else { + player.emotion(this.pack, this.emotionID); + } + }); + emotionButton.emotionID = j; + emotionButton.pack = this.pack; + emotionButton.style.height = '50px'; + emotionButton.style.width = '50px'; + list2.appendChild(emotionButton); + } + list1.remove(); + uiintro.add(list2); + }); + emotionPack.pack = i; + emotionPack.style.height = '50px'; + emotionPack.style.width = '50px'; + list1.appendChild(emotionPack); + } + list1.scrollTop = list1.scrollHeight; + uiintro.style.height = uiintro.content.scrollHeight + 'px'; + var list3 = ui.create.div('.caption'); + if (get.is.phoneLayout()) { + list3.style.height = '110px'; + } + else { + list3.style.height = '150px'; + } + list3.style.overflow = 'scroll'; + lib.setScroll(list3); + for (var i = 0; i < lib.quickVoice.length; i++) { + var node = ui.create.div('.text.chat', function () { + var player = game.me; + var str = this.innerHTML; + if (!player) { + if (game.connectPlayers) { + if (game.online) { + for (var i = 0; i < game.connectPlayers.length; i++) { + if (game.connectPlayers[i].playerid == game.onlineID) { + player = game.connectPlayers[i]; break; + } + } + } + else { + player = game.connectPlayers[0]; + } + } + } + if (!player) return; + if (game.online) { + game.send('chat', game.onlineID, str); + } + else { + player.chat(str); + } + }); + node.innerHTML = lib.quickVoice[i]; + list3.appendChild(node); + } + list3.scrollTop = list1.scrollHeight; + return uiintro; + } + static volumn() { + var uiintro = ui.create.dialog('hidden'); + uiintro.listen(function (e) { + e.stopPropagation(); + }); + uiintro.add('背景音乐'); + var vol1 = ui.create.div('.volumn'); + uiintro.add(vol1); + for (var i = 0; i < 8; i++) { + var span = document.createElement('span'); + span.link = i + 1; + span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.volumn_background); + if (i < lib.config.volumn_background) { + span.innerHTML = '●'; + } + else { + span.innerHTML = '○'; + } + vol1.appendChild(span); + } + uiintro.add('游戏音效'); + + var vol2 = ui.create.div('.volumn'); + uiintro.add(vol2); + for (var i = 0; i < 8; i++) { + var span = document.createElement('span'); + span.link = i + 1; + span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.volumn_audio); + if (i < lib.config.volumn_audio) { + span.innerHTML = '●'; + } + else { + span.innerHTML = '○'; + } + vol2.appendChild(span); + } + uiintro.add(ui.create.div('.placeholder')); + return uiintro; + } + static volumn_background(e) { + if (_status.dragged) return; + var volume = this.link; + if (volume === 1 && lib.config.volumn_background === 1) { + volume = 0; + } + game.saveConfig('volumn_background', volume); + ui.backgroundMusic.volume = volume / 8; + for (var i = 0; i < 8; i++) { + if (i < lib.config.volumn_background) { + this.parentNode.childNodes[i].innerHTML = '●'; + } + else { + this.parentNode.childNodes[i].innerHTML = '○'; + } + } + e.stopPropagation(); + } + static volumn_audio(e) { + if (_status.dragged) return; + var volume = this.link; + if (volume === 1 && lib.config.volumn_audio === 1) { + volume = 0; + } + game.saveConfig('volumn_audio', volume); + for (var i = 0; i < 8; i++) { + if (i < lib.config.volumn_audio) { + this.parentNode.childNodes[i].innerHTML = '●'; + } + else { + this.parentNode.childNodes[i].innerHTML = '○'; + } + } + e.stopPropagation(); + } + static hoverpopped() { + if (this._uiintro) { + return; + } + if (!this._poppedfunc) { + return; + } + ui.click.touchpop(this.forceclick); + var uiintro = this._poppedfunc(); + if (!uiintro) return; + if (ui.currentpopped && ui.currentpopped._uiintro) { + ui.currentpopped._uiintro.delete(); + delete ui.currentpopped._uiintro; + } + ui.currentpopped = this; + uiintro.classList.add('popped'); + uiintro.classList.add('hoverdialog'); + uiintro.classList.add('static'); + this._uiintro = uiintro; + + ui.window.appendChild(uiintro); + var width = this._poppedwidth || 330; + uiintro.style.width = width + 'px'; + if (get.is.phoneLayout()) { + width *= 1.3; + } + + if (uiintro._heightfixed) { + uiintro.style.height = uiintro.content.scrollHeight + 'px'; + } + else { + var height = this._poppedheight || uiintro.content.scrollHeight; + var height2 = ui.window.offsetHeight - 260; + if (get.is.phoneLayout()) { + height2 = (ui.window.offsetHeight - 80) / 1.3; + } + uiintro.style.height = Math.min(height2, height) + 'px'; + } + if (get.is.phoneLayout()) { + uiintro.style.top = '70px'; + } + else { + uiintro.style.top = '50px'; + } + var left = this.parentNode.offsetLeft + this.offsetLeft + this.offsetWidth / 2 - width / 2; + if (left < 10) { + left = 10; + } + else if (left + width > ui.window.offsetWidth - 10) { + left = ui.window.offsetWidth - width - 10; + } + uiintro.style.left = left + 'px'; + uiintro._poppedorigin = this; + if (!lib.config.touchscreen) { + uiintro.addEventListener('mouseleave', ui.click.leavehoverpopped); + } + ui.click.shortcut(false); + if (uiintro._onopen) { + uiintro._onopen(); + } + if (this._paused2 && !lib.config.touchscreen) { + game.pause2(); + uiintro.classList.add('static'); + var layer = ui.create.div('.poplayer', ui.window); + var clicklayer = function (e) { + uiintro.delete(); + layer.remove(); + game.resume2(); + e.stopPropagation(); + return false; + }; + uiintro.style.zIndex = 21; + layer.onclick = clicklayer; + layer.oncontextmenu = clicklayer; + uiintro.addEventListener('mouseleave', clicklayer); + uiintro.addEventListener('click', clicklayer); + } + } + static hoverpopped_leave() { + this._poppedalready = false; + } + static leavehoverpopped() { + if (_status.dragged) return; + if (this.classList.contains('noleave')) return; + this.delete(); + var button = this._poppedorigin; + + var uiintro = this; + setTimeout(function () { + if (button._uiintro == uiintro) { + delete button._uiintro; + } + }, 500); + + } + static dierevive() { + if (game.me.isDead()) { + game.me.revive(Math.max(1, game.me.maxHp)); + game.me.draw(2); + } + else { + if (ui.revive) { + ui.revive.close(); + delete ui.revive; + } + } + } + static dieswap() { + if (game.me.isDead()) { + _status.clicked = true; + var i, translation, intro, str; + if (ui.intro) { + ui.intro.close(); + if (ui.intro.source == 'dieswap') { + delete ui.intro; + ui.control.show(); + game.resume2(); + return; + } + } + game.pause2(); + ui.control.hide(); + ui.intro = ui.create.dialog(); + ui.intro.source = 'dieswap'; + + var players = []; + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isAlive()) { + players.push(game.players[i]); + } + } + ui.intro.add(players, true); + var buttons = ui.intro.querySelectorAll('.button'); + for (var i = 0; i < buttons.length; i++) { + buttons[i].addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.dieswap2); + } + } + else { + if (ui.swap) { + ui.swap.close(); + delete ui.swap; + } + } + } + static dieswap2() { + if (_status.dragged) return; + game.swapPlayer(this.link); + } + static touchconfirm() { + _status.touchconfirmed = true; + document.removeEventListener('touchstart', ui.click.touchconfirm); + } + static windowtouchstart(e) { + if (window.inSplash) return; + if (e.touches[0] && lib.config.swipe && e.touches.length < 2) { + _status._swipeorigin = { + clientX: e.touches[0].clientX, + clientY: e.touches[0].clientY, + time: get.utc() + }; + } + // if(window.ForceTouch&&!_status.paused2&&!_status.forcetouchinterval&&lib.config.enable_pressure){ + // _status.forcetouchinterval=setInterval(ui.click.forcetouch,30); + // } + } + static windowtouchmove(e) { + e.preventDefault(); + if (window.inSplash) return; + if (_status.draggingroundmenu) { + delete _status._swipeorigin; + if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform && e.touches.length) { + var translate = ui.roundmenu._dragtransform.slice(0); + var dx = e.touches[0].clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; + var dy = e.touches[0].clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; + translate[0] += dx; + translate[1] += dy; + if (dx * dx + dy * dy > 100) { + if (ui.roundmenu._resetTimeout) { + clearTimeout(ui.roundmenu._resetTimeout); + delete ui.roundmenu._resetTimeout; + } + } + ui.roundmenu._dragtouches = e.touches[0]; + ui.click.checkroundtranslate(translate); + } + _status.clicked = true; + } + else if (_status.draggingtouchdialog) { + delete _status._swipeorigin; + if (_status.draggingtouchdialog._dragorigin && _status.draggingtouchdialog._dragtransform && e.touches.length) { + var translate = _status.draggingtouchdialog._dragtransform.slice(0); + var dx = e.touches[0].clientX / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientX / game.documentZoom; + var dy = e.touches[0].clientY / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientY / game.documentZoom; + translate[0] += dx; + translate[1] += dy; + _status.draggingtouchdialog._dragtouches = e.touches[0]; + ui.click.checkdialogtranslate(translate, _status.draggingtouchdialog); + } + _status.clicked = true; + } + else if (_status._swipeorigin && e.touches[0]) { + _status._swipeorigin.touches = e.touches[0]; + } + + if (_status.mousedragging && e.touches.length) { + e.preventDefault(); + var item = document.elementFromPoint(e.touches[0].clientX, e.touches[0].clientY); + if (game.chess && ui.selected.cards.length) { + var itemtype = get.itemtype(item); + if (itemtype != 'card' && itemtype != 'button') { + var ex = e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft; + var ey = e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop; + for (var i = 0; i < game.players.length; i++) { + var left = -ui.chessContainer.chessLeft + ui.chess.offsetLeft + game.players[i].getLeft(); + var top = -ui.chessContainer.chessTop + ui.chess.offsetTop + game.players[i].getTop(); + var width = game.players[i].offsetWidth; + var height = game.players[i].offsetHeight; + if (ex > left && ex < left + width && ey > top && ey < top + height) { + item = game.players[i]; + break; + } + } + } + } + while (item) { + if (lib.config.enable_touchdragline && _status.mouseleft && !game.chess) { + ui.canvas.width = ui.arena.offsetWidth; + ui.canvas.height = ui.arena.offsetHeight; + var ctx = ui.ctx; + ctx.shadowBlur = 5; + ctx.shadowColor = 'rgba(0,0,0,0.3)'; + ctx.strokeStyle = 'white'; + ctx.lineWidth = 3; + ctx.setLineDash([8, 2]); + + ctx.beginPath(); + + ctx.moveTo(_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop); + + if (_status.multitarget) { + for (var i = 0; i < _status.lastdragchange.length; i++) { + var exy = _status.lastdragchange[i]._lastdragchange; + ctx.lineTo(exy[0], exy[1]); + } + } + if (!_status.selectionfull) { + ctx.lineTo(e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft, e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop); + } + ctx.stroke(); + if (!_status.multitarget) { + for (var i = 0; i < _status.lastdragchange.length; i++) { + ctx.moveTo(_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop); + var exy = _status.lastdragchange[i]._lastdragchange; + ctx.lineTo(exy[0], exy[1]); + ctx.stroke(); + } + } + } + + if (item == _status.mousedragorigin) { + if (_status.mouseleft) { + _status.mousedragging = null; + _status.mousedragorigin = null; + _status.clicked = false; + game.uncheck(); + game.check(); + _status.clicked = true; + } + return; + } + var itemtype = get.itemtype(item); + if (itemtype == 'card' || itemtype == 'button' || itemtype == 'player') { + _status.mouseleft = true; + if (ui.selected.cards.length) { + ui.selected.cards[0].updateTransform(true, 100); + } + var ex = e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft; + var ey = e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop; + var exx = ex, eyy = ey; + if (game.chess) { + ex -= -ui.chessContainer.chessLeft + ui.chess.offsetLeft; + ey -= -ui.chessContainer.chessTop + ui.chess.offsetTop; + } + if (itemtype != 'player' || game.chess || (ex > item.offsetLeft && ex < item.offsetLeft + item.offsetWidth && + ey > item.offsetTop && ey < item.offsetTop + item.offsetHeight)) { + var targetfixed = false; + if (itemtype == 'player') { + if (get.select(_status.event.selectTarget)[1] <= -1) { + targetfixed = true; + } + } + if (!targetfixed && item.classList.contains('selectable') && _status.dragstatuschanged != item) { + _status.mouseleft = true; + _status.dragstatuschanged = item; + _status.clicked = false; + _status.dragged = false; + var notbefore = itemtype == 'player' && !item.classList.contains('selected'); + ui.click[itemtype].call(item); + if (item.classList.contains('selected')) { + if (notbefore) { + _status.lastdragchange.push(item); + item._lastdragchange = [exx, eyy]; + if (lib.falseitem) { + var from = [_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop]; + var to = [exx, eyy]; + var node = ui.create.div('.linexy.hidden'); + node.style.left = from[0] + 'px'; + node.style.top = from[1] + 'px'; + node.style.transitionDuration = '0.3s'; + node.style.backgroundColor = 'white'; + var dy = to[1] - from[1]; + var dx = to[0] - from[0]; + var deg = Math.atan(Math.abs(dy) / Math.abs(dx)) / Math.PI * 180; + if (dx >= 0) { + if (dy <= 0) { + deg += 90; + } + else { + deg = 90 - deg; + } + } + else { + if (dy <= 0) { + deg = 270 - deg; + } + else { + deg += 270; + } + } + node.style.transform = 'rotate(' + (-deg) + 'deg) scaleY(0)'; + node.style.height = get.xyDistance(from, to) + 'px'; + if (game.chess) { + ui.chess.appendChild(node); + } + else { + ui.arena.appendChild(node); + } + ui.refresh(node); + node.show(); + node.style.transform = 'rotate(' + (-deg) + 'deg) scaleY(1)'; + ui.touchlines.push(node); + node._origin = item; + } + } + } + else { + _status.lastdragchange.remove(item); + for (var i = 0; i < ui.touchlines.length; i++) { + if (ui.touchlines[i]._origin == item) { + ui.touchlines[i].delete(); + ui.touchlines.splice(i--, 1); + } + } + } + _status.selectionfull = true; + if (_status.event.filterButton && ui.selected.buttons.length < get.select(_status.event.selectButton)[1]) { + _status.selectionfull = false; + } + else if (_status.event.filterCard && ui.selected.cards.length < get.select(_status.event.selectCard)[1]) { + _status.selectionfull = false; + } + else if (_status.event.filterTarget && ui.selected.targets.length < get.select(_status.event.selectTarget)[1]) { + _status.selectionfull = false; + } + } + } + return; + } + item = item.parentNode; + } + _status.mouseleft = true; + _status.dragstatuschanged = null; + } + } + static windowtouchend(e) { + delete _status.force; + // if(_status.forcetouchinterval){ + // clearInterval(_status.forcetouchinterval); + // delete _status.forcetouchinterval; + // } + if (window.inSplash) return; + if (e.touches.length == 1 && !_status.dragged && !_status.draggingtouchdialog) { + ui.click.pause(); + } + if (_status.draggingroundmenu) { + delete _status._swipeorigin; + if (ui.roundmenu._resetTimeout) { + clearTimeout(ui.roundmenu._resetTimeout); + delete ui.roundmenu._resetTimeout; + } + var translate; + if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform && ui.roundmenu._dragtouches) { + var dx = ui.roundmenu._dragtouches.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; + var dy = ui.roundmenu._dragtouches.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; + if (dx * dx + dy * dy < 1000) { + ui.click.roundmenu(); + ui.roundmenu._dragtransform = ui.roundmenu._dragorigintransform; + translate = ui.roundmenu._dragtransform; + ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; + } + else { + translate = ui.roundmenu._dragtransform; + translate[0] += dx; + translate[1] += dy; + ui.click.checkroundtranslate(); + } + delete ui.roundmenu._dragorigin; + } + else { + ui.click.roundmenu(); + } + _status.clicked = false; + game.saveConfig('roundmenu_transform', translate); + delete _status.draggingroundmenu; + } + else if (_status.draggingtouchdialog) { + delete _status._swipeorigin; + var translate; + if (_status.draggingtouchdialog._dragorigin && _status.draggingtouchdialog._dragtransform && _status.draggingtouchdialog._dragtouches) { + var dx = _status.draggingtouchdialog._dragtouches.clientX / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientX / game.documentZoom; + var dy = _status.draggingtouchdialog._dragtouches.clientY / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientY / game.documentZoom; + translate = _status.draggingtouchdialog._dragtransform; + translate[0] += dx; + translate[1] += dy; + ui.click.checkdialogtranslate(null, _status.draggingtouchdialog); + + delete _status.draggingtouchdialog._dragorigin; + } + _status.clicked = false; + game.saveConfig('dialog_transform', translate); + delete _status.draggingtouchdialog; + _status.justdragged = true; + setTimeout(function () { + _status.justdragged = false; + }, 500); + } + else if (_status._swipeorigin && !_status.paused2 && !_status.mousedragging && _status._swipeorigin.touches && !_status.filterCharacter) { + if (get.utc() - _status._swipeorigin.time < 500) { + var dx = _status._swipeorigin.touches.clientX / game.documentZoom - _status._swipeorigin.clientX / game.documentZoom; + var dy = _status._swipeorigin.touches.clientY / game.documentZoom - _status._swipeorigin.clientY / game.documentZoom; + var goswipe = function (action) { + game.closeConnectMenu(); + switch (action) { + case 'system': + game.closePopped(); + ui.system1.classList.add('shown'); + ui.system2.classList.add('shown'); + game.closeMenu(); + ui.click.shortcut(); + break; + case 'menu': + if (ui.click.configMenu) { + game.closePopped(); + game.pause2(); + ui.click.configMenu(); + ui.system1.classList.remove('shown'); + ui.system2.classList.remove('shown'); + } + break; + case 'pause': + ui.click.pause(); + break; + case 'auto': + ui.click.auto(); + break; + case 'chat': + game.closeMenu(); + if (ui.chatButton) { + ui.click.hoverpopped.call(ui.chatButton); + } + break; + } + }; + if (Math.abs(dx) < 100) { + if (dy < -200) { + goswipe(lib.config.swipe_up); + } + else if (dy > 200) { + goswipe(lib.config.swipe_down); + } + } + else if (Math.abs(dy) < 100) { + if (dx < -200) { + goswipe(lib.config.swipe_left); + } + else if (dx > 200) { + goswipe(lib.config.swipe_right); + } + } + } + } + var tmpflag = false; + _status.mousedown = false; + _status.clicked = false; + if (_status.mousedragging && _status.mouseleft) { + if (game.check()) { + if (ui.confirm) { + ui.confirm.close(); + } + var event = _status.event; + if (!event.filterOk || event.filterOk()) ui.click.ok(); + ui.canvas.width = ui.arena.offsetWidth; + ui.canvas.height = ui.arena.offsetHeight; + } + else { + game.uncheck(); + game.check(); + } + } + else if (_status.mousedragging && _status.mousedragorigin) { + tmpflag = _status.mousedragorigin; + } + _status.lastdragchange.length = 0; + _status.mousedragging = null; + _status.mouseleft = false; + _status.mousedragorigin = null; + _status.dragstatuschanged = false; + while (ui.touchlines.length) { + ui.touchlines.shift().delete(); + } + if (tmpflag) { + game.check(); + } + _status.dragged = false; + _status.clicked = false; + } + static checkroundtranslate(translate) { + var translate = translate || ui.roundmenu._dragtransform; + if (translate[1] + ui.roundmenu._position[1] + 50 + ui.arena.offsetTop > ui.window.offsetHeight) { + translate[1] = ui.window.offsetHeight - (ui.roundmenu._position[1] + 50) - ui.arena.offsetTop; + } + else if (translate[1] + ui.roundmenu._position[1] + ui.arena.offsetTop < 0) { + translate[1] = -ui.roundmenu._position[1] - ui.arena.offsetTop; + } + if (translate[0] + ui.roundmenu._position[0] + 50 + ui.arena.offsetLeft > ui.window.offsetWidth) { + translate[0] = ui.window.offsetWidth - (ui.roundmenu._position[0] + 50) - ui.arena.offsetLeft; + } + else if (translate[0] + ui.roundmenu._position[0] + ui.arena.offsetLeft < 0) { + translate[0] = -ui.roundmenu._position[0] - ui.arena.offsetLeft; + } + ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; + } + static checkdialogtranslate(translate, dialog) { + var translate = translate || dialog._dragtransform; + if (Math.sqrt(translate[0] * translate[0] + translate[1] * translate[1]) < 10) { + translate[0] = 0; + translate[1] = 0; + } + dialog.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; + } + static windowmousewheel(e) { + _status.tempunpopup = e; + } + static windowmousemove(e) { + if (window.inSplash) return; + if (_status.tempunpopup) { + if (get.evtDistance(_status.tempunpopup, e) > 5) { + delete _status.tempunpopup; + } + } + if (e.button == 2) return; + var dialogs = document.querySelectorAll('#window>.dialog.popped:not(.static)'); + for (var i = 0; i < dialogs.length; i++) { + dialogs[i].delete(); + } + var node = _status.currentmouseenter; + var sourceitem = document.elementFromPoint(e.clientX, e.clientY); + if (game.chess && ui.selected.cards.length) { + var itemtype = get.itemtype(sourceitem); + if (itemtype != 'card' && itemtype != 'button') { + for (var i = 0; i < game.players.length; i++) { + var ex = e.clientX / game.documentZoom - ui.arena.offsetLeft; + var ey = e.clientY / game.documentZoom - ui.arena.offsetTop; + var left = -ui.chessContainer.chessLeft + ui.chess.offsetLeft + game.players[i].getLeft(); + var top = -ui.chessContainer.chessTop + ui.chess.offsetTop + game.players[i].getTop(); + var width = game.players[i].offsetWidth; + var height = game.players[i].offsetHeight; + if (ex > left && ex < left + width && ey > top && ey < top + height) { + sourceitem = game.players[i]; + break; + } + } + } + } + var item = sourceitem; + if (_status.mousedragging) { + e.preventDefault(); + if (lib.config.enable_dragline) { + // var i=0; + // var startPoint0=[_status.mousedragging.clientX/game.documentZoom-ui.arena.offsetLeft,_status.mousedragging.clientY/game.documentZoom-ui.arena.offsetTop]; + // var startPoint=startPoint0; + // var endPoint; + // if(_status.multitarget){ + // for(;i<_status.lastdragchange.length;i++){ + // var exy=_status.lastdragchange[i]._lastdragchange; + // endPoint=[exy[0],exy[1]]; + // _status.dragline[i]=game.linexy(startPoint.concat(endPoint),'drag',_status.dragline[i]); + // startPoint=endPoint; + // } + // } + // if(!_status.selectionfull){ + // endPoint=[e.clientX/game.documentZoom-ui.arena.offsetLeft,e.clientY/game.documentZoom-ui.arena.offsetTop]; + // _status.dragline[i]=game.linexy(startPoint.concat(endPoint),'drag',_status.dragline[i]); + // startPoint=endPoint; + // i++; + // } + // if(!_status.multitarget){ + // for(var j=0;j<_status.lastdragchange.length;j++){ + // i+=j; + // var exy=_status.lastdragchange[j]._lastdragchange; + // _status.dragline[i]=game.linexy(startPoint0.concat([exy[0],exy[1]]),'drag',_status.dragline[i]); + // } + // } + // var remained=_status.dragline.splice(i+1); + // for(var j=0;j item.offsetLeft && ex < item.offsetLeft + item.offsetWidth && + ey > item.offsetTop && ey < item.offsetTop + item.offsetHeight)) { + var targetfixed = false; + if (itemtype == 'player') { + if (get.select(_status.event.selectTarget)[1] <= -1) { + targetfixed = true; + } + } + if (!targetfixed && item.classList.contains('selectable') && _status.dragstatuschanged != item) { + _status.mouseleft = true; + _status.dragstatuschanged = item; + _status.clicked = false; + var notbefore = itemtype == 'player' && !item.classList.contains('selected'); + ui.click[itemtype].call(item); + if (item.classList.contains('selected')) { + if (notbefore) { + _status.lastdragchange.push(item); + item._lastdragchange = [exx, eyy]; + } + } + else { + _status.lastdragchange.remove(item); + } + _status.selectionfull = true; + if (_status.event.filterButton && ui.selected.buttons.length < get.select(_status.event.selectButton)[1]) { + _status.selectionfull = false; + } + else if (_status.event.filterCard && ui.selected.cards.length < get.select(_status.event.selectCard)[1]) { + _status.selectionfull = false; + } + else if (_status.event.filterTarget && ui.selected.targets.length < get.select(_status.event.selectTarget)[1]) { + _status.selectionfull = false; + } + } + } + return; + } + item = item.parentNode; + } + if (!_status.mouseleft) { + _status.mouseleft = true; + game.check(); + for (var i = 0; i < ui.selected.cards.length; i++) { + ui.selected.cards[i].updateTransform(true); + } + } + _status.dragstatuschanged = null; + } + else { + while (item) { + if (item == node && !node._mouseentercreated) { + ui.click.mouseentercancel(); + var hoveration; + if (typeof node._hoveration == 'number') { + hoveration = node._hoveration; + } + else { + hoveration = parseInt(lib.config.hoveration); + if (node.classList.contains('button') || + (node.parentNode && node.parentNode.parentNode) == ui.me) { + hoveration += 500; + } + } + _status._mouseentertimeout = setTimeout(function () { + if (_status.currentmouseenter != node || node._mouseentercreated || _status.tempunpopup || + _status.mousedragging || _status.mousedown || !node.offsetWidth || !node.offsetHeight) { + return; + } + if (node._hoverfunc && !node._nopup) { + var dialog = node._hoverfunc.call(node, e); + if (dialog) { + dialog.classList.add('popped'); + ui.window.appendChild(dialog); + lib.placePoppedDialog(dialog, e); + if (node._hoverwidth) { + dialog.style.width = node._hoverwidth + 'px'; + dialog._hovercustomed = true; + } + node._mouseenterdialog = dialog; + node._mouseentercreated = true; + } + } + }, hoveration); + break; + } + item = item.parentNode; + } + if (_status.draggingdialog) { + var ddialog = _status.draggingdialog; + if (ddialog._dragorigin && ddialog._dragtransform) { + var translate = ddialog._dragtransform.slice(0); + translate[0] += e.clientX / game.documentZoom - ddialog._dragorigin.clientX / game.documentZoom; + translate[1] += e.clientY / game.documentZoom - ddialog._dragorigin.clientY / game.documentZoom; + ui.click.checkdialogtranslate(translate, ddialog); + } + _status.clicked = true; + } + if (_status.draggingroundmenu) { + if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform) { + var translate = ui.roundmenu._dragtransform.slice(0); + translate[0] += e.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; + translate[1] += e.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; + ui.click.checkroundtranslate(translate); + } + _status.clicked = true; + } + } + } + static windowmousedown(e) { + if (window.inSplash) return; + if (!ui.window) return; + if (e.button == 2) return; + _status.mousedown = true; + var dialogs = ui.window.querySelectorAll('#window>.dialog.popped:not(.static)'); + for (var i = 0; i < dialogs.length; i++) { + dialogs[i].delete(); + } + var sourceitem = document.elementFromPoint(e.clientX, e.clientY); + var item = sourceitem; + while (item) { + var itemtype = get.itemtype(item); + if (itemtype == 'button') break; + if (itemtype == 'dialog' && + !item.classList.contains('popped') && + !item.classList.contains('fixed')) { + var ddialog = item; + _status.draggingdialog = ddialog; + ddialog._dragorigin = e; + if (!ddialog._dragtransform) { + ddialog._dragtransform = [0, 0]; + } + return; + } + if (item == ui.roundmenu) { + _status.draggingroundmenu = true; + ui.roundmenu._dragorigin = e; + if (!ui.roundmenu._dragtransform) { + ui.roundmenu._dragtransform = [0, 0]; + } + return; + } + item = item.parentNode; + } + + var evt = _status.event; + if (!lib.config.enable_drag) return; + if (!ui.arena.classList.contains('selecting')) return; + if (!evt.isMine()) return; + + item = sourceitem; + while (item) { + var itemtype = get.itemtype(item); + if (itemtype == 'card' || itemtype == 'button' || itemtype == 'player') { + if (item.classList.contains('selectable') && + !item.classList.contains('selected') && + !item.classList.contains('noclick')) { + _status.clicked = false; + ui.click[itemtype].call(item); + if (item.classList.contains('selected')) { + _status.mousedragging = e; + _status.mousedragorigin = item; + _status.mouseleft = false; + _status.selectionfull = false; + _status.multitarget = false; + _status.lastmouseutc = get.utc(); + ui.arena.classList.add('dragging'); + } + } + return; + } + item = item.parentNode; + } + } + static cardtouchstart(e) { + if (e.touches.length != 1) return; + if (!lib.config.enable_drag) return; + if (!this.parentNode) return; + if (!this.parentNode.parentNode) return; + if (this.parentNode.parentNode.parentNode != ui.me) return; + if (this.parentNode.parentNode.classList.contains('scrollh')) return; + if (this.classList.contains('selectable') && + !this.classList.contains('selected') && + !this.classList.contains('noclick')) { + this._waitingfordrag = { + clientX: e.touches[0].clientX, + clientY: e.touches[0].clientY + }; + } + } + static cardtouchmove(e) { + ui.click.longpresscancel.call(this); + if (this._waitingfordrag) { + var drag = this._waitingfordrag; + _status.clicked = false; + _status.touchnocheck = true; + ui.click.card.call(this); + _status.touchnocheck = false; + if (this.classList.contains('selected')) { + _status.mousedragging = drag; + _status.mousedragorigin = this; + _status.mouseleft = false; + _status.selectionfull = false; + _status.multitarget = false; + } + delete this._waitingfordrag; + } + } + static windowmouseup(e) { + delete _status.force; + // if(_status.forcetouchinterval){ + // clearInterval(_status.forcetouchinterval); + // delete _status.forcetouchinterval; + // } + if (window.inSplash) return; + if (_status.draggingdialog) { + var ddialog = _status.draggingdialog; + var translate; + if (ddialog._dragorigin && ddialog._dragtransform) { + translate = ddialog._dragtransform; + translate[0] += e.clientX / game.documentZoom - ddialog._dragorigin.clientX / game.documentZoom; + translate[1] += e.clientY / game.documentZoom - ddialog._dragorigin.clientY / game.documentZoom; + ui.click.checkdialogtranslate(null, ddialog); + delete ddialog._dragorigin; + } + game.saveConfig('dialog_transform', translate); + delete _status.draggingdialog; + } + if (_status.draggingroundmenu) { + var translate; + if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform) { + var dx = e.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; + var dy = e.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; + if (dx * dx + dy * dy < 25) { + ui.click.roundmenu(); + } + translate = ui.roundmenu._dragtransform; + translate[0] += dx; + translate[1] += dy; + ui.click.checkroundtranslate(); + delete ui.roundmenu._dragorigin; + } + game.saveConfig('roundmenu_transform', translate); + delete _status.draggingroundmenu; + } + if (e.button == 2) { + if (_status.mousedragging) { + _status.mousedragging = null; + _status.mouseleft = false; + _status.mousedragorigin = null; + _status.dragstatuschanged = false; + game.uncheck(); + game.check(); + _status.noright = true; + } + } + else { + var tmpflag = false; + _status.mousedown = false; + for (var i = 0; i < ui.selected.cards.length; i++) { + ui.selected.cards[i].updateTransform(true); + } + if (_status.mousedragging && _status.mouseleft) { + if (game.check()) { + if (ui.confirm) { + ui.confirm.close(); + } + var event = _status.event; + if (!event.filterOk || event.filterOk()) ui.click.ok(); + } + else { + game.uncheck(); + game.check(); + } + } + else if (_status.mousedragging && _status.mousedragorigin) { + tmpflag = _status.mousedragorigin; + } + _status.lastdragchange.length = 0; + _status.mousedragging = null; + _status.mouseleft = false; + _status.mousedragorigin = null; + _status.dragstatuschanged = false; + if (ui.arena) { + ui.canvas.width = ui.arena.offsetWidth; + ui.canvas.height = ui.arena.offsetHeight; + } + if (tmpflag) { + ui.click[get.itemtype(tmpflag)].call(tmpflag); + game.check(); + } + // ui.updatehl(); + } + if (ui.arena) { + ui.arena.classList.remove('dragging'); + } + } + static mousemove() { + if (!lib.config.hover_handcard && this.parentNode && this.parentNode.parentNode == ui.me) { + return; + } + if (!_status.currentmouseenter) { + _status.currentmouseenter = this; + } + } + static mouseenter() { + if (!lib.config.hover_handcard && this.parentNode && this.parentNode.parentNode == ui.me) { + return; + } + _status.currentmouseenter = this; + } + static mouseleave() { + ui.click.mouseentercancel(); + if (_status.currentmouseenter == this) { + _status.currentmouseenter = null; + } + this._mouseentercreated = false; + } + static mousedown() { + ui.click.mouseentercancel(); + if (_status.currentmouseenter == this) { + _status.currentmouseenter = null; + } + this._mouseentercreated = true; + } + static mouseentercancel() { + if (_status._mouseentertimeout) { + clearTimeout(_status._mouseentertimeout); + delete _status._mouseentertimeout; + } + } + static hoverplayer(e) { + var node = get.nodeintro(this, true); + if (node) node.style.zIndex = 21; + return node; + } + static longpressdown(e) { + if (_status.longpressed) return; + if (this._longpresstimeout) { + clearTimeout(this._longpresstimeout); + } + if (lib.config.longpress_info) { + this._longpresstimeout = setTimeout(ui.click.longpresscallback, 500); + } + this._longpressevent = e; + if (_status.longpressing && _status.longpressing != this) { + ui.click.longpresscancel.call(_status.longpressing); + } + // if(window.ForceTouch&&!_status.forcetouchinterval&&lib.config.enable_pressure){ + // _status.forcetouchinterval=setInterval(ui.click.forcetouch,30); + // } + _status.longpressing = this; + } + static longpresscallback() { + if (!_status.longpressing) return; + var node = _status.longpressing; + var func = node._longpresscallback; + var e = node._longpressevent; + if (!func || !e) return; + clearTimeout(node._longpresstimeout); + _status.force = true; + delete _status.longpressing; + delete node._longpresstimeout; + delete node._longpressevent; + if (_status.mousedragging && _status.mouseleft) return; + if (!_status.longpressed) { + _status.longpressed = true; + setTimeout(function () { + _status.longpressed = false; + }, 500); + func.call(node, e); + if (lib.config.touchscreen && lib.config.enable_drag && !node._waitingfordrag) { + _status.mousedragging = null; + _status.mousedragorigin = null; + _status.clicked = false; + game.uncheck(); + game.check(); + _status.clicked = true; + } + delete node._waitingfordrag; + ui.click.touchpop(); + } + } + static longpresscancel() { + if (this._longpresstimeout) { + clearTimeout(this._longpresstimeout); + delete this._longpresstimeout; + } + delete this._longpressevent; + if (_status.longpressing == this) { + delete _status.longpressing; + } + } + static window() { + var clicked = _status.clicked; + var dialogtouched = false; + if (_status.dialogtouched) { + _status.dialogtouched = false; + dialogtouched = true; + } + if (_status.dragged) return; + if (_status.touchpopping) return; + if (_status.reloading) return; + if (_status.clicked || _status.clicked2) { + _status.clicked = false; + _status.clicked2 = false; + } + else { + if (_status.clickingidentity) { + for (var i = 0; i < _status.clickingidentity[1].length; i++) { + _status.clickingidentity[1][i].delete(); + _status.clickingidentity[1][i].style.transform = ''; + } + delete _status.clickingidentity; + } + if (!_status.event.isMine) return; + if (ui.controls.length) { + ui.updatec(); + } + if (_status.editing) { + if (_status.editing.innerHTML.length) { + _status.editing.link = _status.editing.innerHTML; + } + _status.editing.innerHTML = get.translation(_status.editing.link); + delete _status.editing; + } + else if (_status.choosing) { + if (!_status.choosing.expand) { + _status.choosing.parentNode.style.height = ''; + _status.choosing.nextSibling.delete(); + _status.choosing.previousSibling.show(); + delete _status.choosing; + } + } + else if (ui.intro) { + ui.intro.close(); + delete ui.intro; + ui.control.show(); + game.resume2(); + } + else if ((_status.event.isMine() || _status.event.forceMine) && !dialogtouched) { + if (_status.event.custom && _status.event.custom.replace.window) { + _status.event.custom.replace.window(); + } + else { + if (_status.event.skill && _status.event.name == 'chooseToUse') { + ui.click.cancel(); + } + else if (_status.event._checked) { + game.uncheck(); + game.check(); + } + } + } + if (!ui.shortcut.classList.contains('hidden')) { + ui.click.shortcut(false); + } + if (get.is.phoneLayout() && ui.menuContainer && ui.menuContainer.classList.contains('hidden')) { + if (ui.system2.classList.contains('shown')) { + _status.removinground = true; + setTimeout(function () { + _status.removinground = false; + }, 200); + } + ui.arena.classList.remove('phonetop'); + ui.system1.classList.remove('shown'); + ui.system2.classList.remove('shown'); + // if(ui.chessinfo){ + // ui.chessinfo.classList.remove('zoomed'); + // } + } + } + if (_status.tempunpop) { + _status.tempunpop = false; + } + else { + game.closePopped(); + } + if (_status.event.custom && _status.event.custom.add.window) { + _status.event.custom.add.window(clicked); + } + } + static toggle() { + if (_status.dragged) return; + if (this.parentNode.classList.contains('disabled')) return; + _status.tempunpop = true; + if (this.link) { + this.link = false; + this.classList.remove('on'); + if (this.additionalCommand) this.additionalCommand(false, this.parentNode); + } + else { + this.link = true; + this.classList.add('on'); + if (this.additionalCommand) this.additionalCommand(true, this.parentNode); + } + } + static editor() { + if (_status.dragged) return; + if (_status.editing) return; + _status.clicked = true; + this.innerHTML = ''; + _status.editing = this; + if (this.additionalCommand) this.additionalCommand(this); + } + static switcher() { + if (_status.dragged) return; + if (this.parentNode.classList.contains('disabled')) return; + if (_status.choosing) return; + _status.clicked = true; + _status.tempunpop = true; + this.previousSibling.hide(); + var node = ui.create.div('.switcher', this.parentNode).addTempClass('start'); + for (var i = 0; i < this.choice.length; i++) { + var choice = ui.create.div('.pointerdiv', node); + choice.innerHTML = get.translation(this.choice[i]); + choice.link = this.choice[i]; + choice.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.choice); + } + // this.parentNode.style.height=(node.offsetHeight)+'px'; + _status.choosing = this; + if (!_status.choosing.expand) { + _status.choosing.expand = true; + setTimeout(function () { + _status.choosing.expand = false; + }, 500); + } + } + static choice() { + if (_status.dragged) return; + if (!_status.choosing) return; + _status.choosing.link = this.link; + _status.choosing.innerHTML = get.translation(this.link); + this.parentNode.parentNode.style.height = ''; + this.parentNode.delete(); + _status.choosing.previousSibling.show(); + delete _status.choosing; + if (this.parentNode.parentNode.querySelector('.toggle').additionalCommand) { + this.parentNode.parentNode.querySelector('.toggle').additionalCommand(this.link, this.parentNode.parentNode); + } + } + static button() { + if (_status.dragged) return; + if (_status.clicked) return; + if (_status.tempNoButton) return; + if (_status.draggingtouchdialog) return; + if (this.classList.contains('noclick')) return; + if (_status.justdragged) return; + _status.clicked = true; + var custom = _status.event.custom; + if (custom && custom.replace.button) { + custom.replace.button(this); + return; + } + if (!_status.event.isMine()) return; + if (this.classList.contains('selectable') == false) return; + if (this.classList.contains('selected')) { + ui.selected.buttons.remove(this); + this.classList.remove('selected'); + if (_status.multitarget || _status.event.complexSelect) { + game.uncheck(); + game.check(); + } + } + else { + this.classList.add('selected'); + ui.selected.buttons.add(this); + } + if (custom && custom.add && custom.add.button) { + custom.add.button(); + } + game.check(); + } + static touchintro() { + var rect = this.getBoundingClientRect(); + ui.click.touchpop(); + ui.click.intro.call(this, { + clientX: rect.left + 18, + clientY: rect.top + 12 + }); + _status.clicked = false; + } + static card() { + delete this._waitingfordrag; + if (_status.dragged) return; + if (_status.clicked) return; + if (ui.intro) return; + _status.clicked = true; + if (this.parentNode && (this.parentNode.classList.contains('judges') || this.parentNode.classList.contains('marks'))) { + var rect = this.getBoundingClientRect(); + ui.click.touchpop(); + ui.click.intro.call(this, { + clientX: rect.left + 18, + clientY: rect.top + 12 + }); + _status.clicked = false; + return; + } + var custom = _status.event.custom; + if (custom && custom.replace.card) { + custom.replace.card(this); + return; + } + if (this.classList.contains('selectable') == false) return; + if (this.classList.contains('selected')) { + ui.selected.cards.remove(this); + if (_status.multitarget || _status.event.complexSelect) { + game.uncheck(); + game.check(); + } + else { + this.classList.remove('selected'); + this.updateTransform(); + } + } + else { + ui.selected.cards.add(this); + this.classList.add('selected'); + this.updateTransform(true); + } + if (game.chess && get.config('show_range') && !_status.event.skill && this.classList.contains('selected') && + _status.event.isMine() && _status.event.name == 'chooseToUse') { + var player = _status.event.player; + var range = get.info(this).range; + if (range) { + if (typeof range.attack === 'number') { + player.createRangeShadow(Math.min(8, player.getAttackRange(true) + range.attack - 1)); + } + else if (typeof range.global === 'number') { + player.createRangeShadow(Math.min(8, player.getGlobalFrom() + range.global)); + } + } + } + if (custom.add.card) { + custom.add.card(); + } + game.check(); + + if (lib.config.popequip && get.is.phoneLayout() && + arguments[0] != 'popequip' && ui.arena && ui.arena.classList.contains('selecting') && + this.parentNode && this.parentNode.classList.contains('popequip')) { + var rect = this.getBoundingClientRect(); + ui.click.touchpop(); + ui.click.intro.call(this.parentNode, { + clientX: rect.left + 18, + clientY: rect.top + 12 + }); + } + } + static avatar() { + if (!lib.config.doubleclick_intro) return; + if (this.parentNode.isUnseen(0)) return; + if (!lib.character[this.parentNode.name]) return; + if (!ui.menuContainer) return; + var avatar = this; + var player = this.parentNode; + if (!game.players.includes(player) && !game.dead.includes(player)) return; + if (!this._doubleClicking) { + this._doubleClicking = true; + setTimeout(function () { + avatar._doubleClicking = false; + }, 500); + return; + } + // ui.click.skin(this,player.name); + game.pause2(); + ui.click.charactercard(player.name1 || player.name, null, null, true, this); + } + static avatar2() { + if (!lib.config.doubleclick_intro) return; + if (this.parentNode.classList.contains('unseen2')) return; + if (!lib.character[this.parentNode.name2]) return; + if (!ui.menuContainer) return; + var avatar = this; + var player = this.parentNode; + if (!game.players.includes(player) && !game.dead.includes(player)) return; + if (!this._doubleClicking) { + this._doubleClicking = true; + setTimeout(function () { + avatar._doubleClicking = false; + }, 500); + return; + } + // ui.click.skin(this,player.name2); + game.pause2(); + ui.click.charactercard(player.name2, null, null, true, this); + } + static connectroom(e) { + if (_status.dragged) return; + if (_status.clicked) return; + if (ui.intro) return; + if (this.roomfull) { + alert('房间已满'); + } + else if (this.roomgaming && !game.onlineID) { + if (this.config && this.config.observe) { + alert('房间暂时不可旁观'); + } + else { + alert('房间不允许旁观'); + } + } + else if (!this.roomempty && this.version != lib.versionOL) { + if (this.version > lib.versionOL) { + alert('加入失败:你的游戏版本过低'); + } + else { + alert('加入失败:房主的游戏版本过低'); + } + } + else { + if (!_status.enteringroom) { + _status.enteringroom = true; + _status.enteringroomserver = this.serving; + game.send('server', 'enter', this.key, get.connectNickname(), lib.config.connect_avatar); + } + } + } + static player() { + return ui.click.target.apply(this, arguments); + } + static target(e) { + if (_status.dragged) return; + if (_status.clicked) return; + if (ui.intro) return; + if (this.classList.contains('connect')) { + if (game.online) { + if (game.onlinezhu) { + if (!this.playerid && game.connectPlayers) { + if (lib.configOL.mode == 'versus' || lib.configOL.mode == 'doudizhu') return; + if (lib.configOL.mode == 'identity' && lib.configOL.identity_mode == 'zhong') return; + if (!this.classList.contains('unselectable2') && lib.configOL.number <= 2) return; + this.classList.toggle('unselectable2'); + if (this.classList.contains('unselectable2')) { + lib.configOL.number--; + } + else { + lib.configOL.number++; + } + game.send('changeNumConfig', lib.configOL.number, + game.connectPlayers.indexOf(this), this.classList.contains('unselectable2')); + } + } + return; + } + if (this.playerid) { + if (this.ws) { + if (confirm('是否踢出' + this.nickname + '?')) { + var id = get.id(); + this.ws.send(function (id) { + if (game.ws) { + game.ws.close(); + game.saveConfig('reconnect_info'); + game.saveConfig('banned_info', id); + } + }, id); + lib.node.banned.push(id); + } + } + } + else { + if (lib.configOL.mode == 'versus' || lib.configOL.mode == 'doudizhu' || lib.configOL.mode == 'single') return; + if (lib.configOL.mode == 'identity' && (lib.configOL.identity_mode == 'zhong' || lib.configOL.identity_mode == 'purple')) return; + if (!this.classList.contains('unselectable2') && lib.configOL.number <= 2) return; + this.classList.toggle('unselectable2'); + if (this.classList.contains('unselectable2')) { + lib.configOL.number--; + } + else { + lib.configOL.number++; + } + game.send('server', 'config', lib.configOL); + game.updateWaiting(); + } + return; + } + _status.clicked = true; + var custom = _status.event.custom; + if (custom && custom.replace.target) { + custom.replace.target(this, e); + return; + } + if (this.classList.contains('selectable') == false) return; + this.unprompt(); + if (this.classList.contains('selected')) { + ui.selected.targets.remove(this); + if (_status.multitarget || _status.event.complexSelect) { + game.uncheck(); + game.check(); + } + else { + this.classList.remove('selected'); + } + } + else { + ui.selected.targets.add(this); + if (_status.event.name == 'chooseTarget' || _status.event.name == 'chooseToUse' || _status.event.name == 'chooseCardTarget') { + var targetprompt = null; + if (_status.event.targetprompt) { + targetprompt = _status.event.targetprompt; + } + else if (_status.event.skill && !get.info(_status.event.skill).viewAs) { + targetprompt = get.info(_status.event.skill).targetprompt; + } + else if (_status.event.name == 'chooseToUse') { + var currentcard = get.card(); + if (currentcard) { + targetprompt = get.info(currentcard).targetprompt; + } + } + if (targetprompt) { + if (Array.isArray(targetprompt)) { + targetprompt = targetprompt[Math.min(targetprompt.length - 1, ui.selected.targets.indexOf(this))]; + } + else if (typeof targetprompt == 'function') { + targetprompt = targetprompt(this); + } + if (targetprompt && typeof targetprompt == 'string') { + this.prompt(targetprompt); + } + } + } + this.classList.add('selected'); + } + if (custom.add.target) { + custom.add.target(); + } + game.check(); + } + static control2() { + if (this.childNodes.length == 1 && !this._doubleclick) { + ui.click.control.call(this.firstChild); + } + } + static control() { + if (_status.dragged) return; + if (ui.control.classList.contains('hidden')) return; + var node = this.parentNode; + if (node) { + if (node._doubleclick) { + return; + } + else { + node._doubleclick = true; + setTimeout(function () { + node._doubleclick = false; + }, 500); + } + if (node.classList.contains('hidden')) return; + if (node.classList.contains('removing')) return; + if (node.classList.contains('disabled')) return; + } + if (ui.intro) { + ui.intro.close(); + delete ui.intro; + } + _status.clicked = true; + if (this.parentNode.custom) { + this.parentNode.custom(this.link, this); + return; + } + if (this.link == 'ok') { + ui.click.ok(this); + } + else if (this.link == 'cancel') { + ui.click.cancel(this); + } + else { + _status.event.result = { + buttons: ui.selected.buttons.slice(0), + cards: ui.selected.cards.slice(0), + targets: ui.selected.targets.slice(0), + control: this.link, + links: get.links(ui.selected.buttons) + }; + if (this.parentNode.close != false) { + game.uncheck(); + this.parentNode.close(); + } + game.resume(); + } + } + static dialogcontrol() { + _status.event.result = { + buttons: ui.selected.buttons.slice(0), + cards: ui.selected.cards.slice(0), + targets: ui.selected.targets.slice(0), + control: this.link, + links: get.links(ui.selected.buttons) + }; + game.resume(); + } + static skill(skill) { + var info = get.info(skill); + var event = _status.event; + event.backup(skill); + if (info.filterCard && info.discard != false && info.lose != false && !info.viewAs) { + var cards = event.player.getCards(event.position); + for (var i = 0; i < cards.length; i++) { + if (!lib.filter.cardDiscardable(cards[i], event.player)) { + cards[i].uncheck('useSkill'); + } + } + } + if (typeof event.skillDialog == 'object') { + event.skillDialog.close(); + } + if (event.isMine()) { + event.skillDialog = true; + } + game.uncheck(); + game.check(); + if (event.skillDialog === true) { + var str = get.translation(skill); + if (info.prompt) { + var str2; + if (typeof info.prompt == 'function') { + str2 = info.prompt(event); + } + else { + str2 = info.prompt; + } + event.skillDialog = ui.create.dialog(str, '
          ' + str2 + '
          '); + if (info.longprompt) { + event.skillDialog.forcebutton = true; + ui.update(); + } + } + else if (info.promptfunc) { + event.skillDialog = ui.create.dialog(str, '
          ' + info.promptfunc(event, event.player) + '
          '); + } + else if (lib.dynamicTranslate[skill]) { + event.skillDialog = ui.create.dialog(str, '
          ' + lib.dynamicTranslate[skill](event.player, skill) + '
          '); + } + else if (lib.translate[skill + '_info']) { + event.skillDialog = ui.create.dialog(str, '
          ' + lib.translate[skill + '_info'] + '
          '); + } + } + } + static ok(node) { + const gameEvent = get.event(), custom = gameEvent.custom, replaceConfirm = custom.replace.confirm; + if (replaceConfirm) { + replaceConfirm(true); + return; + } + const result = gameEvent.result = { + buttons: ui.selected.buttons.slice(), + cards: ui.selected.cards.slice(), + targets: ui.selected.targets.slice(), + confirm: 'ok', + bool: true, + links: get.links(ui.selected.buttons) + }; + if (node) node.parentNode.close(); + const skill = gameEvent.skill; + if (skill) { + result.skill = skill; + const info = get.info(skill); + if (info && info.direct && !info.clearTime) { + result._noHidingTimer = true; + } + const skillInformation = get.info(gameEvent.skill), viewAs = skillInformation.viewAs; + if (typeof viewAs == 'function') { + const viewedAs = viewAs(result.cards, gameEvent.player); + if (viewedAs) result.card = get.autoViewAs(viewedAs); + } + else if (viewAs) result.card = get.autoViewAs(viewAs); + const resultCard = result.card; + if (resultCard) { + const cards = result.cards; + if (cards.length == 1) { + const firstCard = cards[0]; + if (!resultCard.suit) resultCard.suit = get.suit(firstCard); + if (!resultCard.number) resultCard.number = get.number(firstCard); + } + } + const skillDialog = gameEvent.skillDialog; + if (skillDialog && get.objtype(skillDialog) == 'div') skillDialog.close(); + gameEvent.player.getCards('hej').forEach(card => card.recheck('useSkill')); + gameEvent.restore(); + } + else if (['chooseToUse', 'chooseToRespond'].includes(gameEvent.name)) result.card = get.autoViewAs(result.cards[0]); + if (ui.skills) ui.skills.close(); + if (ui.skills2) ui.skills2.close(); + if (ui.skills3) ui.skills3.close(); + game.uncheck(); + const addConfirm = custom.add.confirm; + if (addConfirm) addConfirm(true); + game.resume(); + } + static cancel(node) { + var event = _status.event; + if (event.custom.replace.confirm) { + event.custom.replace.confirm(false); return; + } + if (event.skill && !event.norestore) { + if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { + event.skillDialog.close(); + } + if (typeof event.dialog == 'string' && event.isMine()) { + event.dialog = ui.create.dialog(event.dialog); + } + if (_status.event.type == 'phase' && ui.confirm) { + ui.confirm.classList.add('removing'); + } + // ui.control.addTempClass('nozoom',100); + event.restore(); + var cards = event.player.getCards('hej'); + for (var i = 0; i < cards.length; i++) { + cards[i].recheck('useSkill'); + } + game.uncheck(); + game.check(); + return; + } + event.result = { + confirm: 'cancel', + bool: false + }; + if (node) { + node.parentNode.close(); + } + if (ui.skills) ui.skills.close(); + if (ui.skills2) ui.skills2.close(); + if (ui.skills3) ui.skills3.close(); + game.uncheck(); + if (event.custom.add.confirm) { + event.custom.add.confirm(true); + } + game.resume(); + } + static logv(e) { + if (_status.currentlogv) { + if (_status.currentlogv == this) return; + if (_status.logvtimeout) { + clearTimeout(_status.logvtimeout); + } + var that = this; + _status.logvtimeout = setTimeout(function () { + if (!_status.currentlogv) { + _status.currentlogv = that; + ui.click.intro.call(that, e); + } + }, 200); + this.logvtimeout = _status.logvtimeout; + } + else { + _status.currentlogv = this; + ui.click.intro.call(this, e); + } + } + static logvleave() { + if (_status.currentlogv == this) { + setTimeout(function () { + delete _status.currentlogv; + }, 150); + } + if (this.logvtimeout) { + clearTimeout(this.logvtimeout); + if (_status.logvtimeout == this.logvtimeout) { + delete _status.logvtimeout; + } + delete this.logvtimeout; + } + } + static charactercard(name, sourcenode, noedit, resume, avatar) { + if (_status.dragged) return; + if (lib.config.theme != 'simple') { + ui.window.classList.add('shortcutpaused'); + ui.menuContainer.classList.add('forceopaque'); + } + else { + ui.window.classList.add('systempaused'); + ui.menuContainer.classList.add('transparent2'); + } + if (lib.config.blur_ui) { + ui.arena.classList.add('blur'); + ui.system.classList.add('blur'); + ui.menuContainer.classList.add('blur'); + } + var layer = ui.create.div('.popup-container'); + var clicklayer = function (e) { + if (_status.touchpopping) return; + if (_status.dragged) return; + ui.window.classList.remove('shortcutpaused'); + ui.window.classList.remove('systempaused'); + ui.menuContainer.classList.remove('forceopaque'); + ui.menuContainer.classList.remove('transparent2'); + ui.arena.classList.remove('blur'); + ui.system.classList.remove('blur'); + ui.menuContainer.classList.remove('blur'); + this.delete(); + e.stopPropagation(); + if (resume) game.resume2(); + return false; + }; + var uiintro = ui.create.div('.menubg.charactercard', layer); + var playerbg = ui.create.div('.menubutton.large.ava', uiintro); + var bg = ui.create.div('.avatar', playerbg, function () { + if (changeskinfunc) { + changeskinfunc(); + } + }).setBackground(name, 'character'); + var changeskinfunc = null; + var nameskin = name; + var nameskin2 = name; + var gzbool = false; + if (nameskin.startsWith('gz_shibing')) { + nameskin = nameskin.slice(3, 11); + } + else if (nameskin.startsWith('gz_')) { + nameskin = nameskin.slice(3); + gzbool = true; + } + var changeskin = function () { + var node = ui.create.div('.changeskin', '可换肤', playerbg); + var avatars = ui.create.div('.avatars', playerbg); + changeskinfunc = function () { + playerbg.classList.add('scroll'); + if (node._created) { + return; + } + node._created = true; + var createButtons = function (num) { + if (!num) return; + if (num >= 4) { + avatars.classList.add('scroll'); + if (lib.config.touchscreen) { + lib.setScroll(avatars); + } + } + for (var i = 0; i <= num; i++) { + var button = ui.create.div(avatars, function () { + playerbg.classList.remove('scroll'); + if (this._link) { + lib.config.skin[nameskin] = this._link; + bg.style.backgroundImage = this.style.backgroundImage; + if (sourcenode) sourcenode.style.backgroundImage = this.style.backgroundImage; + if (avatar) avatar.style.backgroundImage = this.style.backgroundImage; + game.saveConfig('skin', lib.config.skin); + } + else { + delete lib.config.skin[nameskin]; + if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) { + bg.setBackground(nameskin2, 'character'); + if (sourcenode) sourcenode.setBackground(nameskin2, 'character'); + if (avatar) avatar.setBackground(nameskin2, 'character'); + } + else { + bg.setBackground(nameskin, 'character'); + if (sourcenode) sourcenode.setBackground(nameskin, 'character'); + if (avatar) avatar.setBackground(nameskin, 'character'); + } + game.saveConfig('skin', lib.config.skin); + } + }); + button._link = i; + if (i) { + button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); + } + else { + if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); + else button.setBackground(nameskin, 'character', 'noskin'); + } + } + }; + var num = 1; + var loadImage = function () { + var img = new Image(); + img.onload = function () { + num++; + loadImage(); + }; + img.onerror = function () { + num--; + createButtons(num); + }; + img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; + }; + if (lib.config.change_skin) { + loadImage(); + } + else { + createButtons(lib.skin[nameskin]); + } + }; + }; + if (lib.config.change_skin) { + var img = new Image(); + img.onload = changeskin; + img.src = lib.assetURL + 'image/skin/' + nameskin + '/1.jpg'; + } + else if (lib.config.debug && lib.skin[nameskin]) { + changeskin(); + } + var ban = ui.create.div('.menubutton.large.ban.character', uiintro, '禁用', function (e) { + if (this.classList.contains('unselectable')) return; + if (typeof noedit == 'string') { + this.classList.toggle('active'); + var bannedname = noedit + '_banned'; + if (!lib.config[bannedname]) { + lib.config[bannedname] = []; + } + if (this.classList.contains('active')) { + lib.config[bannedname].add(name); + } + else { + lib.config[bannedname].remove(name); + } + game.saveConfig(bannedname, lib.config[bannedname]); + ban.updateBanned(); + } + else { + ui.click.touchpop(); + ui.click.intro.call(this, e); + _status.clicked = true; + } + }); + ban.link = name; + ban._banning = 'offline'; + ban.updateBanned = function () { + if (noedit === true) return; + if (lib.config[get.mode() + '_banned'] && lib.config[get.mode() + '_banned'].includes(name)) { + ban.classList.add('active'); + } + else { + ban.classList.remove('active'); + } + if (sourcenode && sourcenode.updateBanned) { + sourcenode.updateBanned(); + } + }; + ban.updateBanned(); + var fav = ui.create.div('.menubutton.large.fav', uiintro, '收藏', function () { + if (this.classList.contains('unselectable')) return; + this.classList.toggle('active'); + if (this.classList.contains('active')) { + lib.config.favouriteCharacter.add(name); + } + else { + lib.config.favouriteCharacter.remove(name); + } + game.saveConfig('favouriteCharacter', lib.config.favouriteCharacter); + }); + if (noedit === true) { + fav.classList.add('unselectable'); + ban.classList.add('unselectable'); + } + else if (lib.config.favouriteCharacter.includes(name)) { + fav.classList.add('active'); + } + + // 样式二 + if (lib.config.show_characternamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_characternamepinyin == 'showCodeIdentifier2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') { + var intro = ui.create.div('.characterintro', get.characterIntro(name), uiintro); + if (lib.config.show_characternamepinyin == 'showPinyin2' || lib.config.show_characternamepinyin == 'showCodeIdentifier2') { + var charactername = get.rawName2(name); + var characterpinyin = lib.config.show_characternamepinyin == 'showCodeIdentifier2' ? name : get.pinyin(charactername); + var nameinfo = get.character(name); + var charactersex = get.translation(nameinfo[0]); + const charactergroups = get.is.double(name, true); + let charactergroup; + if (charactergroups) charactergroup = charactergroups.map(i => get.translation(i)).join('/'); + else charactergroup = get.translation(nameinfo[1]); + var characterhp = nameinfo[2]; + var characterintroinfo = get.characterIntro(name); + var spacemark = ' | '; + if (charactername.length > 3) spacemark = '' + ' ' + '' + '|' + '' + ' ' + ''; + intro.innerHTML = '' + charactername + '' + '' + '[' + characterpinyin + ']' + '' + spacemark + charactersex + spacemark + charactergroup + spacemark + characterhp + '' + '
          ' + characterintroinfo; + } + var intro2 = ui.create.div('.characterintro.intro2', uiintro); + var list = get.character(name, 3) || []; + var skills = ui.create.div('.characterskill', uiintro); + if (lib.config.touchscreen) { + lib.setScroll(intro); + lib.setScroll(intro2); + lib.setScroll(skills); + } + + if (lib.config.mousewheel) { + skills.onmousewheel = ui.click.mousewheel; + } + var clickSkill = function (e) { + while (intro2.firstChild) { + intro2.removeChild(intro2.lastChild); + } + var current = this.parentNode.querySelector('.active'); + if (current) { + current.classList.remove('active'); + } + this.classList.add('active'); + var skillname = get.translation(this.link); + var skilltranslationinfo = get.skillInfoTranslation(this.link); + if ((lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') && skillname != '阵亡') { + var skillpinyin = lib.config.show_skillnamepinyin == 'showCodeIdentifier2' ? this.link : get.pinyin(skillname); + intro2.innerHTML = '' + skillname + '' + '' + '[' + skillpinyin + ']' + '' + ' ' + skilltranslationinfo; + } else { + intro2.innerHTML = '' + skillname + '' + skilltranslationinfo; + } + var info = get.info(this.link); + var skill = this.link; + var playername = this.linkname; + var skillnode = this; + if (info.derivation) { + var derivation = info.derivation; + if (typeof derivation == 'string') { + derivation = [derivation]; + } + for (var i = 0; i < derivation.length; i++) { + var derivationname = get.translation(derivation[i]); + var derivationtranslationinfo = get.skillInfoTranslation(derivation[i]); + if ((lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') && derivationname.length <= 5 && derivation[i].indexOf('_faq') == -1) { + var derivationpinyin = lib.config.show_skillnamepinyin == 'showCodeIdentifier2' ? derivation[i] : get.pinyin(derivationname); + intro2.innerHTML += '

          ' + derivationname + '' + '' + '[' + derivationpinyin + ']' + '' + ' ' + derivationtranslationinfo; + } else { + intro2.innerHTML += '

          ' + derivationname + '' + derivationtranslationinfo; + } + } + } + if (info.alter) { + intro2.innerHTML += '

          '; + var skillversionnode = intro2.querySelector('.hrefnode.skillversion'); + if (lib.config.vintageSkills.includes(skill)) { + skillversionnode.innerHTML = '切换至新版'; + } + else { + skillversionnode.innerHTML = '切换至旧版'; + } + skillversionnode.listen(function () { + if (lib.config.vintageSkills.includes(skill)) { + lib.config.vintageSkills.remove(skill); + lib.translate[skill + '_info'] = lib.translate[skill + '_info_alter']; + } + else { + lib.config.vintageSkills.push(skill); + lib.translate[skill + '_info'] = lib.translate[skill + '_info_origin']; + } + game.saveConfig('vintageSkills', lib.config.vintageSkills); + clickSkill.call(skillnode, 'init'); + }); + } + // if(e!=='init') game.trySkillAudio(this.link,playername); + // 有bug,先用旧版 + if (lib.config.background_speak && e !== 'init') { + let audio, skillnode = this; + (function play() { + if (!skillnode.audioList || !skillnode.audioList.length) { + skillnode.audioList = game.parseSkillAudio(skillnode.link, playername); + if (!skillnode.audioList.length) return; + } + audio = skillnode.audioList.shift(); + game.playAudio(audio, play); + })(); + } + }; + } + else { + // 样式一 + const introduction = ui.create.div('.characterintro', uiintro), showCharacterNamePinyin = lib.config.show_characternamepinyin; + if (showCharacterNamePinyin != 'doNotShow') { + const characterIntroTable = ui.create.div('.character-intro-table', introduction), span = document.createElement('span'); + span.style.fontWeight = 'bold'; + const nameInfo = get.character(name), exInfo = nameInfo[4], characterName = exInfo && exInfo.includes('ruby') ? lib.translate[name] : get.rawName2(name); + span.innerHTML = characterName; + const ruby = document.createElement('ruby'); + ruby.appendChild(span); + const leftParenthesisRP = document.createElement('rp'); + leftParenthesisRP.textContent = '('; + ruby.appendChild(leftParenthesisRP); + const rt = document.createElement('rt'); + rt.innerHTML = showCharacterNamePinyin == 'showCodeIdentifier' ? name : lib.translate[`${name}_rt`] || get.pinyin(characterName).join(' '); + ruby.appendChild(rt); + const rightParenthesisRP = document.createElement('rp'); + rightParenthesisRP.textContent = ')'; + ruby.appendChild(rightParenthesisRP); + characterIntroTable.appendChild(ruby); + const characterSexDiv = ui.create.div('.character-sex', characterIntroTable), exInfoSex = exInfo && exInfo.find(value => value.startsWith('sex:')), characterSex = exInfoSex ? exInfoSex.split(':').pop() : nameInfo[0]; + new Promise((resolve, reject) => { + const imageName = `sex_${characterSex}`, information = lib.card[imageName]; + if (!information) { + resolve(`${lib.assetURL}image/card/${imageName}.png`); + return; + } + const image = information.image; + if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); + else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); + else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); + else resolve(`${lib.assetURL}${image}`); + }).then(source => new Promise((resolve, reject) => { + const image = new Image(); + image.onload = () => resolve(image); + image.onerror = reject; + image.src = source; + })).then(image => characterSexDiv.appendChild(image)).catch(() => characterSexDiv.innerHTML = get.translation(characterSex)); + const characterGroupDiv = ui.create.div('.character-group', characterIntroTable), characterGroups = get.is.double(name, true); + if (characterGroups) Promise.all(characterGroups.map(characterGroup => new Promise((resolve, reject) => { + const imageName = `group_${characterGroup}`, information = lib.card[imageName]; + if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); + const image = information.image; + if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); + else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); + else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); + else resolve(`${lib.assetURL}${image}`); + }).then(source => new Promise((resolve, reject) => { + const image = new Image(); + image.onload = () => resolve(image); + image.onerror = reject; + image.src = source; + })))).then(images => { + let documentFragment = document.createDocumentFragment(); + images.forEach(documentFragment.appendChild, documentFragment); + characterGroupDiv.appendChild(documentFragment); + }).catch(() => characterGroupDiv.innerHTML = characterGroups.map(characterGroup => get.translation(characterGroup)).join('/')); + else { + const characterGroup = nameInfo[1]; + new Promise((resolve, reject) => { + const imageName = `group_${characterGroup}`, information = lib.card[imageName]; + if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); + const image = information.image; + if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); + else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); + else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); + else resolve(`${lib.assetURL}${image}`); + }).then(source => new Promise((resolve, reject) => { + const image = new Image(); + image.onload = () => resolve(image); + image.onerror = reject; + image.src = source; + })).then(image => characterGroupDiv.appendChild(image)).catch(() => characterGroupDiv.innerHTML = get.translation(characterGroup)); + } + const hpDiv = ui.create.div('.hp', characterIntroTable), nameInfoHP = nameInfo[2], infoHP = get.infoHp(nameInfoHP); + hpDiv.dataset.condition = infoHP < 4 ? 'mid' : 'high'; + ui.create.div(hpDiv); + const hpTextDiv = ui.create.div('.text', hpDiv), infoMaxHP = get.infoMaxHp(nameInfoHP); + hpTextDiv.innerHTML = infoHP == infoMaxHP ? `×${infoHP}` : `×${infoHP}/${infoMaxHP}`; + const infoShield = get.infoHujia(nameInfoHP); + if (infoShield) { + ui.create.div('.shield', hpDiv); + const shieldTextDiv = ui.create.div('.text', hpDiv); + shieldTextDiv.innerHTML = `×${infoShield}`; + } + introduction.appendChild(document.createElement('hr')); + } + const htmlParser = document.createElement('body'); + htmlParser.innerHTML = get.characterIntro(name); + Array.from(htmlParser.childNodes).forEach(value => introduction.appendChild(value)); + const introduction2 = ui.create.div('.characterintro.intro2', uiintro); + var list = get.character(name, 3) || []; + var skills = ui.create.div('.characterskill', uiintro); + if (lib.config.touchscreen) { + lib.setScroll(introduction); + lib.setScroll(introduction2); + lib.setScroll(skills); + } + + if (lib.config.mousewheel) { + skills.onmousewheel = ui.click.mousewheel; + } + var clickSkill = function (e) { + while (introduction2.firstChild) { + introduction2.removeChild(introduction2.lastChild); + } + var current = this.parentNode.querySelector('.active'); + if (current) { + current.classList.remove('active'); + } + this.classList.add('active'); + const skillNameSpan = document.createElement('span'), skillNameSpanStyle = skillNameSpan.style; + skillNameSpanStyle.fontWeight = 'bold'; + const link = this.link, skillName = get.translation(link); + skillNameSpan.innerHTML = skillName; + const showSkillNamePinyin = lib.config.show_skillnamepinyin; + if (showSkillNamePinyin != 'doNotShow' && skillName != '阵亡') { + const ruby = document.createElement('ruby'); + ruby.appendChild(skillNameSpan); + const leftParenthesisRP = document.createElement('rp'); + leftParenthesisRP.textContent = '('; + ruby.appendChild(leftParenthesisRP); + const rt = document.createElement('rt'); + rt.innerHTML = showSkillNamePinyin == 'showCodeIdentifier' ? link : lib.translate[`${link}_rt`] || get.pinyin(skillName).join(' '); + ruby.appendChild(rt); + const rightParenthesisRP = document.createElement('rp'); + rightParenthesisRP.textContent = ')'; + ruby.appendChild(rightParenthesisRP); + const div = ui.create.div(introduction2); + div.style.marginRight = '5px'; + div.appendChild(ruby); + } + else { + skillNameSpanStyle.marginRight = '5px'; + introduction2.appendChild(skillNameSpan); + } + htmlParser.innerHTML = get.skillInfoTranslation(this.link); + Array.from(htmlParser.childNodes).forEach(childNode => introduction2.appendChild(childNode)); + var info = get.info(this.link); + var skill = this.link; + var playername = this.linkname; + var skillnode = this; + let derivations = info.derivation; + if (derivations) { + if (typeof derivations == 'string') derivations = [derivations]; + derivations.forEach(derivation => { + introduction2.appendChild(document.createElement('br')); + introduction2.appendChild(document.createElement('br')); + const derivationNameSpan = document.createElement('span'), derivationNameSpanStyle = derivationNameSpan.style; + derivationNameSpanStyle.fontWeight = 'bold'; + const derivationName = get.translation(derivation); + derivationNameSpan.innerHTML = derivationName; + if (showSkillNamePinyin != 'doNotShow' && derivationName.length <= 5 && derivation.indexOf('_faq') == -1) { + const ruby = document.createElement('ruby'); + ruby.appendChild(derivationNameSpan); + const leftParenthesisRP = document.createElement('rp'); + leftParenthesisRP.textContent = '('; + ruby.appendChild(leftParenthesisRP); + const rt = document.createElement('rt'); + rt.innerHTML = showSkillNamePinyin == 'showCodeIdentifier' ? derivation : lib.translate[`${derivation}_rt`] || get.pinyin(derivationName).join(' '); + ruby.appendChild(rt); + const rightParenthesisRP = document.createElement('rp'); + rightParenthesisRP.textContent = ')'; + ruby.appendChild(rightParenthesisRP); + const div = ui.create.div(introduction2); + div.style.marginRight = '5px'; + div.appendChild(ruby); + } + else { + derivationNameSpanStyle.marginRight = '5px'; + introduction2.appendChild(derivationNameSpan); + } + htmlParser.innerHTML = get.skillInfoTranslation(derivation); + Array.from(htmlParser.childNodes).forEach(childNode => introduction2.appendChild(childNode)); + }); + } + if (info.alter) { + introduction2.appendChild(document.createElement('br')); + introduction2.appendChild(document.createElement('br')); + ui.create.div('.hrefnode.skillversion', introduction2); + var skillversionnode = introduction2.querySelector('.hrefnode.skillversion'); + if (lib.config.vintageSkills.includes(skill)) { + skillversionnode.innerHTML = '切换至新版'; + } + else { + skillversionnode.innerHTML = '切换至旧版'; + } + skillversionnode.listen(function () { + if (lib.config.vintageSkills.includes(skill)) { + lib.config.vintageSkills.remove(skill); + lib.translate[skill + '_info'] = lib.translate[skill + '_info_alter']; + } + else { + lib.config.vintageSkills.push(skill); + lib.translate[skill + '_info'] = lib.translate[skill + '_info_origin']; + } + game.saveConfig('vintageSkills', lib.config.vintageSkills); + clickSkill.call(skillnode, 'init'); + }); + } + // if(e!=='init') game.trySkillAudio(this.link,playername); + // 有bug,先用旧版 + if (lib.config.background_speak && e !== 'init') { + let audio, skillnode = this; + (function play() { + if (!skillnode.audioList || !skillnode.audioList.length) { + skillnode.audioList = game.parseSkillAudio(skillnode.link, playername); + if (!skillnode.audioList.length) return; + } + audio = skillnode.audioList.shift(); + game.playAudio(audio, play); + })(); + } + }; + } + + var initskill = false; + for (var i = 0; i < list.length; i++) { + if (!get.info(list[i]) || get.info(list[i]).nopop) continue; + if (!lib.translate[list[i]] || !lib.translate[list[i] + '_info']) continue; + var skilltrans = get.translation(list[i]); + if (skilltrans.startsWith(' ')) { + skilltrans = skilltrans.slice(6); + } + var current = ui.create.div('.menubutton.large', skills, clickSkill, skilltrans); + current.link = list[i]; + current.linkname = name; + if (!initskill) { + initskill = true; + clickSkill.call(current, 'init'); + } + } + + uiintro.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.touchpop); + layer.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clicklayer); + ui.window.appendChild(layer); + } + static intro(e) { + if (_status.dragged) return; + _status.clicked = true; + if (this.classList.contains('player') && !this.name) { + return; + } + if (this.parentNode == ui.historybar) { + if (ui.historybar.style.zIndex == '22') { + if (_status.removePop) { + if (_status.removePop(this) == false) return; + } + else { + return; + } + } + ui.historybar.style.zIndex = 22; + } + var uiintro; + if (this.classList.contains('card') && this.parentNode && + this.parentNode.classList.contains('equips') && get.is.phoneLayout() && + !get.is.mobileMe(this.parentNode.parentNode)) { + uiintro = get.nodeintro(this.parentNode.parentNode, false, e); + } + uiintro = uiintro || get.nodeintro(this, false, e); + if (!uiintro) return; + uiintro.classList.add('popped'); + uiintro.classList.add('static'); + ui.window.appendChild(uiintro); + var layer = ui.create.div('.poplayer', ui.window); + var clicklayer = function (e) { + if (_status.touchpopping) return; + delete ui.throwEmotion; + delete _status.removePop; + uiintro.delete(); + this.remove(); + ui.historybar.style.zIndex = ''; + delete _status.currentlogv; + if (!ui.arena.classList.contains('menupaused') && !uiintro.noresume) game.resume2(); + if (e && e.stopPropagation) e.stopPropagation(); + if (uiintro._onclose) { + uiintro._onclose(); + } + return false; + }; + layer.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clicklayer); + if (!lib.config.touchscreen) layer.oncontextmenu = clicklayer; + if (this.parentNode == ui.historybar && lib.config.touchscreen) { + var rect = this.getBoundingClientRect(); + e = { clientX: 0, clientY: rect.top + 30 }; + } + lib.placePoppedDialog(uiintro, e); + if (this.parentNode == ui.historybar) { + if (lib.config.show_history == 'right') { + uiintro.style.left = (ui.historybar.offsetLeft - 230) + 'px'; + } + else { + uiintro.style.left = (ui.historybar.offsetLeft + 60) + 'px'; + } + } + uiintro.style.zIndex = 21; + var clickintro = function () { + if (_status.touchpopping) return; + delete _status.removePop; + layer.remove(); + this.delete(); + ui.historybar.style.zIndex = ''; + delete _status.currentlogv; + if (!ui.arena.classList.contains('menupaused') && !uiintro.noresume) game.resume2(); + if (uiintro._onclose) { + uiintro._onclose(); + } + }; + var currentpop = this; + _status.removePop = function (node) { + if (node == currentpop) return false; + layer.remove(); + uiintro.delete(); + delete _status.removePop; + return true; + }; + if (uiintro.clickintro) { + uiintro.listen(function () { + _status.clicked = true; + }); + uiintro._clickintro = clicklayer; + } + else if (!lib.config.touchscreen) { + uiintro.addEventListener('mouseleave', clickintro); + uiintro.addEventListener('click', clickintro); + } + else if (uiintro.touchclose) { + uiintro.listen(clickintro); + } + uiintro._close = clicklayer; + + game.pause2(); + return uiintro; + } + static intro2() { + if (ui.intro) { + ui.intro.close(); + if (ui.intro.source == this) { + delete ui.intro; + ui.control.show(); + game.resume2(); + return; + } + } + } + static auto() { + if (!ui || !ui.auto || ui.auto.classList.contains('hidden') && arguments[0] !== 'forced') return; + if (_status.paused2) return; + ui.click.shortcut(false); + if (!_status.auto) { + _status.auto = true; + ui.auto.classList.add('glow'); + ui.arena.classList.add('auto'); + + if (_status.imchoosing && _status.paused) { + if (ui.confirm) ui.confirm.close(); + ui.control.hide(); + if (_status.event.switchToAuto) { + _status.event.switchToAuto(); + } + else { + if (_status.paused && _status.imchoosing) { + game.uncheck(); + _status.event.redo(); + } + } + game.resume(); + } + else if (_status.event.switchToAuto) { + _status.event.switchToAuto(); + } + if (game.online) { + game.send('auto'); + } + else if (_status.connectMode) { + game.broadcastAll(function (player) { + player.setNickname(player.nickname + ' - 托管'); + }, game.me); + } + } + else { + if (game.notMe) return; + ui.control.show(); + _status.auto = false; + ui.auto.classList.remove('glow'); + ui.arena.classList.remove('auto'); + + if (game.online) { + game.send('unauto'); + } + else if (_status.connectMode) { + game.broadcastAll(function (player) { + player.setNickname(player.nickname); + }, game.me); + } + } + } + static wuxie() { + if (this.classList.contains('hidden')) return; + this.classList.toggle('glow'); + if (this.classList.contains('glow') && _status.event.type == 'wuxie' && + _status.event.isMine() && ui.confirm && _status.imchoosing) { + ui.click.cancel(ui.confirm.lastChild); + } + } + static tempnowuxie() { + if (this.classList.contains('hidden')) return; + this.classList.toggle('glow'); + if (this.classList.contains('glow') && _status.event.type == 'wuxie' && + _status.event.isMine() && ui.confirm && _status.imchoosing) { + var triggerevent = _status.event.getTrigger(); + if (triggerevent && this._origin == triggerevent.parent.id) { + if (triggerevent.targets && triggerevent.num == triggerevent.targets.length - 1) { + this.close(); + } + } + ui.click.cancel(ui.confirm.lastChild); + } + } + static pause() { + if (_status.paused2 || _status.pausing || _status.nopause || !ui.pause) return; + if (!_status.video) { + if (ui.pause.classList.contains('hidden')) return; + if (!_status.gameStarted) return; + } + ui.system.hide(); + game.pause2(); + var node = ui.create.pause(); + if (!node) return; + node.addTempClass('start'); + ui.sidebar3.innerHTML = ''; + if (lib.config.show_discardpile) { + for (var i = 0; i < ui.discardPile.childNodes.length; i++) { + var div = ui.create.div(ui.sidebar3); + div.innerHTML = get.translation(ui.discardPile.childNodes[i]); + ui.sidebar3.insertBefore(div, ui.sidebar3.firstChild); + } + } + node.appendChild(ui.sidebar); + node.appendChild(ui.sidebar3); + ui.historybar.classList.add('paused'); + ui.arena.classList.add('paused'); + ui.window.classList.add('touchinfohidden'); + ui.time.hide(); + if (game.onpause) { + game.onpause(); + } + } + static resume(e) { + if (_status.pausing) return; + if (_status.dragged) return; + if (_status.clicked) return; + this.delete(); + ui.system.show(); + ui.time.show(); + ui.historybar.classList.remove('paused'); + ui.arena.classList.remove('paused'); + ui.window.classList.remove('touchinfohidden'); + game.resume2(); + e.stopPropagation(); + if (game.onresume) { + game.onresume(); + } + return false; + } + static config() { + if (!ui.click.configMenu) return; + if (_status.paused2) _status.config2 = false; + else _status.config2 = true; + + _status.clicked = true; + game.pause2(); + ui.click.configMenu(); + ui.system1.classList.remove('shown'); + ui.system2.classList.remove('shown'); + } + static swap() { + if (_status.dragged) return; + if (this.classList.contains('dead')) return; + if (_status.over) return; + if (ui.auto) ui.auto.show(); + if (ui.wuxie) ui.wuxie.show(); + game.swapPlayer(this); + } + static mousewheel(evt) { + if (this.firstChild && this.firstChild.classList.contains('handcards') && + !this.classList.contains('scrollh')) return; + var node = this; + var num = this._scrollnum || 6; + var speed = this._scrollspeed || 16; + clearInterval(node.interval); + if (evt.detail > 0 || evt.wheelDelta < 0) { + node.interval = setInterval(function () { + if (num-- && Math.abs(node.scrollLeft + node.clientWidth - node.scrollWidth) > 0) { + node.scrollLeft += speed; + } + else { + clearInterval(node.interval); + } + }, 16); + } + else { + node.interval = setInterval(function () { + if (num-- && node.scrollLeft > 0) { + node.scrollLeft -= speed; + } + else { + clearInterval(node.interval); + } + }, 16); + } + } + static touchStart(e) { + this.startX = e.touches[0].clientX / game.documentZoom; + this.startY = e.touches[0].clientY / game.documentZoom; + _status.dragged = false; + } + static dialogtouchStart(e) { + ui.click.touchStart.call(this, e); + _status.dialogtouched = true; + } + static touchScroll(e) { + if (_status.mousedragging) return; + if (_status.draggingtouchdialog) return; + if (!_status.dragged) { + if (Math.abs(e.touches[0].clientX / game.documentZoom - this.startX) > 10 || + Math.abs(e.touches[0].clientY / game.documentZoom - this.startY) > 10) { + _status.dragged = true; + } + } + if ((this == ui.handcards1Container || this == ui.handcards2Container) && !this.classList.contains('scrollh')) { + e.preventDefault(); + } + else if (lib.device == 'ios' && this.scrollHeight <= this.offsetHeight + 5 && this.scrollWidth <= this.offsetWidth + 5) { + e.preventDefault(); + } + else { + delete _status._swipeorigin; + e.stopPropagation(); + } + } + static autoskill(bool, node) { + var list = lib.config.autoskilllist; + if (bool) { + list.remove(node.link); + } + else { + list.add(node.link); + } + game.saveConfig('autoskilllist', list); + } + static skillbutton() { + this.func(this.link); + } + static autoskill2(e) { + this.classList.toggle('on'); + var list = []; + if (lib.skill[this.link].frequent) { + list.push(this.link); + } + if (lib.skill[this.link].subfrequent) { + for (var i = 0; i < lib.skill[this.link].subfrequent.length; i++) { + list.push(this.link + '_' + lib.skill[this.link].subfrequent[i]); + } + } + for (var i = 0; i < list.length; i++) { + if (this.classList.contains('on')) { + lib.config.autoskilllist.remove(list[i]); + } + else { + lib.config.autoskilllist.add(list[i]); + } + } + game.saveConfig('autoskilllist', lib.config.autoskilllist); + ui.click.touchpop(); + e.stopPropagation(); + } + static hiddenskill(e) { + this.classList.toggle('on'); + var hidden = lib.skill[this.link].preHidden; + if (Array.isArray(hidden)) { + if (this.classList.contains('on')) { + _status.prehidden_skills.removeArray(hidden); + } + else { + _status.prehidden_skills.addArray(hidden); + } + } + if (this.classList.contains('on')) { + _status.prehidden_skills.remove(this.link); + } + else { + _status.prehidden_skills.add(this.link); + } + ui.click.touchpop(); + e.stopPropagation(); + } + static rightplayer(e) { + if (this._nopup) return false; + if (_status.clickedplayer) { + return false; + } + + if (this._mouseenterdialog && this._mouseenterdialog.parentNode) { + this._mouseenterdialog.delete(); + } + else { + ui.click.intro.call(this, e); + } + _status.clickedplayer = true; + _status.clicked = false; + ui.click.longpresscancel.call(this); + return false; + } + static right(e) { + if (window.inSplash) return false; + if (lib.config.touchscreen) return; + if (_status.noright) { + _status.noright = false; + return false; + } + if (_status.clickedplayer) { + _status.clickedplayer = false; + return; + } + game.closePopped(); + switch (lib.config.right_click) { + case 'shortcut': ui.click.shortcut(); break; + case 'pause': ui.click.pause(); break; + case 'auto': ui.click.auto(); break; + case 'config': ui.click.config(); break; + } + e.preventDefault(); + return false; + } + +} + +export class UI extends Uninstantable { + static updates = []; + static thrown = []; + static touchlines = []; + static todiscard = {}; + /** + * @type { HTMLStyleElement[] } + */ + static playerPositions = []; + static create = Create; + static click = Click; + static selected = { + /** + * @type { Button[] } + */ + buttons: [], + /** + * @type { Card[] } + */ + cards: [], + /** + * @type { Player[] } + */ + targets: [] + }; + /** + * @type { Dialog[] } + */ + static dialogs; + /** + * @type { Dialog } + */ + static dialog; + /** + * @type { HTMLDivElement } + */ + static arena; + /** + * @type { Control[] } + */ + static controls; + /** + * @type { Control } + */ + static control; + /** + * @type { Control | undefined } + */ + static confirm; + /** + * @type { Control | undefined } + */ + static skills; + /** + * @type { Control | undefined } + */ + static skills1; + /** + * @type { Control | undefined } + */ + static skills2; + /** + * @type { Control | undefined } + */ + static skills3; + static refresh(node) { + void window.getComputedStyle(node, null).getPropertyValue("opacity"); + } + static clear() { + game.addVideo('uiClear'); + var thrown = document.getElementsByClassName('thrown'); + var nodes = []; + var i; + for (i = 0; i < thrown.length; i++) { + nodes.push(thrown[i]); + } + for (i = 0; i < nodes.length; i++) { + if (!nodes[i].fixed) nodes[i].delete(); + } + } + static updatec() { + if (_status.noupdatec) return; + var length = 0, minoffset = -Infinity; + var controls = []; + var widths = []; + var leftwidths = []; + var add = function (node, first) { + var thiswidth = parseInt(node.style.width); + if (thiswidth) { + thiswidth += 8; + length += thiswidth; + if (first) { + leftwidths.push(thiswidth); + } + else { + widths.push(thiswidth); + } + } + else { + length += node.offsetWidth; + if (first) { + leftwidths.push(node.offsetWidth); + } + else { + widths.push(node.offsetWidth); + } + } + if (first) { + controls.unshift(node); + } + else { + controls.push(node); + } + }; + widths = leftwidths.concat(widths); + var staylefts = []; + for (var i = 0; i < ui.control.childNodes.length; i++) { + if (ui.control.childNodes[i].classList.contains('removing')) continue; + if (lib.config.wuxie_right && ui.control.childNodes[i].stayleft) { + staylefts.push(ui.control.childNodes[i]); + } + else { + add(ui.control.childNodes[i]); + } + } + if (staylefts.length) { + var fullwidth = 0; + var fullright = (game.layout == 'long' || game.layout == 'long2' || game.chess || (game.layout != 'nova' && parseInt(ui.arena.dataset.number) <= 5)); + for (var i = 0; i < widths.length; i++) { + fullwidth += widths[i] + 6; + if (get.is.phoneLayout()) fullwidth += 6; + } + fullwidth /= 2; + var currentLeft = 0; + for (var stayleft of staylefts) { + stayleft.currentLeft = currentLeft; + fullwidth += stayleft.offsetWidth; + currentLeft += stayleft.offsetWidth; + if (get.is.phoneLayout()) { + fullwidth += 18; + currentLeft += 18; + } + else { + fullwidth += 12; + currentLeft += 12; + } + } + if (fullright) { + fullwidth += 124; + if ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.dataset.number == '8' && get.mode() != 'boss') { + fullwidth += game.me.getLeft(); + } + } + else { + fullwidth += 154; + } + for (var stayleft of staylefts) { + if (game.layout != 'default') { + var current_offset = stayleft._offset; + if (fullright) { + stayleft._offset = Math.ceil(-ui.arena.offsetWidth / 2) + 135; + if ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.dataset.number == '8' && get.mode() != 'boss') { + stayleft._offset += game.me.getLeft(); + } + } + else { + stayleft._offset = Math.ceil(-ui.arena.offsetWidth / 2) + 165; + } + stayleft._offset += stayleft.currentLeft; + + if (current_offset != stayleft._offset) { + stayleft.addTempClass('controlpressdownx', 500); + stayleft.style.transform = 'translateX(' + stayleft._offset + 'px)'; + } + } + else { + add(stayleft, true); + } + } + if (staylefts.length && controls.length) { + var last = staylefts[staylefts.length - 1]; + minoffset = last._offset + last.offsetWidth + (get.is.phoneLayout() ? 18 : 12); + } + } + if (!controls.length) return; + var offset = -length / 2; + if (minoffset > offset) offset = minoffset; + var control = controls.shift(); + if (control._offset != offset) { + control.addTempClass('controlpressdownx', 500); + control.style.transform = 'translateX(' + offset + 'px)'; + control._offset = offset; + } + while (controls.length) { + var control = controls.shift(); + var width = widths.shift(); + offset += width + 6; + if (get.is.phoneLayout()) { + offset += 6; + } + if (control._offset != offset) { + control.addTempClass('controlpressdownx', 500); + control.style.transform = 'translateX(' + offset + 'px)'; + control._offset = offset; + } + } + } + static updatex() { + ui.update.apply(this, arguments); + ui.updatehl(); + for (var i = 0; i < lib.onresize.length; i++) { + lib.onresize[i](); + } + var cfg = game.documentZoom / game.deviceZoom; + ui.updated(); + game.documentZoom = cfg * game.deviceZoom; + ui.updatez(); + delete ui._updatexr; + } + static updatexr() { + if (ui._updatexr) { + clearTimeout(ui._updatexr); + } + ui._updatexr = setTimeout(ui.updatex, 500); + } + static updatejm(player, nodes, start, inv) { + if (typeof start != 'number') { + start = 0; + } + var str; + if (get.is.mobileMe(player) || game.layout == 'default' || player.classList.contains('linked')) { + str = 'translateX('; + if (inv) { + str += '-'; + } + } + else { + str = 'translateY('; + } + var num = 0; + for (var i = 0; i < nodes.childElementCount; i++) { + var node = nodes.childNodes[i]; + if (i < start) { + node.style.transform = ''; + } + else if (node.classList.contains('removing')) { + start++; + } + else { + ui.refresh(node); + node.classList.remove('drawinghidden'); + node._transform = str + ((i - start) * 28) + 'px)'; + node.style.transform = node._transform; + } + } + } + static updatem(player) { + if (player) { + var start = 0; + if (!player.classList.contains('linked2') || !ui.arena.classList.contains('nolink')) { + start = 1; + } + ui.updatejm(player, player.node.marks, start, get.is.mobileMe(player)); + } + else { + for (var i = 0; i < game.players.length; i++) { + ui.updatem(game.players[i]); + } + } + } + static updatej(player) { + if (player) { + ui.updatejm(player, player.node.judges); + } + else { + for (var i = 0; i < game.players.length; i++) { + ui.updatej(game.players[i]); + } + } + } + static updatehl() { + if (!game.me) return; + if (!ui.handcards1Container || !ui.handcards2Container) return; + if (!ui.handcards1Container.childNodes.length) return; + var hs1 = [], hs2 = []; + for (var i = 0; i < ui.handcards1Container.firstChild.childElementCount; i++) { + if (!ui.handcards1Container.firstChild.childNodes[i].classList.contains('removing')) { + hs1.push(ui.handcards1Container.firstChild.childNodes[i]); + } + } + for (var i = 0; i < ui.handcards2Container.firstChild.childElementCount; i++) { + if (!ui.handcards2Container.firstChild.childNodes[i].classList.contains('removing')) { + hs2.push(ui.handcards2Container.firstChild.childNodes[i]); + } + } + var offset1, offset12 = 0; + if (!lib.config.fold_card) { + offset1 = 112; + ui.handcards1Container.classList.add('scrollh'); + } + else { + offset1 = Math.min(112, (ui.handcards1Container.offsetWidth - 128) / (hs1.length - 1)); + if (hs1.length > 1 && offset1 < 32) { + offset1 = 32; + ui.handcards1Container.classList.add('scrollh'); + } + else { + ui.handcards1Container.classList.remove('scrollh'); + } + } + if (offset1 < 100) { + offset12 = 100 - offset1; + } + for (var i = 0; i < hs1.length; i++) { + hs1[i].style.transform = 'translateX(' + (i * offset1) + 'px)'; + hs1[i]._transform = 'translateX(' + (i * offset1) + 'px)'; + ui.refresh(hs1[i]); + hs1[i].classList.remove('drawinghidden'); + if (offset12 > 40) { + offset12 = 90 - hs1[i].node.info.offsetWidth; + hs1[i].node.info.querySelector('span').style.display = 'none'; + if (hs1[i].node.name.classList.contains('long')) { + hs1[i].node.name.style.transform = 'translateY(16px) scale(0.85)'; + hs1[i].node.name.style.transformOrigin = 'top left'; + } + else { + hs1[i].node.name.style.transform = 'translateY(16px)'; + } + hs1[i].node.info.style.transform = 'translateX(-' + offset12 + 'px) translateY(-3px)'; + } + else { + hs1[i].node.info.querySelector('span').style.display = ''; + hs1[i].node.name.style.transform = ''; + hs1[i].node.name.style.transformOrigin = ''; + hs1[i].node.info.style.transform = 'translateX(-' + offset12 + 'px)'; + } + } + ui.handcards1Container.firstChild.style.width = (offset1 * (hs1.length - 1) + 118) + 'px'; + + var offset2, offset22 = 0; + if (!lib.config.fold_card) { + offset2 = 112; + ui.handcards2Container.classList.add('scrollh'); + } + else { + offset2 = Math.min(112, (ui.handcards2Container.offsetWidth - 128) / (hs2.length - 1)); + if (hs2.length > 1 && offset2 < 32) { + offset2 = 32; + ui.handcards2Container.classList.add('scrollh'); + } + else { + ui.handcards2Container.classList.remove('scrollh'); + } + } + if (offset2 < 100) { + offset22 = 100 - offset2; + } + for (var i = 0; i < hs2.length; i++) { + hs2[i].style.transform = 'translateX(' + (i * offset2) + 'px)'; + hs2[i]._transform = 'translateX(' + (i * offset2) + 'px)'; + ui.refresh(hs2[i]); + hs2[i].classList.remove('drawinghidden'); + if (offset22 > 40) { + offset22 = 90 - hs2[i].node.info.offsetWidth; + hs2[i].node.info.querySelector('span').style.display = 'none'; + if (hs2[i].node.name.classList.contains('long')) { + hs2[i].node.name.style.transform = 'translateY(16px) scale(0.85)'; + hs2[i].node.name.style.transformOrigin = 'top left'; + } + else { + hs2[i].node.name.style.transform = 'translateY(16px)'; + } + hs2[i].node.info.style.transform = 'translateX(-' + offset22 + 'px) translateY(-3px)'; + } + else { + hs2[i].node.info.querySelector('span').style.display = ''; + hs2[i].node.name.style.transform = ''; + hs2[i].node.name.style.transformOrigin = ''; + hs2[i].node.info.style.transform = 'translateX(-' + offset22 + 'px)'; + } + } + ui.handcards2Container.firstChild.style.width = (offset2 * (hs2.length - 1) + 118) + 'px'; + } + static updateh(compute) { + if (!game.me) return; + if (!ui.handcards1Container) return; + if (lib.config.low_performance) { + if (compute) { + ui.updatehl(); + setTimeout(ui.updatehl, 1000); + } + return; + } + if (compute) { + ui.handcards1Container._handcardsWidth = ui.handcards1Container.offsetWidth; + ui.handcards2Container._handcardsWidth = ui.handcards2Container.offsetWidth; + } + ui.updatehx(game.me.node.handcards1); + ui.updatehx(game.me.node.handcards2); + } + static updatehx(node) { + var width = node.parentNode._handcardsWidth; + var num = node.childElementCount - node.getElementsByClassName('removing').length; + node.classList.remove('fold0'); + node.classList.remove('fold1'); + node.classList.remove('fold2'); + node.classList.remove('fold3'); + if (num * 78 + 40 >= width) { + // node.dataset.fold=3; + node.classList.add('fold3'); + } + else if (num * 93 + 25 >= width) { + // node.dataset.fold=2; + node.classList.add('fold2'); + } + else if (num * 112 + 6 >= width) { + // node.dataset.fold=1; + node.classList.add('fold1'); + } + else { + // node.dataset.fold=0; + node.classList.add('fold0'); + } + } + static updated() { + if (document.documentElement.offsetWidth < 900 || document.documentElement.offsetHeight < 500) { + game.deviceZoom = Math.min( + Math.round(document.documentElement.offsetWidth / 98) / 10, + Math.round(document.documentElement.offsetHeight / 50) / 10 + ); + } + else { + game.deviceZoom = 1; + } + } + static updatez() { + var width = document.documentElement.offsetWidth; + var height = document.documentElement.offsetHeight; + var zoom = game.documentZoom; + if (zoom != 1) { + document.body.style.width = Math.round(width / zoom) + 'px'; + document.body.style.height = Math.round(height / zoom) + 'px'; + document.body.style.transform = 'scale(' + (Math.floor(zoom * 100) / 100) + ')'; + } + else { + document.body.style.width = width + 'px'; + document.body.style.height = height + 'px'; + document.body.style.transform = ''; + } + } + static update() { + for (var i = 0; i < ui.updates.length; i++) { + ui.updates[i](); + } + if (ui.dialog && !ui.dialog.classList.contains('noupdate')) { + if (game.chess) { + if (ui.dialog.content.scrollHeight < 240 && (!ui.dialog.buttons || !ui.dialog.buttons.length) && !ui.dialog.forcebutton) { + ui.dialog.style.height = ui.dialog.content.offsetHeight + 'px'; + ui.dialog.classList.add('slim'); + } + else { + ui.dialog.style.height = ''; + ui.dialog.classList.remove('slim'); + } + } + else { + if ((!ui.dialog.buttons || !ui.dialog.buttons.length) && !ui.dialog.forcebutton && ui.dialog.classList.contains('fullheight') == false && get.mode() != 'stone') { + ui.dialog.classList.add('nobutton'); + if (ui.dialog.content.offsetHeight < 240) { + if (!ui.dialog._heightset) { + ui.dialog._heightset = ui.dialog.style.height || true; + } + ui.dialog.style.height = ui.dialog.content.offsetHeight + 'px'; + if (lib.config.show_log != 'off') { + ui.dialog.classList.add('scroll1'); + ui.dialog.classList.add('scroll2'); + return; + } + } + else { + if (typeof ui.dialog._heightset == 'string') { + ui.dialog.style.height = ui.dialog._heightset; + } + else if (ui.dialog._heightset) { + ui.dialog.style.height = ''; + } + delete ui.dialog._heightset; + } + } + else { + if (typeof ui.dialog._heightset == 'string') { + ui.dialog.style.height = ui.dialog._heightset; + } + else if (ui.dialog._heightset) { + ui.dialog.style.height = ''; + } + delete ui.dialog._heightset; + ui.dialog.classList.remove('nobutton'); + } + } + var height1 = ui.dialog.content.offsetHeight; + var height2 = ui.dialog.contentContainer.offsetHeight; + if (game.chess) { + if (height1 < 240) { + ui.dialog.style.height = height1 + 'px'; + } + } + else { + if (!ui.dialog.forcebutton && !ui.dialog._scrollset && (height1 <= 190 || (height2 >= height1 && height2 >= 210))) { + ui.dialog.classList.remove('scroll1'); + ui.dialog.classList.remove('scroll2'); + } + else { + ui.dialog.classList.add('scroll1'); + ui.dialog.classList.add('scroll2'); + if (game.layout != 'default') { + ui.dialog.style.height = Math.min(height1, ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.classList.contains('choose-character')) ? 380 : 350) + 'px'; + ui.dialog._scrollset = true; + } + } + if (game.layout == 'long2' || game.layout == 'nova') { + if (height1 + 240 >= ui.arena.offsetHeight) { + ui.dialog.classList.add('scroll3'); + } + else { + ui.dialog.classList.remove('scroll3'); + } + } + } + } + } + static recycle(node, key) { + if (!ui._recycle) ui._recycle = {}; + if (typeof node == 'string') { + return ui._recycle[node]; + } + ui._recycle[key] = node; + } + /** + * @author curpond + * @author Tipx-L + * @param {number} [numberOfPlayers] + */ + static updateConnectPlayerPositions(numberOfPlayers) { + if (typeof numberOfPlayers != 'number') { + const configOL = lib.configOL; + numberOfPlayers = parseInt(configOL.player_number) || configOL.number; + } + if (!numberOfPlayers) return; + const playerPositions = ui.playerPositions; + playerPositions.forEach((position) => { + game.dynamicStyle.remove(position); + }); + playerPositions.length = 0; + const temporaryPlayer = ui.create.div('.player.connect', ui.window).hide(); + const computedStyle = getComputedStyle(temporaryPlayer); + const halfWidth = parseFloat(computedStyle.width) / 2; + const halfHeight = parseFloat(computedStyle.height) / 2; + temporaryPlayer.remove(); + const halfNumberOfPlayers = Math.round(numberOfPlayers / 2); + const upperPercentage = 100 / (halfNumberOfPlayers + 1); + const scale = 10 / numberOfPlayers; + for (let ordinal = 0; ordinal < halfNumberOfPlayers; ordinal++) { + const selector = `#window>.player.connect[data-position='${ordinal}']`; + const css = { + left: `calc(${upperPercentage * (ordinal + 1)}% - ${halfWidth}px)`, + top: `calc(${100 / 3}% - ${halfHeight}px)` + }; + if (scale < 1) + css["transform"] = `scale(${scale})`; + + game.dynamicStyle.add(selector, css); + playerPositions.push(selector); + } + const lowerPercentage = 100 / (numberOfPlayers - halfNumberOfPlayers + 1); + for (let ordinal = halfNumberOfPlayers; ordinal < numberOfPlayers; ordinal++) { + const selector = `#window>.player.connect[data-position='${ordinal}']`; + const css = { + left: `calc(${lowerPercentage * (ordinal - halfNumberOfPlayers + 1)}% - ${halfWidth}px)`, + top: `calc(${100 * 2 / 3}% - ${halfHeight}px)` + }; + if (scale < 1) + css["transform"] = `scale(${scale})`; + + game.dynamicStyle.add(selector, css); + playerPositions.push(selector); + } + } + /** + * @author curpond + * @author Tipx-L + * @param {number} [numberOfPlayers] + */ + static updatePlayerPositions(numberOfPlayers) { + if (typeof numberOfPlayers != 'number') numberOfPlayers = ui.arena.dataset.number; + //当人数不超过8人时,还是用以前的布局 + if (!numberOfPlayers || numberOfPlayers <= 8) return; + const playerPositions = ui.playerPositions; + playerPositions.forEach((position) => { + game.dynamicStyle.remove(position); + }); + playerPositions.length = 0; + //单个人物的宽度,这里要设置玩家的实际的宽度 + const temporaryPlayer = ui.create.div('.player', ui.arena).hide(); + const computedStyle = getComputedStyle(temporaryPlayer); + const scale = 6 / numberOfPlayers; + //玩家顶部距离父容器上边缘的距离偏移的单位距离 + const quarterHeight = parseFloat(computedStyle.height) / 4 * scale; + const halfWidth = parseFloat(computedStyle.width) / 2; + temporaryPlayer.remove(); + //列数,即假如8人场,除去自己后,上面7个人占7列 + const columnCount = numberOfPlayers - 1; + const percentage = 90 / (columnCount - 1); + //仅当游戏人数大于8人,且玩家的座位号大于0时,设置玩家的位置;因为0号位是game.me在最下方,无需设置 + for (let ordinal = 1; ordinal < numberOfPlayers; ordinal++) { + const reversedOrdinal = columnCount - ordinal; + //动态计算玩家的top属性,实现拱桥的效果;只让两边的各两个人向下偏移一些 + const top = Math.max(0, Math.round(numberOfPlayers / 5) - Math.min(Math.abs(ordinal - 1), Math.abs(reversedOrdinal))) * quarterHeight; + const selector = `#arena[data-number='${numberOfPlayers}']>.player[data-position='${ordinal}']`; + game.dynamicStyle.add(selector, { + left: `calc(${percentage * reversedOrdinal + 5}% - ${halfWidth}px)`, + top: `${top}px`, + transform: `scale(${scale})` + }); + playerPositions.push(selector); + } + } + static updateRoundNumber(roundNumber, cardPileNumber) { + if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = `${roundNumber}轮 剩余牌: ${cardPileNumber}`; + } +}; + +export const ui = UI; diff --git a/noname/util/browser.js b/noname/util/browser.js new file mode 100644 index 000000000..7e84aa899 --- /dev/null +++ b/noname/util/browser.js @@ -0,0 +1,19 @@ +import { PromiseErrorHandler } from './struct/index.js'; + +/** + * 从浏览器名到不同浏览器下异步处理方式的映射 + * + * `key`的值同`get.coreInfo`函数返回值的第一个元素 + * + * @type {Record<"firefox" | "chrome" | "safari" | "other", new () => PromiseErrorHandler>} + */ +export const promiseErrorHandlerMap = { + 'chrome': PromiseErrorHandler.ChromePromiseErrorHandler, + 'firefox': PromiseErrorHandler.FirefoxPromiseErrorHandler, + 'safari': PromiseErrorHandler.UnknownPromiseErrorHandler, + 'other': PromiseErrorHandler.UnknownPromiseErrorHandler +}; + +/** + * @typedef {import('./struct/interface/promise-error-handler.js').PromiseErrorHandler} PromiseErrorHandler + */ diff --git a/noname/util/mutex.js b/noname/util/mutex.js index 74d87659b..cce998fc7 100644 --- a/noname/util/mutex.js +++ b/noname/util/mutex.js @@ -1,18 +1,24 @@ /** - * + * 一个非常普通的“锁” */ export class Mutex { /** + * 锁目前的状态,只有“unlocked”和“locked”两种情况 + * * @type {'locked' | 'unlocked'} */ #status; /** + * 上锁后用于等待的锁Promise + * * @type {null | Promise} */ #promise; /** + * 上锁后用于触发锁Promise的resolve函数 + * * @type {null | function(): void} */ #resolve; @@ -23,6 +29,11 @@ export class Mutex { this.#resolve = null; } + /** + * 上锁 + * + * 请时刻记住使用`await Mutex#lock()`来使锁正常工作 + */ async lock() { switch (this.#status) { case 'locked': @@ -36,6 +47,11 @@ export class Mutex { } } + /** + * 解锁 + * + * 请不要在未上锁的情况下解锁 + */ unlock() { if (this.#status === 'unlocked') throw new Error('This Mutex is not locked.'); @@ -44,6 +60,7 @@ export class Mutex { } /** + * 启用锁的try-finally封装,用于在函数执行完后自动解放锁的控制权(就算发生错误) * * @param {function(): void | Promise} content */ diff --git a/noname/util/struct/index.js b/noname/util/struct/index.js new file mode 100644 index 000000000..3515a4fad --- /dev/null +++ b/noname/util/struct/index.js @@ -0,0 +1,5 @@ +/** + * 无名杀内部所需要的数据结构 + */ + +export * as PromiseErrorHandler from './promise-error-handler/index.js'; diff --git a/noname/util/struct/interface/index.d.ts b/noname/util/struct/interface/index.d.ts new file mode 100644 index 000000000..eaed359b5 --- /dev/null +++ b/noname/util/struct/interface/index.d.ts @@ -0,0 +1,5 @@ +/** + * 无名杀内部构建所需要用到的接口 + */ + +export { PromiseErrorHandler } from './promise-error-handler' diff --git a/noname/util/struct/interface/promise-error-handler.d.ts b/noname/util/struct/interface/promise-error-handler.d.ts new file mode 100644 index 000000000..6c35dcf55 --- /dev/null +++ b/noname/util/struct/interface/promise-error-handler.d.ts @@ -0,0 +1,53 @@ +/** + * 不同浏览器下异步报错问题处理方式的接口,用于定义不同浏览器对待异步报错的处理方式 + */ +export interface PromiseErrorHandler { + /** + * 当异步处理对象初始化时执行的操作 + * + * 因为未来或许会涉及到错误处理方式的更改,故所有初始化操作请于此处执行 + * + * 若该函数为异步函数,则将阻塞运行 + */ + onLoad?(): void | Promise + + /** + * 当异步处理对象被释放时执行的操作 + * + * 目前版本无任何用处,请等待未来的更新 + * + * 未来或许会涉及到错误处理方式的更改,此后请使用无名杀提供的方式来进行异步错误处理的更改 + * + * 若该函数为异步函数,则将阻塞运行 + */ + onUnload?(): void | Promise + + /** + * 当全局监听器捕获到`unhandledrejection`事件时会调用的函数 + * + * 该函数用于正式处理异步报错事件 + * + * 该函数为异步函数时不会阻塞运行 + * + * @param event - 被捕获到的异步报错事件 + */ + onHandle?(event: PromiseRejectionEvent): void | Promise + + /** + * 当触发`window.onerror`时会调用的函数 + * + * 用于在执行`window.onerror`前执行一些可能存在的善后操作 + * + * 该函数无法为异步函数 + */ + onErrorPrepare?(): void + + /** + * 当`window.onerror`运行**即将结束**时会调用的函数 + * + * 用于在执行`window.onerror`后执行一些可能存在的善后操作 + * + * 该函数无法为异步函数 + */ + onErrorFinish?(): void +} diff --git a/noname/util/struct/promise-error-handler/chrome.js b/noname/util/struct/promise-error-handler/chrome.js new file mode 100644 index 000000000..6519c2d55 --- /dev/null +++ b/noname/util/struct/promise-error-handler/chrome.js @@ -0,0 +1,87 @@ +/** + * 关于`Google Chrome`的异步错误处理 + * + * `Chrome`所用的`v8`引擎为`Error`提供了特有的报错栈堆处理函数,用于用户自定义报错栈堆的内容。 + * + * 我们用到了`Error.prepareStackTrace(error, structuredStackTrace)`这个函数,这个函数的信息可参考[这里](https://v8.dev/docs/stack-trace-api#customizing-stack-traces) + * + * 该函数提供了结构化的栈堆信息,很幸运的是,这个结构化的栈堆能直接告诉我们报错的文件以及位置,故我们使用该函数,让异步报错能直接定位原始位置 + * + * @implements {PromiseErrorHandler} + */ +export class ChromePromiseErrorHandler { + + /** + * 用于临时记录报错信息的列表,通过`Error.prepareStackTrace`更新该列表 + * + * @type {[Error, NodeJS.CallSite[]][]} + */ + #errorList; + + /** + * @type {typeof Error.prepareStackTrace} + */ + #originErrorPrepareStackTrace; + + /** + * 初始化`Error.prepareStackTrace`,将该值赋值成我们需要的函数 + * + * 未防止本来Error.prepareStackTrace便存在赋值的行为,我们将原始值存储,并在需要的函数中调用 + * + * > 这或许就是本体扩展化的第一步(小声) + */ + onLoad() { + this.#errorList = []; + this.#originErrorPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = (error, stackTraces) => { + // 其实这步或许不需要 + // 但真赋值了Error.prepareStackTrace的话,保不齐会出现需要返回值的情况 + const result = this.#originErrorPrepareStackTrace + ? this.#originErrorPrepareStackTrace(error, stackTraces) + : void 0; + this.#errorList.push([error, stackTraces]); + return result; + }; + } + + /** + * 将原来可能的`Error.prepareStackTrace`赋值回去 + */ + onUnload() { + Error.prepareStackTrace = this.#originErrorPrepareStackTrace; + } + + /** + * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 + * + * 如果捕获出来的错误存放我们存报错栈堆的列表中,则证明该错误能获取到栈堆,由此来获取报错的地址和行列号 + * + * @param {PromiseRejectionEvent} event + */ + onHandle(event) { + event.promise.catch((error) => { + const result = this.#errorList.find(savedError => savedError[0] === error); + if (result) { + // @ts-ignore + window.onerror( + result[0].message, + result[1][0].getScriptNameOrSourceURL(), + result[1][0].getLineNumber() || void 0, + result[1][0].getColumnNumber() || void 0, + result[0] + ); + } + }); + } + + /** + * 正式报错时便不再需要报错信息了,故直接清空列表,释放内存 + */ + onErrorPrepare() { + this.#errorList.length = 0; + } +} + +/** + * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler + */ diff --git a/noname/util/struct/promise-error-handler/firefox.js b/noname/util/struct/promise-error-handler/firefox.js new file mode 100644 index 000000000..c2d37d77a --- /dev/null +++ b/noname/util/struct/promise-error-handler/firefox.js @@ -0,0 +1,40 @@ +/** + * 关于`Mozilla Firefox`的异步错误处理 + * + * 很幸运,Mozilla直接为`Firefox`的报错提供了地址和行列号,故我们能直接获取到要获取的信息,不用像`v8`那样通过栈堆获取 + * + * 虽然但是,我们还是需要判断一下捕获的报错是否是错误 + * + * @implements {PromiseErrorHandler} + */ +export class FirefoxPromiseErrorHandler { + /** + * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 + * + * 如果捕获到的错误是`Error`,则能直接通过`Firefox`的特性来获取地址和行列号 + * + * @param {PromiseRejectionEvent} event + */ + onHandle(event) { + event.promise.catch((error) => { + if (typeof error === 'object' && error instanceof Error) { + // Firefox在大环境下默认情况必须要那么多ts-ignore + // @ts-ignore + window.onerror( + error.message, + // @ts-ignore + error.fileName, + // @ts-ignore + error.lineNumber, + // @ts-ignore + error.columnNumber, + error + ); + } + }); + } +} + +/** + * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler + */ diff --git a/noname/util/struct/promise-error-handler/index.js b/noname/util/struct/promise-error-handler/index.js new file mode 100644 index 000000000..747d197a7 --- /dev/null +++ b/noname/util/struct/promise-error-handler/index.js @@ -0,0 +1,13 @@ +/** + * 关于不同浏览器下对异步错误的处理方式 + * + * 目前已实现的浏览器如下: + * + * - `Google Chrome`(包括`electron`、`cordova`以及`crosswalk`) + * - `Mozilla Firefox` + * + */ + +export { ChromePromiseErrorHandler } from './chrome.js'; +export { FirefoxPromiseErrorHandler } from './firefox.js'; +export { UnknownPromiseErrorHandler } from './unknown.js'; diff --git a/noname/util/struct/promise-error-handler/unknown.js b/noname/util/struct/promise-error-handler/unknown.js new file mode 100644 index 000000000..04992d8f0 --- /dev/null +++ b/noname/util/struct/promise-error-handler/unknown.js @@ -0,0 +1,31 @@ +/** + * 关于除已实现浏览器外其余浏览器的异步错误处理 + * + * 很遗憾,对于这类浏览器,因为标准未涉及报错栈堆或地址及行列号,故我们只能直接,暴力的throw出我们捕获道德错误, + * + * 尽管我们还是会为了这类浏览器判断是不是捕获到了一个`Error` + * + * 总之,虽然这里跟Safari无关,但我们还是为新时代IE默哀一秒 + * + * @implements {PromiseErrorHandler} + */ +export class UnknownPromiseErrorHandler { + /** + * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 + * + * 如果捕获到的错误是`Error`,则...我们只能暴力的将`Error`再次`throw`出去 + * + * @param {PromiseRejectionEvent} event + */ + onHandle(event) { + event.promise.catch((error) => { + if (typeof error === 'object' && error instanceof Error) { + throw error; + } + }); + } +} + +/** + * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler + */