"use strict"; { 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频道等)均为玩家自发组织,与无名杀官方无关!')){ localStorage.setItem('gplv3_noname_alerted',true); } else{ const ua=navigator.userAgent.toLowerCase(); const ios=ua.includes('iphone')||ua.includes('ipad')||ua.includes('macintosh'); //electron if(typeof window.process=='object'&&typeof window.require=='function'){ const versions=window.process.versions; const electronVersion=parseFloat(versions.electron); let remote; if(electronVersion>=14){ remote=require('@electron/remote'); }else{ remote=require('electron').remote; } const thisWindow=remote.getCurrentWindow(); thisWindow.destroy(); window.process.exit(); } //android-cordova环境 //ios-cordova环境或ios浏览器环境 //非ios的网页版 else if(!ios){ window.close(); } } } const nonameInitialized=localStorage.getItem('noname_inited'); const GeneratorFunction=(function*(){}).constructor; // gnc: GeNCoroutine const gnc={ of:fn=>gnc.is.generatorFunc(fn)?function genCoroutine(){ let gen=fn.apply(this,arguments); gen.status="next"; gen.state=undefined; const callback=(resolve,reject)=>{ let result, nexts=resolve, throws=reject; try{ result=gen[gen.status](gen.state); }catch(error){ reject(error); return; } if(!result.done){ nexts=(item)=>{ gen.state=item; gen.status="next"; callback(resolve,reject); } throws=(err)=>{ gen.state=err; gen.status="throw"; callback(resolve,reject); } } result=result.value; Promise.resolve(result).then(nexts,throws); } return new Promise(callback); }:(()=>{throw new TypeError("gnc.of needs a GeneratorFunction.")})(), is:{ coroutine:item=>typeof item=="function"&&item.name=="genCoroutine", generatorFunc:item=>item instanceof GeneratorFunction, generator:item=>(typeof item=="object")&&("constructor" in item)&&item.constructor&&("constructor" in item.constructor)&&item.constructor.constructor===GeneratorFunction } }; const _status={ paused:false, paused2:false, paused3:false, over:false, clicked:false, auto:false, event:{ finished:true, next:[], after:[] }, ai:{}, lastdragchange:[], skillaudio:[], dieClose:[], dragline:[], dying:[], globalHistory:[{ cardMove:[], custom:[], useCard:[], changeHp:[], everything:[], }], cardtag:{ yingbian_zhuzhan:[], yingbian_kongchao:[], yingbian_fujia:[], yingbian_canqu:[], yingbian_force:[] }, renku:[], prehidden_skills:[], postReconnect:{}, }; const lib={ configprefix:'noname_0.9_', versionOL:27, updateURLS:{ coding:'https://raw.fgit.cf/libccy/noname', github:'https://raw.githubusercontent.com/libccy/noname', }, updateURL:'https://raw.githubusercontent.com/libccy/noname', mirrorURL:'https://raw.fgit.cf/libccy/noname', hallURL:'47.99.105.222', assetURL:typeof nonameInitialized!='string'||nonameInitialized=='nodejs'?'':nonameInitialized, compatibleEdition:Boolean(typeof nonameInitialized=='string'&&nonameInitialized.match(/\/(?:com\.widget|yuri\.nakamura)\.noname\//)), changeLog:[], updates:[], canvasUpdates:[], video:[], skilllist:[], connectBanned:[], characterIntro:{}, characterTitle:{}, characterPack:{}, characterFilter:{}, characterSort:{}, characterReplace:{}, characterGuozhanFilter:["mode_guozhan"], dynamicTranslate:{}, cardPack:{}, skin:{}, onresize:[], onphase:[], onwash:[], onover:[], ondb:[], ondb2:[], chatHistory:[], emotionList:{ xiaowu_emotion:14, xiaokuo_emotion:8, shibing_emotion:15, guojia_emotion:20, zhenji_emotion:20, xiaosha_emotion:20, xiaotao_emotion:20, xiaojiu_emotion:20, }, animate:{ skill:{}, card:{}, }, onload:[], onload2:[], onprepare:[], arenaReady:[], onfree:[], inpile:[], inpile_nature:[], extensions:[], extensionPack:{}, cardType:{}, hook:{globaltrigger:{},globalskill:{}}, //函数钩子 hooks:{ // 本体势力的颜色 addGroup:[(id,_short,_name,config)=>{ if("color" in config&&config.color!=null){ let color1,color2,color3,color4; if (typeof config.color=="string"&&/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(config.color)){ let c1=parseInt(`0x${config.color.slice(1, 3)}`); let c2=parseInt(`0x${config.color.slice(3, 5)}`); let c3=parseInt(`0x${config.color.slice(5, 7)}`); color1=color2=color3=color4=[c1,c2,c3,1]; } else if(Array.isArray(config.color)&&config.color.length==4){ if(config.color.every(item=>Array.isArray(item))){ color1=config.color[0]; color2=config.color[1]; color3=config.color[2]; color4=config.color[3]; } else color1=color2=color3=color4=config.color; } if(color1&&color2&&color3&&color4){ const cs=lib.linq.cselector; const g1=cs.group( cs.of( cs.class("player","identity"), cs.isAttr("data-color",`"${id}"`) ), cs.of( "div", cs.isAttr("data-nature",`"${id}"`) ), cs.of( "span", cs.isAttr("data-nature",`"${id}"`) ) ); const g2=cs.group( cs.of( "div", cs.isAttr("data-nature",`"${id}m"`) ), cs.of( "span", cs.isAttr("data-nature",`"${id}m"`) ) ); const g3=cs.group( cs.of( "div", cs.isAttr("data-nature",`"${id}mm"`) ), cs.of( "span", cs.isAttr("data-nature",`"${id}mm"`) ) ); let result={}; result[g1]={ textShadow:cs.group( "black 0 0 1px", `rgba(${color1.join()}) 0 0 2px`, `rgba(${color2.join()}) 0 0 5px`, `rgba(${color3.join()}) 0 0 10px`, `rgba(${color4.join()}) 0 0 10px` ) }; result[g2]={ textShadow:cs.group( "black 0 0 1px", `rgba(${color1.join()}) 0 0 2px`, `rgba(${color2.join()}) 0 0 5px`, `rgba(${color3.join()}) 0 0 5px`, `rgba(${color4.join()}) 0 0 5px`, "black 0 0 1px" ) }; result[g3]={ textShadow:cs.group( "black 0 0 1px", `rgba(${color1.join()}) 0 0 2px`, `rgba(${color2.join()}) 0 0 2px`, `rgba(${color3.join()}) 0 0 2px`, `rgba(${color4.join()}) 0 0 2px`, "black 0 0 1px" ) }; game.dynamicStyle.addObject(result); lib.groupnature[id]=id; } } if(typeof config.image=='string') Object.defineProperty(lib.card,`group_${id}`,{ configurable:true, enumerable:false, writable:true, value:{ fullskin:true, image:config.image } }); }], //增加新属性杀 addNature:[(nature,_translation,config)=>{ if(typeof config!='object') config={}; let linked=config.linked,order=config.order,background=config.background,lineColor=config.lineColor; if(typeof linked!='boolean') linked=true; if(typeof order!='number') order=0; if(typeof background!='string') background=''; if(!Array.isArray(lineColor)||lineColor.length!=3) lineColor=[]; else if(background.startsWith('ext:')){ background=background.replace(/^ext:/,'extension/'); } if(linked) lib.linked.add(nature); if(lineColor.length) lib.lineColor.set(nature,lineColor); lib.nature.set(nature,order); if(background.length>0) lib.natureBg.set(nature,background); let color1,color2; if (typeof config.color=="string"&&/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(config.color)){ let c1=parseInt(`0x${item[1].slice(1, 3)}`); let c2=parseInt(`0x${item[1].slice(3, 5)}`); let c3=parseInt(`0x${item[1].slice(5, 7)}`); color1=color2=[c1,c2,c3,1]; } else if(Array.isArray(config.color)&&config.color.length>=2&&config.color.length<=4){ if(config.color.every(item=>Array.isArray(item))){ color1=config.color[0]; color2=config.color[1]; } else{ let color=config.color.slice(); if(color.length==3) color.push(1); color1=color2=color; } } if(color1&&color2){ const cs=lib.linq.cselector; const g1=cs.group( cs.of( cs.class("card","fullskin",`${nature}`), '>', cs.class("name") ) ); let result={}; result[g1]={ color:`rgba(${color1.join()})`, border:cs.merge( '1px', 'solid', `rgba(${color2.join()})` ), }; game.dynamicStyle.addObject(result); const g2=cs.group( cs.of( cs.class("tempname",`${nature}`), ':not([data-nature])>', cs.class("span") ) ) let result2={}; result2[g2]={ color:`rgba(${color1.join()})`, }; game.dynamicStyle.addObject(result2); } }], }, announce:{ init(){ _status._announce=document.createElement("Announce"); _status._announce_cache=new Map(); delete lib.announce.init; }, //推送一个对象给所有监听了name的订阅者。 publish(name,values){ if(_status._announce) _status._announce.dispatchEvent(new CustomEvent(name,{ detail:values })); return values; }, //订阅name相关的事件。 subscribe(name,method){ if(_status._announce&&_status._announce_cache) { let subscribeFunction; if(_status._announce_cache.has(method)){ let records=_status._announce_cache.get(method); subscribeFunction=records.get("Listener"); records.get("EventTargets").add(name); } else{ subscribeFunction=event=>method(event.detail); let records=new Map(); records.set("Listener",subscribeFunction); records.set("EventTargets",[name]); _status._announce_cache.set(method,records); } _status._announce.addEventListener(name,subscribeFunction); } return method; }, //取消对事件name的订阅 unsubscribe(name,method){ if(_status._announce&&_status._announce_cache&&_status._announce_cache.has(method)){ let records=_status._announce_cache.get(method); const listener=records.get("Listener"); let eventTargets=records.get("EventTargets"); eventTargets.remove(name); if(eventTargets.length<=0) _status._announce_cache.remove(method); _status._announce.removeEventListener(name,listener); } return method; } }, objectURL:new Map(), hookmap:{}, imported:{}, layoutfixed:['chess','tafang','stone'], pinyins:{ _metadata:{ shengmu:['zh','ch','sh','b','p','m','f','d','t','l','n','g','k','h','j','q','x','r','z','c','s','y','w'], special_shengmu:['j','q','x','y'], feijiemu:{ i:['ing','iu','ie','in'], u:['ui','un'], ü:['üe','ün'], }, zhengtirendu:['zhi','chi','shi','ri','zi','ci','si'], yunjiao:{ '一麻':['a','ia','ua'], '二波':['o','e','uo'], '三皆':['ie','üe'], '四开':['ai','uai'], '五微':['ei','ui'], '六豪':['ao','iao'], '七尤':['ou','iu'], '八寒':['an','ian','uan','üan'], '九文':['en','in','un','ün'], '十唐':['ang','iang','uang'], '十一庚':['eng','ing','ong','ung'], '十二齐':['i','er','ü'], '十三支':['-i'], '十四姑':['u'], }, } }, //Yingbian //应变 yingbian:{ condition:{ color:new Map([ ['zhuzhan','wood'], ['kongchao','soil'], ['fujia','orange'], ['canqu','fire'], ['force','metal'] ]), complex:new Map([ ['zhuzhan',function(event){ const yingbianZhuzhan=game.createEvent('yingbianZhuzhan'); yingbianZhuzhan.player=event.player; yingbianZhuzhan.card=event.card; yingbianZhuzhan._trigger=event; yingbianZhuzhan.yingbianZhuzhanAI=event.yingbianZhuzhanAI; yingbianZhuzhan.afterYingbianZhuzhan=event.afterYingbianZhuzhan; yingbianZhuzhan.setContent(()=>{ 'step 0' event._global_waiting=true; event.send=(player,card,source,targets,id,id2,yingbianZhuzhanAI,skillState)=>{ if(skillState) player.applySkills(skillState); var type=get.type2(card),str=get.translation(source); if(targets&&targets.length) str+=`对${get.translation(targets)}`; str+=`使用了${get.translation(card)},是否弃置一张${get.translation(type)}为其助战?`; player.chooseCard({ filterCard:(card,player)=>get.type2(card)==type&&lib.filter.cardDiscardable(card,player), prompt:str, position:'h', _global_waiting:true, id:id, id2:id2, ai:typeof yingbianZhuzhanAI=='function'?yingbianZhuzhanAI(player,card,source,targets):cardx=>{ var info=get.info(card); if(info&&info.ai&&info.ai.yingbian){ var ai=info.ai.yingbian(card,source,targets,player); if(!ai) return 0; return ai-get.value(cardx); } else if(get.attitude(player,source)<=0) return 0; return 5-get.value(cardx); } }); if(!game.online) return; _status.event._resultid=id; game.resume(); }; 'step 1' var type=get.type2(card); event.list=game.filterPlayer(current=>current!=player&¤t.countCards('h')&&(_status.connectMode||current.hasCard(cardx=>get.type2(cardx)==type,'h'))).sortBySeat(_status.currentPhase||player); event.id=get.id(); 'step 2' if(!event.list.length) event.finish(); else if(_status.connectMode&&(event.list[0].isOnline()||event.list[0]==game.me)) event.goto(4); else event.send(event.current=event.list.shift(),event.card,player,trigger.targets,event.id,trigger.parent.id,trigger.yingbianZhuzhanAI); 'step 3' if(result.bool){ event.zhuzhanresult=event.current; event.zhuzhanresult2=result; if(event.current!=game.me) game.delayx(); event.goto(8); } else event.goto(2); 'step 4' var id=event.id,sendback=(result,player)=>{ if(result&&result.id==id&&!event.zhuzhanresult&&result.bool){ event.zhuzhanresult=player; event.zhuzhanresult2=result; game.broadcast('cancel',id); if(_status.event.id==id&&_status.event.name=='chooseCard'&&_status.paused) return ()=>{ event.resultOL=_status.event.resultOL; ui.click.cancel(); if(ui.confirm) ui.confirm.close(); }; } else if(_status.event.id==id&&_status.event.name=='chooseCard'&&_status.paused) return ()=>event.resultOL=_status.event.resultOL; },withme=false,withol=false,list=event.list; for(var i=0;i<list.length;i++){ var current=list[i]; if(current.isOnline()){ withol=true; current.wait(sendback); current.send(event.send,current,event.card,player,trigger.targets,event.id,trigger.parent.id,trigger.yingbianZhuzhanAI,get.skillState(current)); list.splice(i--,1); } else if(current==game.me){ withme=true; event.send(current,event.card,player,trigger.targets,event.id,trigger.parent.id,trigger.yingbianZhuzhanAI); list.splice(i--,1); } } if(!withme) event.goto(6); if(_status.connectMode&&(withme||withol)) game.players.forEach(value=>{ if(value!=player) value.showTimer(); }); event.withol=withol; 'step 5' if(!result||!result.bool||event.zhuzhanresult) return; game.broadcast('cancel',event.id); event.zhuzhanresult=game.me; event.zhuzhanresult2=result; 'step 6' if(event.withol&&!event.resultOL) game.pause(); 'step 7' game.players.forEach(value=>value.hideTimer()); 'step 8' if(event.zhuzhanresult){ var target=event.zhuzhanresult; target.line(player,'green'); target.discard(event.zhuzhanresult2.cards).discarder=target; if(typeof event.afterYingbianZhuzhan=='function') event.afterYingbianZhuzhan(event,trigger); var yingbianCondition=event.name.slice(8).toLowerCase(),yingbianConditionTag=`yingbian_${yingbianCondition}_tag`; target.popup(yingbianConditionTag,lib.yingbian.condition.color.get(yingbianCondition)); game.log(target,'响应了',player,'发起的',yingbianConditionTag); target.addExpose(0.2); event.result={ bool:true } } else event.result={ bool:false }; }); yingbianZhuzhan._args=Array.from(arguments); return yingbianZhuzhan; }] ]), simple:new Map([ ['kongchao',event=>!event.player.countCards('h')], ['fujia',event=>event.player.isMaxHandcard()], ['canqu',event=>event.player.getHp()==1] ]) }, effect:new Map([ ['add',()=>{ trigger.yingbian_addTarget=true; }], ['remove',()=>{ trigger.yingbian_removeTarget=true; }], ['damage',()=>{ if(typeof trigger.baseDamage!='number') trigger.baseDamage=1; trigger.baseDamage++; game.log(card,'的伤害值基数+1'); }], ['draw',()=>{ player.draw(); }], ['gain',()=>{ const cardx=trigger.respondTo; if(cardx&&cardx[1]&&cardx[1].cards&&cardx[1].cards.filterInD('od').length) player.gain(cardx[1].cards.filterInD('od'),'gain2'); }], ['hit',()=>{ trigger.directHit.addArray(game.players).addArray(game.dead); game.log(card,'不可被响应'); }], ['all',()=>{ card.yingbian_all=true; game.log(card,'执行所有选项'); }] ]), prompt:new Map([ ['add','目标+1'], ['remove','目标-1'], ['damage','伤害+1'], ['draw','摸一张牌'], ['gain','获得响应的牌'], ['hit','此牌不可被响应'], ['all','无视条件执行所有选项'] ]) }, //The actual card name //实际的卡牌名称 actualCardName:new Map([ ['挟令','挟天子以令诸侯'], ['霹雳投石车','霹雳车'] ]), characterDialogGroup:{ '收藏':function(name,capt){ return lib.config.favouriteCharacter.includes(name)?capt:null; }, '最近':function(name,capt){ var list=get.config('recentCharacter')||[]; return list.includes(name)?capt:null; } }, listenEnd:function(node){ if(!node._listeningEnd){ node._listeningEnd=true; node.listenTransition(function(){ delete node._listeningEnd; if(node._onEndMoveDelete){ node.moveDelete(node._onEndMoveDelete); } else if(node._onEndDelete){ node.delete(); } node._transitionEnded=true; }); } }, configMenu:{ general:{ name:'通用', config:{ low_performance:{ name:'流畅模式', init:false, intro:'减少部分游戏特效,提高游戏速度', onclick:function(bool){ game.saveConfig('low_performance',bool); if(bool){ ui.window.classList.add('low_performance'); } else{ ui.window.classList.remove('low_performance'); } } }, compatiblemode:{ name:'兼容模式', init:false, intro:'开启兼容模式可防止扩展使游戏卡死并提高对旧扩展的兼容性,但对游戏速度有一定影响,若无不稳定或不兼容的扩展建议关闭', onclick:function(bool){ game.saveConfig('compatiblemode',bool); if(bool){ ui.window.classList.add('compatiblemode'); } else{ ui.window.classList.remove('compatiblemode'); } } }, confirm_exit:{ name:'确认退出', init:false, unfrequent:true, intro:'离开游戏前弹出确认对话框', }, keep_awake:{ name:'屏幕常亮', init:false, unfrequent:true, intro:'防止屏幕自动关闭<br>注:旧版本通过NoSleep.js实现的屏幕常亮可能会影响外置音频的音量', onclick:function(bool){ game.saveConfig('keep_awake',bool); if(bool){ if(window.plugins&&window.plugins.insomnia) window.plugins.insomnia.keepAwake(); else if(window.noSleep){ document.addEventListener(lib.config.touchscreen?'touchend':'click', function enableNoSleepX() { document.removeEventListener(lib.config.touchscreen?'touchend':'click', enableNoSleepX, false); window.noSleep.enable(); }, false); } } else{ if(window.plugins&&window.plugins.insomnia) window.plugins.insomnia.allowSleepAgain(); else if(window.noSleep) window.noSleep.disable(); } } }, auto_confirm:{ name:'自动确认', init:true, unfrequent:true, intro:'当候选目标只有1个时,点击目标后无需再点击确认', }, skip_shan:{ name:'无闪自动取消', init:false, unfrequent:true, intro:'当自己需要使用或打出【闪】时,若自己没有【闪】,则跳过该步骤', }, unauto_choose:{ name:'拆顺手牌选择', init:false, unfrequent:true, intro:'拆牌或者顺牌时,就算只能选择对方的手牌依然手动选择', }, wuxie_self:{ name:'不无懈自己', init:true, unfrequent:true, intro:'自己使用的单目标普通锦囊即将生效时,不询问无懈', }, tao_enemy:{ name:'不对敌方出桃', init:false, intro:'双方阵营明确的模式中(如对决),敌方角色濒死时不询问出桃', unfrequent:true, }, enable_drag:{ name:'启用拖拽', init:true, intro:'按住卡牌后可将卡牌拖至目标', unfrequent:true, }, enable_dragline:{ name:'拖拽指示线', init:true, unfrequent:true, intro:'拖拽时显示虚线,可能降低游戏速度', }, enable_touchdragline:{ name:'拖拽指示线', init:false, unfrequent:true, intro:'拖拽时显示虚线,可能降低游戏速度', }, // enable_pressure:{ // name:'启用压感', // init:false, // intro:'开启后可通过按压执行操作', // unfrequent:true, // }, // pressure_taptic:{ // name:'触觉反馈', // init:false, // intro:'开启后按压操作执行时将产生震动', // unfrequent:true, // }, // pressure_click:{ // name:'按压操作', // init:'pause', // intro:'在空白区域按压时的操作', // unfrequent:true, // item:{ // pause:'暂停', // config:'选项', // auto:'托管', // } // }, touchscreen:{ name:'触屏模式', init:false, restart:true, unfrequent:true, intro:'开启后可使触屏设备反应更快,但无法使用鼠标操作', onclick:function(bool){ if(get.is.nomenu('touchscreen',bool)) return false; game.saveConfig('touchscreen',bool); } }, swipe:{ name:'滑动手势', init:true, unfrequent:true, intro:'在非滚动区域向四个方向滑动可执行对应操作', }, swipe_down:{ name:'下划操作', init:'menu', unfrequent:true, intro:'向下滑动时执行的操作', item:{ system:'显示按钮', menu:'打开菜单', pause:'切换暂停', auto:'切换托管', chat:'显示聊天', off:'关闭', }, onclick:function(item){ if(get.is.nomenu('swipe_down',item)) return false; game.saveConfig('swipe_down',item); } }, swipe_up:{ name:'上划操作', intro:'向上滑动时执行的操作', init:'auto', unfrequent:true, item:{ system:'显示按钮', menu:'打开菜单', pause:'切换暂停', auto:'切换托管', chat:'显示聊天', off:'关闭', }, onclick:function(item){ if(get.is.nomenu('swipe_up',item)) return false; game.saveConfig('swipe_up',item); } }, swipe_left:{ name:'左划操作', intro:'向左滑动时执行的操作', init:'system', unfrequent:true, item:{ system:'显示按钮', menu:'打开菜单', pause:'切换暂停', auto:'切换托管', chat:'显示聊天', off:'关闭', }, onclick:function(item){ if(get.is.nomenu('swipe_left',item)) return false; game.saveConfig('swipe_left',item); } }, swipe_right:{ name:'右划操作', intro:'向右滑动时执行的操作', init:'system', unfrequent:true, item:{ system:'显示按钮', menu:'打开菜单', pause:'切换暂停', auto:'切换托管', chat:'显示聊天', off:'关闭', }, onclick:function(item){ if(get.is.nomenu('swipe_right',item)) return false; game.saveConfig('swipe_right',item); } }, round_menu_func:{ name:'触屏按钮操作', intro:'点击屏幕中圆形按钮时执行的操作', init:'system', unfrequent:true, item:{ system:'显示按钮', menu:'打开菜单', pause:'切换暂停', auto:'切换托管' }, onclick:function(item){ if(get.is.nomenu('round_menu_func',item)) return false; game.saveConfig('round_menu_func',item); }, }, show_splash:{ name:'显示开始界面', intro:'游戏开始前进入模式选择画面', init:'init', item:{ off:'关闭', init:'首次启动', always:'保持开启', } }, game_speed:{ name:'游戏速度', init:'mid', item:{ vslow:'慢', slow:'较慢', mid:'中', fast:'较快', vfast:'快', vvfast:'很快', }, intro:'设置不同游戏操作间的时间间隔' }, sync_speed:{ name:'限制结算速度', intro:'在动画结算完成前不执行下一步操作,开启后游戏操作的间隔更长但画面更浏畅,在游戏较卡时建议开启', init:true }, enable_vibrate:{ name:'开启震动', intro:'回合开始时使手机震动', init:false }, right_click:{ name:'右键操作', init:'pause', intro:'在空白区域点击右键时的操作', unfrequent:true, item:{ pause:'暂停', shortcut:'工具', config:'选项', auto:'托管', }, onclick:function(item){ if(get.is.nomenu('right_click',item)) return false; game.saveConfig('right_click',item); } }, longpress_info:{ name:'长按显示信息', init:true, unfrequent:true, restart:true, intro:'长按后弹出菜单', }, right_info:{ name:'右键显示信息', init:true, unfrequent:true, restart:true, intro:'右键点击后弹出菜单', }, hover_all:{ name:'悬停显示信息', init:true, unfrequent:true, restart:true, intro:'悬停后弹出菜单', }, hover_handcard:{ name:'悬停手牌显示信息', init:true, unfrequent:true, intro:'悬停手牌后弹出菜单', }, hoveration:{ name:'悬停菜单弹出时间', unfrequent:true, intro:'鼠标移至目标到弹出菜单的时间间隔', init:'1000', item:{ '500':'0.5秒', '700':'0.7秒', '1000':'1秒', '1500':'1.5秒', '2500':'2.5秒', } }, doubleclick_intro:{ name:'双击显示武将资料', init:true, unfrequent:true, intro:'双击武将头像后显示其资料卡', }, video:{ name:'保存录像', init:'20', intro:'游戏结束后保存录像在最大条数,超过后将从最早的录像开始删除(已收藏的录像不计入条数)', item:{ '0':'关闭', '5':'五局', '10':'十局', '20':'二十局', '50':'五十局', '10000':'无限', }, unfrequent:true, }, max_loadtime:{ name:'最长载入时间', intro:'设置游戏从启动到完成载入所需的最长时间,超过此时间未完成载入会报错,若设备较慢或安装了较多扩展可适当延长此时间', init:'5000', unfrequent:true, item:{ 5000:'5秒', 10000:'10秒', 20000:'20秒', 60000:'60秒' }, onclick:function(item){ game.saveConfig('max_loadtime',item); if(item=='5000'){ localStorage.removeItem(lib.configprefix+'loadtime'); } else{ localStorage.setItem(lib.configprefix+'loadtime',item); } } }, mousewheel:{ name:'滚轮控制手牌', init:true, unfrequent:true, intro:'开启后滚轮可使手牌横向滚动,在mac等可横向滚动的设备上建议关闭', onclick:function(bool){ game.saveConfig('mousewheel',bool); if(lib.config.touchscreen) return; if(lib.config.mousewheel){ ui.handcards1Container.onmousewheel=ui.click.mousewheel; ui.handcards2Container.onmousewheel=ui.click.mousewheel; } else{ ui.handcards1Container.onmousewheel=null; ui.handcards2Container.onmousewheel=null; } } }, auto_check_update:{ name:'自动检查游戏更新', intro:'进入游戏时检查更新', init:false, unfrequent:true }, lucky_star:{ name:'幸运星模式', intro:'在涉及随机数等的技能中,必定得到效果最好的结果。(联机模式无效)', init:false, unfrequent:true }, dev:{ name:'开发者模式', intro:'开启后可使用浏览器控制台控制游戏,同时可更新到开发版', init:false, onclick:function(bool){ game.saveConfig('dev',bool); if(_status.connectMode) return; if(bool){ lib.cheat.i(); } else{ delete window.cheat; delete window.game; delete window.ui; delete window.get; delete window.ai; delete window.lib; delete window._status; } }, unfrequent:true, }, fuck_sojson:{ name:'检测加密扩展', init:false, }, errstop:{ name:'出错时停止游戏', init:false, unfrequent:true }, update_link:{ name:'更新地址', init:'coding', unfrequent:true, item:{ coding:'FastGit', github:'GitHub', }, onclick:function(item){ game.saveConfig('update_link',item); lib.updateURL=lib.updateURLS[item]||lib.updateURLS.coding; }, }, extension_source:{ name:'获取扩展地址', init:'GitHub Proxy', unfrequent:true, item:{}, intro:()=>`获取在线扩展时的地址。当前地址:${document.createElement('br').outerHTML}${lib.config.extension_sources[lib.config.extension_source]}` }, extension_create:{ name:'添加获取扩展地址', clear:true, unfrequent:true, onclick:function(){ game.prompt('请输入地址名称',function(str){ if(str){ var map=lib.config.extension_sources; game.prompt('请输入'+str+'的地址',function(str2){ if(str2){ delete map[str]; map[str]=str2; game.saveConfig('extension_sources',map); game.saveConfig('extension_source',str); var nodexx=ui.extension_source; nodexx.updateInner(); var nodeyy=nodexx._link.menu; var nodezz=nodexx._link.config; for(var i=0;i<nodeyy.childElementCount;i++){ if(nodeyy.childNodes[i]._link==str){ nodeyy.childNodes[i].remove(); break; } } var textMenu=ui.create.div('',str,nodeyy,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(); } }); textMenu._link=str; nodezz.item[name]=str; alert('已添加扩展地址:'+str); } }) } }); }, }, extension_delete:{ name:'删除当前扩展地址', clear:true, unfrequent:true, onclick:function(){ var bool=false,map=lib.config.extension_sources; for(var i in map){ if(i!=lib.config.extension_source){ bool=true; break; } } if(!bool){ alert('不能删除最后一个扩展地址!'); return; } var name=lib.config.extension_source; game.saveConfig('extension_source',i); delete map[name]; game.saveConfig('extension_sources',map); var nodexx=ui.extension_source; nodexx.updateInner(); var nodeyy=nodexx._link.menu; var nodezz=nodexx._link.config; for(var i=0;i<nodeyy.childElementCount;i++){ if(nodeyy.childNodes[i]._link==name){ nodeyy.childNodes[i].remove(); break; } } delete nodezz.item[name]; alert('已删除扩展地址:'+name); }, }, update:function(config,map){ if('ontouchstart' in document){ map.touchscreen.show(); } else{ map.touchscreen.hide(); } if(lib.device||lib.node){ map.auto_check_update.show(); } else{ map.auto_check_update.hide(); } if(lib.device){ map.enable_vibrate.show(); map.keep_awake.show(); } else{ map.enable_vibrate.hide(); map.keep_awake.hide(); } // if(config.enable_pressure){ // map.pressure_click.show(); // if(lib.device){ // map.pressure_taptic.show(); // } // else{ // map.pressure_taptic.hide(); // } // } // else{ // map.pressure_click.hide(); // map.pressure_taptic.hide(); // } if(lib.config.touchscreen){ map.mousewheel.hide(); map.hover_all.hide(); map.hover_handcard.hide(); map.hoveration.hide(); map.right_info.hide(); map.right_click.hide(); map.longpress_info.show(); map.swipe.show(); if(lib.config.swipe){ map.swipe_up.show(); map.swipe_down.show(); map.swipe_left.show(); map.swipe_right.show(); } else{ map.swipe_up.hide(); map.swipe_down.hide(); map.swipe_left.hide(); map.swipe_right.hide(); } } else{ map.mousewheel.show(); map.hover_all.show(); map.right_info.show(); map.right_click.show(); map.longpress_info.hide(); if(!config.hover_all){ map.hover_handcard.hide(); map.hoveration.hide(); } else{ map.hover_handcard.show(); map.hoveration.show(); } map.swipe.hide(); map.swipe_up.hide(); map.swipe_down.hide(); map.swipe_left.hide(); map.swipe_right.hide(); } if(lib.config.enable_drag){ if(lib.config.touchscreen){ map.enable_dragline.hide(); map.enable_touchdragline.show(); } else{ map.enable_dragline.show(); map.enable_touchdragline.hide(); } } else{ map.enable_dragline.hide(); map.enable_touchdragline.hide(); } if(!get.is.phoneLayout()){ map.round_menu_func.hide(); } else{ map.round_menu_func.show(); } if(!lib.node&&lib.device!='ios'){ map.confirm_exit.show(); } else{ map.confirm_exit.hide(); } if(config.dev){ map.errstop.show(); } else{ map.errstop.hide(); } } } }, appearence:{ name:'外观', config:{ theme:{ name:'主题', init:'woodden', item:{}, visualMenu:function(node,link){ if(!node.menu){ node.className='button character themebutton '+link; node.menu=ui.create.div(node,'','<div></div><div></div><div></div><div></div>'); } }, onclick:function(theme){ game.saveConfig('theme',theme); ui.arena.hide(); lib.init.background(); if(lib.config.autostyle){ if(theme=='simple'){ lib.configMenu.appearence.config.player_border.onclick('slim'); } else{ lib.configMenu.appearence.config.player_border.onclick('normal'); } } setTimeout(function(){ var theme=ui.css.theme; ui.css.theme=lib.init.css(lib.assetURL+'theme/'+lib.config.theme,'style'); theme.remove(); setTimeout(function(){ui.arena.show();},100); },500); } }, layout:{ name:'布局', init:'mobile', item:{ //default:'旧版', newlayout:'对称', mobile:'默认', long:'宽屏', long2:'手杀', nova:'新版' }, visualMenu:function(node,link){ node.className='button character themebutton '+lib.config.theme; if(!node.created){ node.created=true; node.style.overflow='hidden'; node.firstChild.style.display='none'; // node.firstChild.classList.add('shadowed'); // node.firstChild.style.width='16px'; // node.firstChild.style.height='auto'; // node.firstChild.style.padding='2px'; // node.firstChild.style.textAlign='center'; var me=ui.create.div(node); me.style.top='auto'; if(link=='default'||link=='newlayout'){ me.style.width='calc(100% - 6px)'; me.style.left='3px'; me.style.bottom='3px'; me.style.height='25px'; if(link=='newlayout'){ me.style.height='23px'; me.style.bottom='4px'; } } else if(link=='long2'||link=='nova'){ me.style.display='none'; } else{ me.style.width='120%'; me.style.left='-10%'; me.style.bottom='0'; me.style.height='22px'; } me.style.borderRadius='2px'; var list=['re_caocao','re_liubei','sp_zhangjiao','sunquan']; for(var i=0;i<4;i++){ var player=ui.create.div('.fakeplayer',node); ui.create.div('.avatar',player).setBackground(list.randomRemove(),'character'); player.style.borderRadius='2px'; if(i!=3){ player.style.top='auto'; } if(link=='default'){ player.style.height='19px'; player.style.width='38px'; player.classList.add('oldlayout') } else if(link=='mobile'||link=='newlayout'){ player.style.width='24px'; player.style.height='29px'; } else if(link=='nova') { player.style.width='20px'; player.style.height='24px'; } else{ player.style.width='20px'; player.style.height='34px'; } if(i==1){ player.style.left='3px'; } if(i==2){ player.style.left='auto'; player.style.right='3px'; } if(i==3){ player.style.top='3px'; } if(link=='default'){ if(i==0){ player.style.bottom='6px'; } if(i==0||i==3){ player.style.left='calc(50% - 18px)'; } if(i==1||i==2){ player.style.bottom='36px'; } } else if(link=='newlayout'){ if(i==0){ player.style.bottom='1px'; } if(i==0||i==3){ player.style.left='calc(50% - 12px)'; } if(i==1||i==2){ player.style.bottom='32px'; } } else if(link=='mobile'){ if(i==0||i==3){ player.style.left='calc(50% - 12px)'; } if(i==1||i==2){ player.style.bottom='30px'; } } else if(link=='long'){ if(i==0||i==3){ player.style.left='calc(50% - 10px)'; } if(i==1||i==2){ player.style.bottom='45px'; } } else if(link=='long2'){ if(i==0){ player.style.bottom='2px'; player.style.left='3px'; } if(i==3){ player.style.left='calc(50% - 10px)'; } if(i==1||i==2){ player.style.bottom='45px'; } } else if(link=='nova'){ if(i==0){ player.style.bottom='2px'; player.style.left='3px'; } if(i==3){ player.style.left='calc(50% - 10px)'; } if(i==1||i==2){ player.style.left='3px'; player.style.bottom=(i*30)+'px'; } } if(i==0&&(link=='mobile'||link=='long')){ player.classList.add('me'); player.style.borderRadius='0px'; player.style.width='25px'; player.style.height='25px'; player.style.bottom='-3px'; player.style.left='-3px'; } } } }, onclick:function(layout){ if(lib.layoutfixed.contains(lib.config.mode)){ game.saveConfig('layout',layout); } else{ lib.init.layout(layout); } } }, splash_style:{ name:'启动页', item:{ style1:'样式一', style2:'样式二', }, visualMenu:(node,link)=>{ node.className='button character'; node.style.width='200px'; node.style.height=`${node.offsetWidth*1080/2400}px`; node.style.display='flex'; node.style.flexDirection='column'; node.style.alignItems='center'; node.style.backgroundSize='100% 100%'; node.setBackgroundImage(`image/splash/${link}.jpg`); } }, // fewplayer:{ // name:'启用人数', // intro:'设置启用新版布局的最小人数(不足时切换至默认布局)', // init:'3', // // unfrequent:true, // item:{ // '2':'两人', // '3':'三人', // '4':'四人', // '5':'五人', // '6':'六人', // '7':'七人', // '8':'八人', // }, // onclick:function(item){ // game.saveConfig('fewplayer',item); // if(ui.arena) ui.arena.setNumber(ui.arena.dataset.number); // } // }, player_height:{ name:'角色高度', init:'long', // unfrequent:true, item:{ short:'矮', default:'中', long:'高', }, onclick:function(item){ game.saveConfig('player_height',item); ui.arena.dataset.player_height=item; } }, player_height_nova:{ name:'角色高度', init:'short', item:{ // auto:'自动', short:'矮', default:'中', long:'高', }, onclick:function(item){ game.saveConfig('player_height_nova',item); // if(item=='auto'){ // if(parseInt(ui.arena.dataset.number)>=7){ // ui.arena.dataset.player_height_nova='short'; // } // else{ // ui.arena.dataset.player_height_nova='default'; // } // } // else{ ui.arena.dataset.player_height_nova=item; // } } }, // background_color_music:{ // name:'背景色', // init:'black', // item:{ // blue:'蓝色', // black:'黑色', // }, // onclick:function(color){ // game.saveConfig('background_color_music',color); // document.body.dataset.background_color_music=color; // } // }, // background_color_wood:{ // name:'背景色', // init:'blue', // item:{ // blue:'蓝色', // black:'黑色', // }, // onclick:function(color){ // game.saveConfig('background_color_wood',color); // document.body.dataset.background_color_wood=color; // } // }, // theme_color_music:{ // name:'主题色', // init:'black', // item:{ // blue:'蓝色', // black:'黑色', // }, // onclick:function(color){ // game.saveConfig('theme_color_music',color); // document.body.dataset.theme_color_music=color; // } // }, ui_zoom:{ name:'界面缩放', unfrequent:true, init:'normal', item:{ esmall:'80%', vsmall:'90%', small:'95%', normal:'100%', big:'105%', vbig:'110%', ebig:'120%', eebig:'150%', eeebig:'180%', eeeebig:'200%', }, onclick:function(zoom){ game.saveConfig('ui_zoom',zoom); switch(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; ui.updatez(); if (Array.isArray(lib.onresize)) { lib.onresize.forEach(fun => { if (typeof fun == 'function') fun(); }); } } }, image_background:{ name:'游戏背景', init:'default', item:{}, visualBar:function(node,item,create){ if(node.created){ node.lastChild.classList.remove('active'); return; } node.created=true; ui.create.filediv('.menubutton','添加背景',node,function(file){ if(file){ var name=file.name; if(name.includes('.')){ name=name.slice(0,name.indexOf('.')); } var link=(game.writeFile?'cdv_':'custom_')+name; if(item[link]){ for(var i=1;i<1000;i++){ if(!item[link+'_'+i]){ link=link+'_'+i;break; } } } item[link]=name; var callback=function(){ create(link,node.parentNode.defaultNode); node.parentNode.updateBr(); lib.config.customBackgroundPack.add(link); game.saveConfig('customBackgroundPack',lib.config.customBackgroundPack); }; if(game.writeFile){ game.writeFile(file,'image/background',link+'.jpg',callback); } else{ game.putDB('image',link,file,callback); } if(node.lastChild.classList.contains('active')){ editbg.call(node.lastChild); } } }).inputNode.accept='image/*'; var editbg=function(){ this.classList.toggle('active'); var page=this.parentNode.parentNode; for(var i=0;i<page.childElementCount;i++){ if(page.childNodes[i].classList.contains('button')){ var link=page.childNodes[i]._link; if(link&&link!='default'){ var str; if(this.classList.contains('active')){ if(link.startsWith('custom_')||link.startsWith('cdv_')){ str='删除'; } else{ str='隐藏'; } } else{ str=item[link]; } page.childNodes[i].firstChild.innerHTML=get.verticalStr(str); } } } }; ui.create.div('.menubutton','编辑背景',node,editbg); }, visualMenu:function(node,link,name,config){ node.className='button character'; node.style.backgroundImage=''; node.style.backgroundSize=''; if(node.firstChild){ node.firstChild.innerHTML=get.verticalStr(name); } if(link=='default'||link.startsWith('custom_')){ node.style.backgroundImage='none'; node.classList.add('dashedmenubutton'); if(link.startsWith('custom_')){ game.getDB('image',link,function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; node.style.backgroundImage='url('+data+')'; node.style.backgroundSize='cover'; node.classList.remove('dashedmenubutton'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } else{ node.parentNode.defaultNode=node; } } else{ node.setBackgroundImage('image/background/'+link+'.jpg'); node.style.backgroundSize='cover'; } }, onclick:function(background,node){ if(node&&node.firstChild){ var menu=node.parentNode; if(node.firstChild.innerHTML==get.verticalStr('隐藏')){ menu.parentNode.noclose=true; node.remove(); menu.updateBr(); if(!lib.config.prompt_hidebg){ alert('隐藏的背景可通过选项-其它-重置隐藏内容恢复'); game.saveConfig('prompt_hidebg',true); } lib.config.hiddenBackgroundPack.add(background); game.saveConfig('hiddenBackgroundPack',lib.config.hiddenBackgroundPack); delete lib.configMenu.appearence.config.image_background.item[background]; if(lib.config.image_background==background){ background='default'; this.lastChild.innerHTML='默认'; } else{ this.lastChild.innerHTML=lib.configMenu.appearence.config.image_background.item[lib.config.image_background]; return; } } else if(node.firstChild.innerHTML==get.verticalStr('删除')){ menu.parentNode.noclose=true; if(confirm('是否删除此背景?(此操作不可撤销)')){ node.remove(); menu.updateBr(); lib.config.customBackgroundPack.remove(background); game.saveConfig('customBackgroundPack',lib.config.customBackgroundPack); if(background.startsWith('cdv_')){ game.removeFile('image/background/'+background+'.jpg'); } else{ game.deleteDB('image',background); } delete lib.configMenu.appearence.config.image_background.item[background]; if(lib.config.image_background==background){ background='default'; this.lastChild.innerHTML='默认'; } else{ this.lastChild.innerHTML=lib.configMenu.appearence.config.image_background.item[lib.config.image_background]; return; } } } } game.saveConfig('image_background',background); lib.init.background(); game.updateBackground(); }, }, image_background_random:{ name:'随机背景', init:false, onclick:function(bool){ game.saveConfig('image_background_random',bool); lib.init.background(); } }, image_background_blur:{ name:'背景模糊', init:false, onclick:function(bool){ game.saveConfig('image_background_blur',bool); if(lib.config.image_background_blur){ ui.background.style.filter='blur(8px)'; ui.background.style.webkitFilter='blur(8px)'; ui.background.style.transform='scale(1.05)'; } else{ ui.background.style.filter=''; ui.background.style.webkitFilter=''; ui.background.style.transform=''; } }, }, phonelayout:{ name:'触屏布局', init:false, onclick:function(bool){ if(get.is.nomenu('phonelayout',bool)) return false; game.saveConfig('phonelayout',bool); if(get.is.phoneLayout()){ ui.css.phone.href=lib.assetURL+'layout/default/phone.css'; ui.arena.classList.add('phone'); } else{ ui.css.phone.href=''; ui.arena.classList.remove('phone'); } } }, change_skin:{ name:'开启换肤', init:true, intro:'在武将的右键菜单中换肤,皮肤可在选项-文件-图片文件-皮肤图片中添加' }, change_skin_auto:{ name:'自动换肤', init:'off', item:{ 'off':'关闭', '30000':'半分钟', '60000':'一分钟', '120000':'两分钟', '300000':'五分钟', }, intro:'游戏每进行一段时间自动为一个随机角色更换皮肤', onclick:function(item){ game.saveConfig('change_skin_auto',item); clearTimeout(_status.skintimeout); if(item!='off'){ _status.skintimeout=setTimeout(ui.click.autoskin,parseInt(item)); } } }, card_style:{ name:'卡牌样式', init:'default', intro:'设置正面朝上的卡牌的样式', item:{ wood:'木纹', music:'音乐', simple:'原版', ol:'手杀', // new:'新版', custom:'自定', default:'默认', }, visualBar:function(node,item,create,switcher){ if(node.created){ return; } var button; for(var i=0;i<node.parentNode.childElementCount;i++){ if(node.parentNode.childNodes[i]._link=='custom'){ button=node.parentNode.childNodes[i]; } } if(!button){ return; } node.created=true; var deletepic; ui.create.filediv('.menubutton','添加图片',node,function(file){ if(file){ game.putDB('image','card_style',file,function(){ game.getDB('image','card_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; button.style.backgroundImage='url('+data+')'; button.className='button card fullskin'; node.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } }).inputNode.accept='image*'; deletepic=ui.create.div('.menubutton.deletebutton','删除图片',node,function(){ if(confirm('确定删除自定义图片?(此操作不可撤销)')){ game.deleteDB('image','card_style'); button.style.backgroundImage='none'; button.className='button character dashedmenubutton'; node.classList.remove('showdelete'); if(lib.config.card_style=='custom'){ lib.configMenu.appearence.config.card_style.onclick('default'); switcher.lastChild.innerHTML='默认'; } button.classList.add('transparent'); } }); }, visualMenu:function(node,link,name,config){ node.className='button card fullskin'; node.style.backgroundSize='100% 100%'; switch(link){ case 'default':case 'custom':{ if(lib.config.theme=='simple'){ node.style.backgroundImage='linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; node.className='button character'; } else{ node.style.backgroundImage='none'; node.className='button character dashedmenubutton'; } break; } case 'new':node.setBackgroundImage('theme/style/card/image/new.png');break; case 'ol':node.setBackgroundImage('theme/style/card/image/ol.png');break; case 'wood':node.setBackgroundImage('theme/woodden/wood.jpg');node.style.backgroundSize='initial';break; case 'music':node.setBackgroundImage('theme/music/wood3.png');break; case 'simple':node.setBackgroundImage('theme/simple/card.png');break; } if(link=='custom'){ node.classList.add('transparent'); game.getDB('image','card_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; node.style.backgroundImage='url('+data+')'; node.className='button card fullskin'; node.parentNode.lastChild.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick:function(layout){ game.saveConfig('card_style',layout); var style=ui.css.card_style; ui.css.card_style=lib.init.css(lib.assetURL+'theme/style/card',lib.config.card_style); style.remove(); if(ui.css.card_stylesheet){ ui.css.card_stylesheet.remove(); delete ui.css.card_stylesheet; } if(layout=='custom'){ game.getDB('image','card_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.card_stylesheet){ ui.css.card_stylesheet.remove(); } ui.css.card_stylesheet=lib.init.sheet('.card:not(*:empty){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, unfrequent:true, }, cardback_style:{ name:'卡背样式', intro:'设置背面朝上的卡牌的样式', init:'default', item:{ // wood:'木纹', // music:'音乐', official:'原版', // new:'新版', feicheng:'废城', liusha:'流沙', ol:'手杀', custom:'自定', default:'默认', }, visualBar:function(node,item,create,switcher){ if(node.created){ return; } var button; for(var i=0;i<node.parentNode.childElementCount;i++){ if(node.parentNode.childNodes[i]._link=='custom'){ button=node.parentNode.childNodes[i]; } } if(!button){ return; } node.created=true; var deletepic; ui.create.filediv('.menubutton','添加图片',node,function(file){ if(file){ game.putDB('image','cardback_style',file,function(){ game.getDB('image','cardback_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; button.style.backgroundImage='url('+data+')'; button.className='button character'; node.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } }).inputNode.accept='image/*'; ui.create.filediv('.menubutton.deletebutton.addbutton','添加翻转图片',node,function(file){ if(file){ game.putDB('image','cardback_style2',file,function(){ node.classList.add('hideadd'); }); } }).inputNode.accept='image/*'; deletepic=ui.create.div('.menubutton.deletebutton','删除图片',node,function(){ if(confirm('确定删除自定义图片?(此操作不可撤销)')){ game.deleteDB('image','cardback_style'); game.deleteDB('image','cardback_style2'); button.style.backgroundImage='none'; button.className='button character dashedmenubutton'; node.classList.remove('showdelete'); node.classList.remove('hideadd'); if(lib.config.cardback_style=='custom'){ lib.configMenu.appearence.config.cardback_style.onclick('default'); switcher.lastChild.innerHTML='默认'; } button.classList.add('transparent'); } }); }, visualMenu:function(node,link,name,config){ node.style.backgroundSize='100% 100%'; switch(link){ case 'default':case 'custom':{ node.style.backgroundImage='none'; node.className='button character dashedmenubutton'; break; } case 'new':node.className='button character';node.setBackgroundImage('theme/style/cardback/image/new.png');break; case 'feicheng':node.className='button character';node.setBackgroundImage('theme/style/cardback/image/feicheng.png');break; case 'official':node.className='button character';node.setBackgroundImage('theme/style/cardback/image/official.png');break; case 'liusha':node.className='button character';node.setBackgroundImage('theme/style/cardback/image/liusha.png');break; case 'ol':node.className='button character';node.setBackgroundImage('theme/style/cardback/image/ol.png');break; case 'wood':node.className='button card fullskin';node.setBackgroundImage('theme/woodden/wood.jpg');node.style.backgroundSize='initial';break; case 'music':node.className='button card fullskin';node.setBackgroundImage('theme/music/wood3.png');break; } if(link=='custom'){ node.classList.add('transparent'); game.getDB('image','cardback_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; node.style.backgroundImage='url('+data+')'; node.className='button character'; node.parentNode.lastChild.classList.add('showdelete'); game.getDB('image','cardback_style2',function(file){ if(file){ node.parentNode.lastChild.classList.add('hideadd'); } }); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick:function(layout){ game.saveConfig('cardback_style',layout); var style=ui.css.cardback_style; ui.css.cardback_style=lib.init.css(lib.assetURL+'theme/style/cardback',lib.config.cardback_style); style.remove(); if(ui.css.cardback_stylesheet){ ui.css.cardback_stylesheet.remove(); delete ui.css.cardback_stylesheet; } if(ui.css.cardback_stylesheet2){ ui.css.cardback_stylesheet2.remove(); delete ui.css.cardback_stylesheet2; } if(layout=='custom'){ game.getDB('image','cardback_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.cardback_stylesheet){ ui.css.cardback_stylesheet.remove(); } ui.css.cardback_stylesheet=lib.init.sheet('.card:empty,.card.infohidden{background-image:url('+fileLoadedEvent.target.result+')}'); game.getDB('image','cardback_style2',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.cardback_stylesheet2){ ui.css.cardback_stylesheet2.remove(); } ui.css.cardback_stylesheet2=lib.init.sheet('.card.infohidden:not(.infoflip){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, unfrequent:true, }, hp_style:{ name:'体力条样式', init:'ol', item:{ default:'默认', // official:'勾玉', emotion:'表情', glass:'勾玉', round:'国战', ol:'手杀', xinglass:'双鱼', xinround:'OL', custom:'自定', }, visualBar:function(node,item,create,switcher){ if(node.created){ return; } var button; for(var i=0;i<node.parentNode.childElementCount;i++){ if(node.parentNode.childNodes[i]._link=='custom'){ button=node.parentNode.childNodes[i]; } } if(!button){ return; } node.created=true; var deletepic; ui.create.filediv('.menubutton.addbutton','添加图片',node,function(file){ if(file&&node.currentDB){ game.putDB('image','hp_style'+node.currentDB,file,function(){ game.getDB('image','hp_style'+node.currentDB,function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; button.childNodes[node.currentDB-1].style.backgroundImage='url('+data+')'; button.classList.add('shown'); node.classList.add('showdelete'); node.currentDB++; if(node.currentDB>4){ node.classList.add('hideadd'); button.classList.remove('transparent'); delete node.currentDB; } }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } }).inputNode.accept='image/*'; deletepic=ui.create.div('.menubutton.deletebutton','删除图片',node,function(){ if(confirm('确定删除自定义图片?(此操作不可撤销)')){ game.deleteDB('image','hp_style1'); game.deleteDB('image','hp_style2'); game.deleteDB('image','hp_style3'); game.deleteDB('image','hp_style4'); for(var i=0;i<button.childElementCount;i++){ button.childNodes[i].style.backgroundImage='none'; } node.classList.remove('showdelete'); node.classList.remove('hideadd'); if(lib.config.hp_style=='custom'){ lib.configMenu.appearence.config.hp_style.onclick('default'); switcher.lastChild.innerHTML='默认'; } button.classList.add('transparent'); button.classList.remove('shown'); node.currentDB=1; } }); }, visualMenu:function(node,link,name,config){ node.className='button hpbutton dashedmenubutton'; node.innerHTML=''; for(var i=1;i<=4;i++){ var div=ui.create.div(node); if(link=='default'){ ui.create.div(div); } else if(link!='custom'){ div.setBackgroundImage('theme/style/hp/image/'+link+i+'.png'); } if(i==4){ div.style.webkitFilter='grayscale(1)'; } } if(link=='custom'){ node.classList.add('transparent'); var getDB=function(num){ node.parentNode.lastChild.currentDB=num; game.getDB('image','hp_style'+num,function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; node.childNodes[num-1].style.backgroundImage='url('+data+')'; node.classList.add('shown'); node.parentNode.lastChild.classList.add('showdelete'); if(num<4){ getDB(num+1); } else{ node.parentNode.lastChild.classList.add('hideadd'); node.classList.remove('transparent'); delete node.parentNode.firstChild.currentDB; } }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } getDB(1); } }, onclick:function(layout){ game.saveConfig('hp_style',layout); var style=ui.css.hp_style; ui.css.hp_style=lib.init.css(lib.assetURL+'theme/style/hp',lib.config.hp_style); style.remove(); if(ui.css.hp_stylesheet1){ ui.css.hp_stylesheet1.remove(); delete ui.css.hp_stylesheet1; } if(ui.css.hp_stylesheet2){ ui.css.hp_stylesheet2.remove(); delete ui.css.hp_stylesheet2; } if(ui.css.hp_stylesheet3){ ui.css.hp_stylesheet3.remove(); delete ui.css.hp_stylesheet3; } if(ui.css.hp_stylesheet4){ ui.css.hp_stylesheet4.remove(); delete ui.css.hp_stylesheet4; } if(layout=='custom'){ game.getDB('image','hp_style1',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.hp_stylesheet1){ ui.css.hp_stylesheet1.remove(); } ui.css.hp_stylesheet1=lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="high"]>div:not(.lost){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); game.getDB('image','hp_style2',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.hp_stylesheet2){ ui.css.hp_stylesheet2.remove(); } ui.css.hp_stylesheet2=lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="mid"]>div:not(.lost){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); game.getDB('image','hp_style3',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.hp_stylesheet3){ ui.css.hp_stylesheet3.remove(); } ui.css.hp_stylesheet3=lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="low"]>div:not(.lost){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); game.getDB('image','hp_style4',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.hp_stylesheet4){ ui.css.hp_stylesheet4.remove(); } ui.css.hp_stylesheet4=lib.init.sheet('.hp:not(.text):not(.actcount)>.lost{background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, unfrequent:true, }, player_style:{ name:'角色背景', init:'default', intro:'设置角色的背景图片', item:{ wood:'木纹', music:'音乐', simple:'简约', custom:'自定', default:'默认', }, visualBar:function(node,item,create,switcher){ if(node.created){ return; } var button; for(var i=0;i<node.parentNode.childElementCount;i++){ if(node.parentNode.childNodes[i]._link=='custom'){ button=node.parentNode.childNodes[i]; } } if(!button){ return; } node.created=true; var deletepic; ui.create.filediv('.menubutton','添加图片',node,function(file){ if(file){ game.putDB('image','player_style',file,function(){ game.getDB('image','player_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; button.style.backgroundImage='url('+data+')'; button.className='button character'; button.style.backgroundSize='100% 100%'; node.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } }).inputNode.accept='image/*'; deletepic=ui.create.div('.menubutton.deletebutton','删除图片',node,function(){ if(confirm('确定删除自定义图片?(此操作不可撤销)')){ game.deleteDB('image','player_style'); button.style.backgroundImage='none'; button.className='button character dashedmenubutton'; node.classList.remove('showdelete'); if(lib.config.player_style=='custom'){ lib.configMenu.appearence.config.player_style.onclick('default'); switcher.lastChild.innerHTML='默认'; } button.classList.add('transparent'); } }); }, visualMenu:function(node,link,name,config){ node.className='button character'; node.style.backgroundSize=''; node.style.height='108px'; switch(link){ case 'default':case 'custom':{ node.style.backgroundImage='none'; node.className='button character dashedmenubutton'; break; } case 'wood':node.setBackgroundImage('theme/woodden/wood.jpg');break; case 'music':node.style.backgroundImage='linear-gradient(#4b4b4b, #464646)';break; case 'simple':node.style.backgroundImage='linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))';break; } if(link=='custom'){ node.classList.add('transparent'); game.getDB('image','player_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; node.style.backgroundImage='url('+data+')'; node.className='button character'; node.parentNode.lastChild.classList.add('showdelete'); node.style.backgroundSize='100% 100%'; }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick:function(layout){ game.saveConfig('player_style',layout); if(ui.css.player_stylesheet){ ui.css.player_stylesheet.remove(); delete ui.css.player_stylesheet; } if(layout=='custom'){ game.getDB('image','player_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.player_stylesheet){ ui.css.player_stylesheet.remove(); } ui.css.player_stylesheet=lib.init.sheet('#window .player{background-image:url("'+fileLoadedEvent.target.result+'");background-size:100% 100%;}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } else if(layout!='default'){ var str=''; switch(layout){ 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; } ui.css.player_stylesheet=lib.init.sheet('#window .player{background-image:'+str+'}'); } }, unfrequent:true, }, border_style:{ name:'角色边框', init:'default', intro:'设置角色边框的样式,当设为自动时,样式将随着一局游戏中伤害或击杀的数量自动改变', item:{ gold:'金框', silver:'银框', bronze:'铜框', dragon_gold:'金龙', dragon_silver:'银龙', dragon_bronze:'玉龙', custom:'自定', auto:'自动', default:'默认', }, visualBar:function(node,item,create,switcher){ if(node.created){ return; } var button; for(var i=0;i<node.parentNode.childElementCount;i++){ if(node.parentNode.childNodes[i]._link=='custom'){ button=node.parentNode.childNodes[i]; } } if(!button){ return; } node.created=true; var deletepic; ui.create.filediv('.menubutton','添加图片',node,function(file){ if(file){ game.putDB('image','border_style',file,function(){ game.getDB('image','border_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; button.style.backgroundImage='url('+data+')'; button.className='button character'; button.style.backgroundSize='100% 100%'; node.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } }).inputNode.accept='image/*'; deletepic=ui.create.div('.menubutton.deletebutton','删除图片',node,function(){ if(confirm('确定删除自定义图片?(此操作不可撤销)')){ game.deleteDB('image','border_style'); button.style.backgroundImage='none'; button.className='button character dashedmenubutton'; node.classList.remove('showdelete'); if(lib.config.border_style=='custom'){ lib.configMenu.appearence.config.border_style.onclick('default'); switcher.lastChild.innerHTML='默认'; } button.classList.add('transparent'); } }); }, visualMenu:function(node,link,name,config){ node.className='button character'; node.style.backgroundSize=''; node.style.height='108px'; node.dataset.decoration=''; if(link=='default'||link=='custom'||link=='auto'){ node.style.backgroundImage='none'; node.className='button character dashedmenubutton'; } else{ if(link.startsWith('dragon_')){ link=link.slice(7); node.dataset.decoration=link; } node.setBackgroundImage('theme/style/player/'+link+'1.png'); node.style.backgroundSize='100% 100%'; } if(link=='custom'){ node.classList.add('transparent'); game.getDB('image','border_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; node.style.backgroundImage='url('+data+')'; node.className='button character'; node.parentNode.lastChild.classList.add('showdelete'); node.style.backgroundSize='100% 100%'; }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick:function(layout){ game.saveConfig('border_style',layout); if(ui.css.border_stylesheet){ ui.css.border_stylesheet.remove(); delete ui.css.border_stylesheet; } if(layout=='custom'){ game.getDB('image','border_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.border_stylesheet){ ui.css.border_stylesheet.remove(); } ui.css.border_stylesheet=lib.init.sheet(); ui.css.border_stylesheet.id="ui.css.border"; ui.css.border_stylesheet.sheet.insertRule('#window .player>.framebg{display:block;background-image:url("'+fileLoadedEvent.target.result+'")}',0); ui.css.border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}',0); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } else if(layout!='default'&&layout!='auto'){ ui.css.border_stylesheet=lib.init.sheet(); if(layout.startsWith('dragon_')){ layout=layout.slice(7); ui.arena.dataset.framedecoration=layout; } else{ ui.arena.dataset.framedecoration=''; } 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/'+layout+'1.png")}',0); 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/'+layout+'3.png")}',0); ui.css.border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}',0); } }, unfrequent:true, }, autoborder_count:{ name:'边框升级方式', intro:'<strong>击杀</strong> 每击杀一人,边框提升两级<br><strong>伤害</strong> 每造成两点伤害,边框提升一级<br><strong>混合</strong> 击杀量决定边框颜色,伤害量决定边框装饰', init:'kill', item:{ kill:'击杀', damage:'伤害', mix:'混合', }, unfrequent:true, }, autoborder_start:{ name:'基础边框颜色', init:'bronze', item:{ bronze:'铜', silver:'银', gold:'金' }, unfrequent:true }, player_border:{ name:'边框宽度', init:'normal', intro:'设置角色的边框宽度', unfrequent:true, item:{ slim:'细', narrow:'窄', normal:'中', wide:'宽' }, onclick:function(item){ game.saveConfig('player_border',item); if(item!='wide'||game.layout=='long'||game.layout=='long2'){ ui.arena.classList.add('slim_player'); } else{ ui.arena.classList.remove('slim_player'); } if(item=='slim'){ ui.arena.classList.add('uslim_player'); } else{ ui.arena.classList.remove('uslim_player'); } if(item=='narrow'){ ui.arena.classList.add('mslim_player'); } else{ ui.arena.classList.remove('mslim_player'); } if(item=='normal'&&lib.config.mode!='brawl'&&(game.layout=='long'||game.layout=='long2')){ ui.arena.classList.add('lslim_player'); } else{ ui.arena.classList.remove('lslim_player'); } ui.window.dataset.player_border=item; } }, menu_style:{ name:'菜单背景', init:'default', item:{ wood:'木纹', music:'音乐', simple:'简约', custom:'自定', default:'默认', }, visualBar:function(node,item,create,switcher){ if(node.created){ return; } var button; for(var i=0;i<node.parentNode.childElementCount;i++){ if(node.parentNode.childNodes[i]._link=='custom'){ button=node.parentNode.childNodes[i]; } } if(!button){ return; } node.created=true; var deletepic; ui.create.filediv('.menubutton','添加图片',node,function(file){ if(file){ game.putDB('image','menu_style',file,function(){ game.getDB('image','menu_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; button.style.backgroundImage='url('+data+')'; button.style.backgroundSize='cover'; button.className='button character'; node.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } }).inputNode.accept='image/*'; deletepic=ui.create.div('.menubutton.deletebutton','删除图片',node,function(){ if(confirm('确定删除自定义图片?(此操作不可撤销)')){ game.deleteDB('image','menu_style'); button.style.backgroundImage='none'; button.style.backgroundSize='auto'; button.className='button character dashedmenubutton'; node.classList.remove('showdelete'); if(lib.config.menu_style=='custom'){ lib.configMenu.appearence.config.menu_style.onclick('default'); switcher.lastChild.innerHTML='默认'; } button.classList.add('transparent'); } }); }, visualMenu:function(node,link,name,config){ node.className='button character'; node.style.backgroundSize='auto'; switch(link){ case 'default':case 'custom':{ node.style.backgroundImage='none'; node.classList.add('dashedmenubutton'); break; } case 'wood':node.setBackgroundImage('theme/woodden/wood2.png');break; case 'music':node.style.backgroundImage='linear-gradient(#4b4b4b, #464646)';break; case 'simple':node.style.backgroundImage='linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))';break; } if(link=='custom'){ node.classList.add('transparent'); game.getDB('image','menu_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; node.style.backgroundImage='url('+data+')'; node.style.backgroundSize='cover'; node.className='button character'; node.parentNode.lastChild.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick:function(layout){ game.saveConfig('menu_style',layout); if(ui.css.menu_stylesheet){ ui.css.menu_stylesheet.remove(); delete ui.css.menu_stylesheet; } if(layout=='custom'){ game.getDB('image','menu_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.menu_stylesheet){ ui.css.menu_stylesheet.remove(); } ui.css.menu_stylesheet=lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:url("'+fileLoadedEvent.target.result+'");background-size:cover}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } else if(layout!='default'){ var str=''; switch(layout){ 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; } ui.css.menu_stylesheet=lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:'+str+'}'); } }, unfrequent:true, }, control_style:{ name:'按钮背景', init:'default', item:{ wood:'木纹', music:'音乐', simple:'简约', custom:'自定', default:'默认', }, visualBar:function(node,item,create,switcher){ if(node.created){ return; } var button; for(var i=0;i<node.parentNode.childElementCount;i++){ if(node.parentNode.childNodes[i]._link=='custom'){ button=node.parentNode.childNodes[i]; } } if(!button){ return; } node.created=true; var deletepic; ui.create.filediv('.menubutton','添加图片',node,function(file){ if(file){ game.putDB('image','control_style',file,function(){ game.getDB('image','control_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; button.style.backgroundImage='url('+data+')'; button.className='button character controlbutton'; node.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } }).inputNode.accept='image/*'; deletepic=ui.create.div('.menubutton.deletebutton','删除图片',node,function(){ if(confirm('确定删除自定义图片?(此操作不可撤销)')){ game.deleteDB('image','control_style'); button.style.backgroundImage='none'; button.className='button character controlbutton dashedmenubutton'; node.classList.remove('showdelete'); if(lib.config.control_style=='custom'){ lib.configMenu.appearence.config.control_style.onclick('default'); switcher.lastChild.innerHTML='默认'; } button.classList.add('transparent'); } }); }, visualMenu:function(node,link,name,config){ node.className='button character controlbutton'; node.style.backgroundSize=''; switch(link){ case 'default':case 'custom':{ node.style.backgroundImage='none'; node.classList.add('dashedmenubutton'); break; } case 'wood':node.setBackgroundImage('theme/woodden/wood.jpg');break; case 'music':node.style.backgroundImage='linear-gradient(#4b4b4b, #464646)';break; case 'simple':node.style.backgroundImage='linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))';break; } if(link=='custom'){ node.classList.add('transparent'); game.getDB('image','control_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; node.style.backgroundImage='url('+data+')'; node.className='button character controlbutton'; node.parentNode.lastChild.classList.add('showdelete'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick:function(layout){ game.saveConfig('control_style',layout); if(ui.css.control_stylesheet){ ui.css.control_stylesheet.remove(); delete ui.css.control_stylesheet; } if(layout=='custom'){ game.getDB('image','control_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.control_stylesheet){ ui.css.control_stylesheet.remove(); } ui.css.control_stylesheet=lib.init.sheet('#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:url("'+fileLoadedEvent.target.result+'")}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } else if(layout!='default'){ var str=''; switch(layout){ 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(layout=='wood'){ ui.css.control_stylesheet=lib.init.sheet('#window .control,#window .menubutton,#window #system>div>div,#window #system>div>.pressdown2{background-image:'+str+'}'); } else{ 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+'}'); } } }, unfrequent:true, }, custom_button:{ name:'自定义按钮高度', init:false, unfrequent:true, onclick:function(bool){ if(bool!=='skip'){ game.saveConfig('custom_button',bool); } if(ui.css.buttonsheet){ ui.css.buttonsheet.remove(); } if(lib.config.custom_button){ var cbnum1=6+(parseInt(lib.config.custom_button_system_top)||0); var cbnum2=6+(parseInt(lib.config.custom_button_system_bottom)||0); var cbnum3=3+(parseInt(lib.config.custom_button_control_top)||0); var cbnum4=3+(parseInt(lib.config.custom_button_control_bottom)||0); var cbnum5=2; var cbnum6=2; if(cbnum3<0){ cbnum5+=cbnum3; cbnum3=0; } if(cbnum4<0){ cbnum6+=cbnum4; cbnum4=0; } ui.css.buttonsheet=lib.init.sheet( '#system>div>div, .caption>div>.tdnode{padding-top:'+cbnum1+'px !important;padding-bottom:'+cbnum2+'px !important}', '#control>.control>div{padding-top:'+cbnum3+'px;padding-bottom:'+cbnum4+'px}', '#control>.control{padding-top:'+cbnum5+'px;padding-bottom:'+cbnum6+'px}' ); } } }, custom_button_system_top:{ name:'菜单上部高度', init:'0x', item:{ '-5x':'-5px', '-4x':'-4px', '-3x':'-3px', '-2x':'-2px', '-1x':'-1px', '0x':'默认', '1x':'1px', '2x':'2px', '3x':'3px', '4x':'4px', '5x':'5px', }, unfrequent:true, onclick:function(item){ game.saveConfig('custom_button_system_top',item); lib.configMenu.appearence.config.custom_button.onclick('skip'); } }, custom_button_system_bottom:{ name:'菜单下部高度', init:'0x', item:{ '-5x':'-5px', '-4x':'-4px', '-3x':'-3px', '-2x':'-2px', '-1x':'-1px', '0x':'默认', '1x':'1px', '2x':'2px', '3x':'3px', '4x':'4px', '5x':'5px', }, unfrequent:true, onclick:function(item){ game.saveConfig('custom_button_system_bottom',item); lib.configMenu.appearence.config.custom_button.onclick('skip'); } }, custom_button_control_top:{ name:'技能上部高度', init:'0x', item:{ '-5x':'-5px', '-4x':'-4px', '-3x':'-3px', '-2x':'-2px', '-1x':'-1px', '0x':'默认', '1x':'1px', '2x':'2px', '3x':'3px', '4x':'4px', '5x':'5px', }, unfrequent:true, onclick:function(item){ game.saveConfig('custom_button_control_top',item); lib.configMenu.appearence.config.custom_button.onclick('skip'); } }, custom_button_control_bottom:{ name:'技能下部高度', init:'0x', item:{ '-5x':'-5px', '-4x':'-4px', '-3x':'-3px', '-2x':'-2px', '-1x':'-1px', '0x':'默认', '1x':'1px', '2x':'2px', '3x':'3px', '4x':'4px', '5x':'5px', }, unfrequent:true, onclick:function(item){ game.saveConfig('custom_button_control_bottom',item); lib.configMenu.appearence.config.custom_button.onclick('skip'); } }, radius_size:{ name:'圆角大小', init:'default', item:{ off:'关闭', reduce:'减小', default:'默认', increase:'增大', }, unfrequent:true, onclick:function(item){ game.saveConfig('radius_size',item); ui.window.dataset.radius_size=item; } }, glow_phase:{ name:'当前回合角色高亮', unfrequent:true, init:'yellow', intro:'设置当前回合角色的边框颜色', item:{ none:'无', yellow:'黄色', green:'绿色', purple:'紫色', }, onclick:function(bool){ game.saveConfig('glow_phase',bool); lib.init.cssstyles(); } }, fold_card:{ name:'折叠手牌', init:true, unfrequent:true, }, fold_mode:{ name:'折叠模式菜单', intro:'关闭后模式菜单中“更多”内的项目将直接展开', init:true, unfrequent:true, }, seperate_control:{ name:'分离选项条', init:true, unfrequent:true, intro:'开启后玩家在进行选择时不同的选项将分开,而不是连在一起', }, blur_ui:{ name:'模糊效果', intro:'在暂停或打开菜单时开启模糊效果', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('blur_ui',bool); if(bool){ ui.window.classList.add('blur_ui'); } else{ ui.window.classList.remove('blur_ui'); } } }, glass_ui:{ name:'玻璃主题', intro:'为游戏主题打开玻璃效果(手机暂不支持)', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('glass_ui',bool); if(bool){ ui.window.classList.add('glass_ui'); } else{ ui.window.classList.remove('glass_ui'); } } }, damage_shake:{ name:'伤害抖动', intro:'角色受到伤害时的抖动效果', init:true, unfrequent:true, }, button_press:{ name:'按钮效果', intro:'选项条被按下时将有按下效果', init:true, unfrequent:true, }, jiu_effect:{ name:'喝酒效果', init:true, unfrequent:true, }, animation:{ name:'游戏特效', intro:'开启后出现属性伤害、回复体力等情况时会显示动画', init:false, unfrequent:true, }, skill_animation_type:{ name:'技能特效', intro:'开启后觉醒技、限定技将显示全屏文字', init:'default', unfrequent:true, item:{ default:'默认', old:'旧版', off:'关闭' } }, die_move:{ name:'阵亡效果', intro:'阵亡后武将的显示效果', init:'flip', unfrequent:true, item:{ off:'关闭', move:'移动', flip:'翻面', } }, target_shake:{ name:'目标效果', intro:'一名玩家成为卡牌或技能的目标时的显示效果', init:'off', item:{ off:'关闭', zoom:'缩放', shake:'抖动', }, unfrequent:true, onclick:function(bool){ game.saveConfig('target_shake',bool); ui.arena.dataset.target_shake=bool; } }, turned_style:{ name:'翻面文字', intro:'角色被翻面时显示“翻面”', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('turned_style',bool); if(bool){ ui.arena.classList.remove('hide_turned'); } else{ ui.arena.classList.add('hide_turned'); } } }, link_style2:{ name:'横置样式', intro:'设置角色被横置时的样式', init:'chain', unfrequent:true, item:{ chain:'铁索', rotate:'横置', mark:'标记' }, onclick:function(style){ var list=[]; for(var i=0;i<game.players.length;i++){ if(game.players[i].isLinked()){ list.push(game.players[i]); } } game.saveConfig('link_style2',style); for(var i=0;i<list.length;i++){ if(get.is.linked2(list[i])){ list[i].classList.add('linked2'); list[i].classList.remove('linked'); } else{ list[i].classList.add('linked'); list[i].classList.remove('linked2'); } } if(style=='chain'){ ui.arena.classList.remove('nolink'); } else{ ui.arena.classList.add('nolink'); } ui.updatem(); } }, cardshape:{ name:'手牌显示', intro:'将手牌设置为正方形或长方形', init:'default', unfrequent:true, item:{ default:'默认', oblong:'长方', }, onclick:function(item){ var linked=false; if(game.me&&game.me.isLinked()){ linked=true; } game.saveConfig('cardshape',item); if(item=='oblong'&&(game.layout=='long'||game.layout=='mobile'||game.layout=='long2'||game.layout=='nova')){ ui.arena.classList.add('oblongcard'); ui.window.classList.add('oblongcard'); } else{ ui.arena.classList.remove('oblongcard'); ui.window.classList.remove('oblongcard'); } if(linked){ if(get.is.linked2(game.me)){ game.me.classList.remove('linked'); game.me.classList.add('linked2'); } else{ game.me.classList.add('linked'); game.me.classList.remove('linked2'); } } } }, cardtempname:{ name:'视为卡牌名称显示', intro:'显示强制视为类卡牌(如武魂),包括拆顺对话框内的判定牌(国色)转换等名称的显示方式', init:'image', unfrequent:true, item:{ default:'纵向', horizon:'横向', image:'图片', off:'禁用', }, onclick:function(item){ game.saveConfig('cardtempname',item); if(!game.me||!game.me.getCards) return; var hs=game.me.getCards('h'); for(var i=0;i<hs.length;i++){ if(hs[i]._tempName){ switch(item){ case 'default': case 'horizon': case 'image': ui.create.cardTempName(hs[i]); break; default: hs[i]._tempName.delete(); delete hs[i]._tempName; } } } } }, /*textequip:{ name:'装备显示', init:'image', unfrequent:true, item:{ image:'图片', text:'文字', }, onclick:function(item){ game.saveConfig('textequip',item); if(item=='text'&&(game.layout=='long'||game.layout=='mobile')){ ui.arena.classList.add('textequip'); } else{ ui.arena.classList.remove('textequip'); } } },*/ buttoncharacter_style:{ name:'选将样式', init:'default', item:{ default:'默认', simple:'精简', old:'旧版' }, unfrequent:true, }, buttoncharacter_prefix:{ name:'武将前缀', init:'default', item:{ default:'默认', simple:'不显示颜色', off:'不显示前缀' }, unfrequent:true, }, cursor_style:{ name:'鼠标指针', init:'auto', intro:'设置为固定后鼠标指针将不随移动到的区域而变化', unfrequent:true, item:{ auto:'自动', pointer:'固定' }, onclick:function(item){ game.saveConfig('cursor_style',item); if(item=='pointer'){ ui.window.classList.add('nopointer'); } else{ ui.window.classList.remove('nopointer'); } } }, name_font:{ name:'人名字体', init:'xingkai', unfrequent:true, item:{}, textMenu:function(node,link){ if(link!='default'){ node.style.fontFamily=link; } node.style.fontSize='20px'; }, onclick:function(font){ game.saveConfig('name_font',font); lib.init.cssstyles(); } }, identity_font:{ name:'身份字体', init:'huangcao', unfrequent:true, item:{}, textMenu:function(node,link){ if(link!='default'){ node.style.fontFamily=link; } node.style.fontSize='20px'; }, onclick:function(font){ game.saveConfig('identity_font',font); lib.init.cssstyles(); } }, cardtext_font:{ name:'卡牌字体', init:'default', unfrequent:true, item:{}, textMenu:function(node,link){ if(link!='default'){ node.style.fontFamily=link; } node.style.fontSize='20px'; }, onclick:function(font){ game.saveConfig('cardtext_font',font); lib.init.cssstyles(); } }, global_font:{ name:'界面字体', init:'default', unfrequent:true, item:{}, textMenu:function(node,link){ if(link!='default'){ node.style.fontFamily=link; } else{ node.style.fontFamily="'STHeiti','SimHei','Microsoft JhengHei','Microsoft YaHei','WenQuanYi Micro Hei','Suits',Helvetica,Arial,sans-serif"; } node.style.fontSize='20px'; }, onclick:function(font){ game.saveConfig('global_font',font); lib.init.cssstyles(); } }, suits_font:{ name:'替换花色字体', init:true, unfrequent:true, intro:'使用全角字符的花色替代系统自带的花色(重启游戏后生效)', onclick:function(bool){ game.saveConfig('suits_font',bool); } }, update:function(config,map){ if(lib.config.custom_button){ map.custom_button_system_top.show(); map.custom_button_system_bottom.show(); map.custom_button_control_top.show(); map.custom_button_control_bottom.show(); } else{ map.custom_button_system_top.hide(); map.custom_button_system_bottom.hide(); map.custom_button_control_top.hide(); map.custom_button_control_bottom.hide(); } if(lib.config.change_skin){ map.change_skin_auto.show(); } else{ map.change_skin_auto.hide(); } if(lib.config.image_background_random){ map.image_background_blur.show(); map.image_background.hide(); // map.import_background.hide(); } else{ map.image_background.show(); if(lib.config.image_background=='default'){ map.image_background_blur.hide(); } else{ map.image_background_blur.show(); } // if(lib.config.image_background=='custom'&&lib.db){ // map.import_background.show(); // } // else{ // map.import_background.hide(); // } } if(lib.config.layout=='long'||lib.config.layout=='mobile'){ //map.textequip.show(); map.cardshape.show(); map.phonelayout.show(); } else{ //map.textequip.hide(); if(lib.config.layout=='long2'||lib.config.layout=='nova'){ map.phonelayout.show(); map.cardshape.show(); } else{ map.phonelayout.hide(); map.cardshape.hide(); } } if(lib.config.layout=='long'){ // map.fewplayer.show(); map.player_height.show(); } else{ // map.fewplayer.hide(); if(lib.config.layout=='long2'){ map.player_height.show(); } else{ map.player_height.hide(); } } if(lib.config.layout=='nova'){ map.player_height_nova.show(); } else{ map.player_height_nova.hide(); } if(lib.config.touchscreen){ map.cursor_style.hide(); } else{ map.cursor_style.show(); } if(lib.config.border_style=='auto'){ map.autoborder_count.show(); map.autoborder_start.show(); } else{ map.autoborder_count.hide(); map.autoborder_start.hide(); } }, } }, view:{ name:'显示', config:{ update:function(config,map){ if(lib.config.mode=='versus'||lib.config.mode=='chess'||lib.config.mode=='tafang'||lib.config.mode=='boss'){ map.show_handcardbutton.show(); } else{ map.show_handcardbutton.hide(); } if(lib.config.touchscreen){ map.pop_logv.hide(); } else{ map.pop_logv.show(); } if(lib.device){ if(lib.device=='android'){ map.show_statusbar_android.show(); map.show_statusbar_ios.hide(); } else if(lib.device=='ios'){ map.show_statusbar_ios.show(); map.show_statusbar_android.hide(); } if(!game.download){ setTimeout(function(){ if(!window.StatusBar){ map.show_statusbar.hide(); } },5000); } } else{ map.show_statusbar_ios.hide(); map.show_statusbar_android.hide(); } if(get.is.phoneLayout()){ map.remember_round_button.show(); map.popequip.show(); map.filternode_button.show(); map.show_pause.hide(); map.show_auto.hide(); map.show_replay.hide(); map.show_round_menu.show(); } else{ map.show_pause.show(); map.show_auto.show(); map.show_replay.show(); map.show_round_menu.hide(); map.remember_round_button.hide(); map.popequip.hide(); map.filternode_button.hide(); } if(lib.config.show_card_prompt){ map.hide_card_prompt_basic.show(); map.hide_card_prompt_equip.show(); } else{ map.hide_card_prompt_basic.hide(); map.hide_card_prompt_equip.hide(); } if(lib.config.show_log!='off'){ map.clear_log.show(); } else{ map.clear_log.hide(); } if(get.is.phoneLayout()){ map.show_time2.show(); map.show_time.hide(); if(lib.config.show_time2){ map.watchface.show(); } else{ map.watchface.hide(); } } else{ map.show_time2.hide(); map.show_time.show(); map.watchface.hide(); } if(lib.config.show_extensionmaker){ map.show_extensionshare.show(); } else{ map.show_extensionshare.hide(); } }, show_history:{ name:'出牌记录栏', init:'off', intro:'在屏幕左侧或右侧显示出牌记录', unfrequent:true, item:{ off:'关闭', left:'靠左', right:'靠右', }, onclick:function(bool){ if(lib.config.show_history=='right') ui.window.animate('rightbar2'); game.saveConfig('show_history',bool); if(_status.video||!_status.prepareArena) return; if(bool=='left'){ ui.window.classList.add('leftbar'); ui.window.classList.remove('rightbar'); } else if(bool=='right'){ ui.window.classList.remove('leftbar'); ui.window.classList.add('rightbar'); } else{ ui.window.classList.remove('leftbar'); ui.window.classList.remove('rightbar'); } } }, pop_logv:{ name:'自动弹出记录', init:false, unfrequent:true }, show_log:{ name:'历史记录栏', init:'off', intro:'在屏幕中部显示出牌文字记录', unfrequent:true, item:{ off:'关闭', left:'靠左', center:'居中', right:'靠右', }, onclick:function(bool){ game.saveConfig('show_log',bool); if(lib.config.show_log!='off'){ ui.arenalog.style.display=''; ui.arenalog.dataset.position=bool; } else{ ui.arenalog.style.display='none'; ui.arenalog.innerHTML=''; } } }, clear_log:{ name:'自动清除历史记录', init:false, unfrequent:true, intro:'开启后将定时清除历史记录栏的条目(而不是等记录栏满后再清除)' }, log_highlight:{ name:'历史记录高亮', init:true, unfrequent:true, intro:'开启后历史记录不同类别的信息将以不同颜色显示', }, show_time:{ name:'显示时间', intro:'在屏幕顶部显示当前时间', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('show_time',bool); if(bool){ ui.time.style.display=''; } else{ ui.time.style.display='none'; } } }, show_time2:{ name:'显示时间', intro:'在触屏按钮处显示当前时间', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('show_time2',bool); if(bool){ ui.roundmenu.classList.add('clock'); } else{ ui.roundmenu.classList.remove('clock'); } } }, watchface:{ name:'表盘样式', init:'none', unfrequent:true, item:{ none:'默认', simple:'简约', }, onclick:function(item){ game.saveConfig('watchface',item); ui.roundmenu.dataset.watchface=item; } }, show_time3:{ name:'显示游戏时间', init:false, unfrequent:true }, show_statusbar_android:{ name:'显示状态栏', init:false, unfrequent:true, content:function(bool){ game.saveConfig('show_statusbar',bool); if(window.StatusBar&&lib.device=='android'){ if(bool){ window.StatusBar.overlaysWebView(false); window.StatusBar.backgroundColorByName('black'); window.StatusBar.show(); } else{ window.StatusBar.hide(); } } } }, show_statusbar_ios:{ name:'显示状态栏', init:'off', unfrequent:true, item:{ default:'默认', overlay:'嵌入', auto:'自动', off:'关闭' }, onclick:function(bool){ game.saveConfig('show_statusbar_ios',bool); if(window.StatusBar&&lib.device=='ios'){ if(bool!='off'&&bool!='auto'){ if(lib.config.show_statusbar_ios=='default'){ window.StatusBar.overlaysWebView(false); document.body.classList.remove('statusbar'); } else{ window.StatusBar.overlaysWebView(true); document.body.classList.add('statusbar'); } window.StatusBar.backgroundColorByName('black'); window.StatusBar.show(); } else{ document.body.classList.remove('statusbar'); window.StatusBar.hide(); } } } }, show_card_prompt:{ name:'显示出牌信息', intro:'出牌时在使用者上显示卡牌名称', init:true, unfrequent:true, }, hide_card_prompt_basic:{ name:'隐藏基本牌信息', intro:'不显示基本牌名称', init:false, unfrequent:true, }, hide_card_prompt_equip:{ name:'隐藏装备牌信息', intro:'不显示装备牌名称', init:false, unfrequent:true, }, show_phase_prompt:{ name:'显示阶段信息', intro:'在当前回合不同阶段开始时显示阶段名称', init:true, unfrequent:true, }, show_phaseuse_prompt:{ name:'出牌阶段提示', intro:'在你出牌时显示提示文字', init:true, unfrequent:true, }, auto_popped_config:{ name:'自动弹出选项', intro:'鼠标移至选项按钮时弹出模式选择菜单', init:true, unfrequent:true, }, auto_popped_history:{ name:'自动弹出历史', intro:'鼠标移至暂停按钮时弹出历史记录菜单', init:false, unfrequent:true, }, show_round_menu:{ name:'显示触屏按钮', init:true, unfrequent:true, onclick:function(bool){ if(get.is.nomenu('show_round_menu',bool)) return false; game.saveConfig('show_round_menu',bool); if(bool&&ui.roundmenu){ ui.roundmenu.style.display=''; } else{ ui.roundmenu.style.display='none'; alert('关闭触屏按钮后可通过手势打开菜单(默认为下划)') } } }, remember_round_button:{ name:'记住按钮位置', intro:'重新开始后触屏按钮将保存的上一局的位置', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('remember_round_button',bool); if(!bool){ ui.click.resetround(); } } }, remember_dialog:{ name:'记住对话框位置', intro:'移动对话框后新的对话框也将在移动后的位置显示', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('remember_dialog',bool); if(!bool){ if(ui.dialog){ var dialog=ui.dialog; dialog.style.transform=''; dialog._dragtransform=[0,0]; dialog.style.transition='all 0.3s'; dialog._dragtouches; dialog._dragorigin; dialog._dragorigintransform; setTimeout(function(){ dialog.style.transition=''; },500); } game.saveConfig('dialog_transform',[0,0]); } } }, transparent_dialog:{ name:'堆叠对话框虚化', init:false, intro:'当具有static属性的对话框堆叠(如五谷丰登对话框中提示无懈可击)时,将后方的对话框变为半透明', onclick:function(bool){ game.saveConfig('transparent_dialog',bool); if(bool){ for(var i=0;i<ui.dialogs.length;i++){ if(ui.dialogs[i]!=ui.dialog&&ui.dialogs[i].static){ ui.dialogs[i].unfocus(); } } } else{ for(var i=0;i<ui.dialogs.length;i++){ if(ui.dialogs[i]!=ui.dialog&&ui.dialogs[i].static){ ui.dialogs[i].refocus(); } } } } }, show_rarity:{ name:'显示武将评级', init:false, intro:'仅供娱乐,重启后生效', unfrequent:true, onclick:function(bool){ game.saveConfig('show_rarity',bool); } }, mark_identity_style:{ name:'标记身份操作', intro:'设置单击身份按钮时的操作', unfrequent:true, init:'menu', item:{ menu:'菜单', click:'单击', }, }, character_dialog_tool:{ name:'自由选将显示', intro:'点击自由选将时默认显示的条目', init:'最近', item:{ '收藏':'收藏', '最近':'最近', 'all':'全部' }, unfrequent:true, }, recent_character_number:{ name:'最近使用武将', intro:'自由选将对话框中最近使用武将的数量', init:'12', item:{ '6':'6', '12':'12', '20':'24', '30':'36', }, unfrequent:true }, popequip:{ name:'触屏装备选择', intro:'设置触屏布局中选择装备的方式', init:true, unfrequent:true, }, filternode_button:{ name:'触屏筛选按钮', intro:'设置自由选将对话框中筛选按钮的样式', init:true, unfrequent:true, }, show_charactercard:{ name:'显示武将资料', intro:'在武将界面单击时弹出武将资料卡', init:true, unfrequent:true }, show_favourite:{ name:'显示添加收藏', intro:'在角色的右键菜单中显示添加收藏', init:false, unfrequent:true }, show_favmode:{ name:'显示模式收藏', intro:'快捷菜单中显示收藏模式', init:true, unfrequent:true }, show_favourite_menu:{ name:'显示收藏菜单', intro:'在选项-武将中显示收藏一栏', init:true, unfrequent:true }, show_ban_menu:{ name:'显示禁将菜单', intro:'在选项-武将中显示禁将一栏', init:true, unfrequent:true }, right_range:{ name:'显示距离信息', intro:'在角色的右键菜单中显示距离等信息', init:true, unfrequent:true }, hide_card_image:{ name:'隐藏卡牌背景', intro:'所有卡牌将使用文字作为背景', init:false, unfrequent:true, restart:true, }, show_name:{ name:'显示角色名称', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('show_name',bool); if(bool){ ui.arena.classList.remove('hide_name'); } else{ ui.arena.classList.add('hide_name'); } } }, show_sex:{ name:'显示角色性别', intro:'在角色的右键菜单中显示角色性别', init:true, unfrequent:true }, show_group:{ name:'显示角色势力', intro:'在角色的右键菜单中显示角色势力', init:true, unfrequent:true }, show_replay:{ name:'显示重来按钮', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('show_replay',bool); if(lib.config.show_replay){ ui.replay.style.display=''; } else{ ui.replay.style.display='none'; } } }, show_playerids:{ name:'显示身份按钮', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('show_playerids',bool); if(lib.config.show_playerids){ ui.playerids.style.display=''; } else{ ui.playerids.style.display='none'; } } }, show_sortcard:{ name:'显示整理手牌按钮', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('show_sortcard',bool); if(lib.config.show_sortcard){ ui.sortCard.style.display=''; } else{ ui.sortCard.style.display='none'; } } }, show_pause:{ name:'显示暂停按钮', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('show_pause',bool); if(lib.config.show_pause){ ui.pause.style.display=''; } else{ ui.pause.style.display='none'; } } }, show_auto:{ name:'显示托管按钮', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('show_auto',bool); if(lib.config.show_auto){ ui.auto.style.display=''; } else{ ui.auto.style.display='none'; } } }, show_volumn:{ name:'显示音量按钮', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('show_volumn',bool); if(lib.config.show_volumn){ ui.volumn.style.display=''; } else{ ui.volumn.style.display='none'; } } }, show_cardpile:{ name:'显示牌堆按钮', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('show_cardpile',bool); if(bool){ ui.cardPileButton.style.display=''; } else{ ui.cardPileButton.style.display='none'; } } }, show_cardpile_number:{ name:'显示剩余牌数', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('show_cardpile_number',bool); if(bool){ ui.cardPileNumber.style.display=''; } else{ ui.cardPileNumber.style.display='none'; } } }, show_handcardbutton:{ name:'显示手牌按钮', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('show_handcardbutton',bool); } }, show_giveup:{ name:'显示投降按钮', init:true, unfrequent:true, onclick:function(bool){ game.saveConfig('show_giveup',bool); } }, show_wuxie:{ name:'显示无懈按钮', intro:'在右上角显示不询问无懈', init:false, unfrequent:true, onclick:function(bool){ game.saveConfig('show_wuxie',bool); if(lib.config.show_wuxie){ ui.wuxie.style.display=''; } else{ ui.wuxie.style.display='none'; } } }, wuxie_right:{ name:'无懈按钮靠左', init:true, unfrequent:true, }, show_discardpile:{ name:'暂停时显示弃牌堆', init:false, unfrequent:true, }, show_extensionmaker:{ name:'显示制作扩展', init:true, unfrequent:true, }, show_extensionshare:{ name:'显示分享扩展', init:true, unfrequent:true, }, show_characternamepinyin:{ name:'显示武将名注解', intro:'在武将资料卡显示武将名及其注解、性别、势力、体力等信息', init:'showPinyin', unfrequent:true, item:{ doNotShow:'不显示', showPinyin:'拼音(样式一)', showCodeIdentifier:'代码ID(样式一)', showPinyin2:'拼音(样式二)', showCodeIdentifier2:'代码ID(样式二)', }, visualMenu:(node,link,name)=>{ node.classList.add('button','character'); const style=node.style; style.alignItems='center'; style.animation='background-position-left-center-right-center-left-center 15s ease infinite'; style.background='linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB)'; style.backgroundSize='400% 400%'; style.display='flex'; style.height='60px'; style.justifyContent='center'; style.width='180px'; const firstChild=node.firstChild; firstChild.removeAttribute('class'); firstChild.style.position='initial'; if(link=='doNotShow') return; const ruby=document.createElement('ruby'); ruby.textContent=name; const rt=document.createElement('rt'); rt.style.fontSize='smaller'; if(link=='showPinyin2'||link=='showCodeIdentifier2'){ rt.textContent=link=='showCodeIdentifier2'?'['+link+']':'['+get.pinyin(name)+']'; ruby.appendChild(rt); }else{ const leftParenthesisRP=document.createElement('rp'); leftParenthesisRP.textContent='('; ruby.appendChild(leftParenthesisRP); rt.textContent=link=='showCodeIdentifier'?link:get.pinyin(name).join(' '); ruby.appendChild(rt); const rightParenthesisRP=document.createElement('rp'); rightParenthesisRP.textContent=')'; ruby.appendChild(rightParenthesisRP); } firstChild.innerHTML=ruby.outerHTML; } }, show_skillnamepinyin:{ name:'显示技能名注解', intro:'在武将资料卡显示技能名注解', get init(){ return lib.configMenu.view.config.show_characternamepinyin.init; }, get unfrequent(){ return lib.configMenu.view.config.show_characternamepinyin.unfrequent; }, get item(){ return lib.configMenu.view.config.show_characternamepinyin.item; }, get visualMenu(){ return lib.configMenu.view.config.show_characternamepinyin.visualMenu; } } } }, audio:{ name:'音效', config:{ update:function(config,map){ if(lib.config.background_music=='music_custom'&&(lib.device||lib.node)){ map.import_music.show(); } else{ map.import_music.hide(); } map.clear_background_music[get.is.object(lib.config.customBackgroundMusic)?'show':'hide'](); ui.background_music_setting=map.background_music; map.background_music._link.config.updatex.call(map.background_music,[]); }, background_music:{ updatex:function(){ this.lastChild.innerHTML=this._link.config.item[lib.config.background_music]; var menu=this._link.menu; for(var i=0;i<menu.childElementCount;i++){ if(!['music_off','music_custom','music_random'].concat(lib.config.all.background_music).contains(menu.childNodes[i]._link)) menu.childNodes[i].delete(); } }, name:'背景音乐', init:true, item:{ music_default:'默认', }, onclick:function(item){ game.saveConfig('background_music',item); game.playBackgroundMusic(); } }, import_music:{ name:'<div style="white-space:nowrap;width:calc(100% - 5px)">'+ '<input type="file" style="width:calc(100% - 40px)" accept="audio/*">'+ '<button style="width:40px">确定</button></div>', clear:true, }, background_audio:{ name:'游戏音效', init:true, }, background_speak:{ name:'人物配音', init:true, }, equip_audio:{ name:'装备配音', init:false, }, repeat_audio:{ name:'播放重复语音', init:false, }, volumn_audio:{ name:'音效音量', init:8, item:{ '0':'〇', '1':'一', '2':'二', '3':'三', '4':'四', '5':'五', '6':'六', '7':'七', '8':'八', }, onclick:function(volume){ game.saveConfig('volumn_audio',parseInt(volume)); } }, volumn_background:{ name:'音乐音量', init:8, item:{ '0':'〇', '1':'一', '2':'二', '3':'三', '4':'四', '5':'五', '6':'六', '7':'七', '8':'八', }, onclick:function(volume){ game.saveConfig('volumn_background',parseInt(volume)); ui.backgroundMusic.volume=volume/8; } }, clear_background_music:{ name:'清除自定义背景音乐', clear:true, onclick:function(){ if(confirm('是否清除已导入的所有自定义背景音乐?(该操作不可撤销!)')){ for(var i in lib.config.customBackgroundMusic){ lib.config.all.background_music.remove(i); if(i.startsWith('cdv_')){ game.removeFile('audio/background/'+i+'.mp3'); } else{ game.deleteDB('audio',i); } } lib.config.customBackgroundMusic=null; game.saveConfig('customBackgroundMusic',null); game.saveConfig('background_music','music_off'); if(!_status._aozhan) game.playBackgroundMusic(); } }, }, } }, skill:{ name:'技能', config:{ update:function(config,map){ for(var i in map){ if(map[i]._link.config.type=='autoskill'){ if(!lib.config.autoskilllist.contains(i)){ map[i].classList.add('on'); } else{ map[i].classList.remove('on'); } } else if(map[i]._link.config.type=='banskill'){ if(!lib.config.forbidlist.contains(i)){ map[i].classList.add('on'); } else{ map[i].classList.remove('on'); } } } } } }, others:{ name:'其它', config:{ // reset_database:{ // name:'重置游戏', // onclick:function(){ // var node=this; // if(node._clearing){ // if(indexedDB) indexedDB.deleteDatabase(lib.configprefix+'data'); // game.reload(); // return; // } // node._clearing=true; // node.innerHTML='单击以确认 (3)'; // setTimeout(function(){ // node.innerHTML='单击以确认 (2)'; // setTimeout(function(){ // node.innerHTML='单击以确认 (1)'; // setTimeout(function(){ // node.innerHTML='重置游戏录像'; // delete node._clearing; // },1000); // },1000); // },1000); // }, // clear:true // }, reset_game:{ name:'重置游戏设置', onclick:function(){ var node=this; if(node._clearing){ 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); } game.deleteDB('config'); game.deleteDB('data'); game.reload(); return; } node._clearing=true; node.firstChild.innerHTML='单击以确认 (3)'; setTimeout(function(){ node.firstChild.innerHTML='单击以确认 (2)'; setTimeout(function(){ node.firstChild.innerHTML='单击以确认 (1)'; setTimeout(function(){ node.firstChild.innerHTML='重置游戏设置'; delete node._clearing; },1000); },1000); },1000); }, clear:true }, reset_hiddenpack:{ name:'重置隐藏内容', onclick:function(){ if(this.firstChild.innerHTML!='已重置'){ this.firstChild.innerHTML='已重置' game.saveConfig('hiddenModePack',[]); game.saveConfig('hiddenCharacterPack',[]); game.saveConfig('hiddenCardPack',[]); game.saveConfig('hiddenPlayPack',[]); game.saveConfig('hiddenBackgroundPack',[]); var that=this; setTimeout(function(){ that.firstChild.innerHTML='重置隐藏内容'; setTimeout(function(){ if(confirm('是否重新启动使改变生效?')){ game.reload(); } }); },500); } }, clear:true }, reset_tutorial:{ name:'重置新手向导', onclick:function(){ if(this.firstChild.innerHTML!='已重置'){ this.firstChild.innerHTML='已重置' game.saveConfig('new_tutorial',false); game.saveConfig('prompt_hidebg'); game.saveConfig('prompt_hidepack'); var that=this; setTimeout(function(){ that.firstChild.innerHTML='重置新手向导'; },500); } }, clear:true }, import_data:{ name:'导入游戏设置', onclick:function(){ ui.import_data_button.classList.toggle('hidden'); }, clear:true }, import_data_button:{ name:'<div style="white-space:nowrap;width:calc(100% - 10px)">'+ '<input type="file" accept="*/*" style="width:calc(100% - 40px)">'+ '<button style="width:40px">确定</button></div>', clear:true, }, export_data:{ name:'导出游戏设置', onclick:function(){ var data; var export_data=function(data){ game.export(lib.init.encode(JSON.stringify(data)),'无名杀 - 数据 - '+(new Date()).toLocaleString()); } if(!lib.db){ data={}; for(var i in localStorage){ if(i.startsWith(lib.configprefix)){ data[i]=localStorage[i]; } } export_data(data); } else{ game.getDB('config',null,function(data1){ game.getDB('data',null,function(data2){ export_data({ config:data1, data:data2 }); }); }); } }, clear:true }, redownload_game:{ name:'重新下载游戏', onclick:function(){ var node=this; if(node._clearing){ localStorage.removeItem('noname_inited'); game.reload(); return; } node._clearing=true; node.firstChild.innerHTML='单击以确认 (3)'; setTimeout(function(){ node.firstChild.innerHTML='单击以确认 (2)'; setTimeout(function(){ node.firstChild.innerHTML='单击以确认 (1)'; setTimeout(function(){ node.firstChild.innerHTML='重新下载游戏'; delete node._clearing; },1000); },1000); },1000); }, clear:true }, update:function(config,map){ if(lib.device||lib.node){ map.redownload_game.show(); } else{ map.redownload_game.hide(); } } // trim_game:{ // name:'隐藏非官方扩展包', // onclick:function(){ // if(this.innerHTML!='已隐藏'){ // this.innerHTML='已隐藏'; // var pack=lib.config.all.cards.slice(0); // if(Array.isArray(lib.config.hiddenCardPack)){ // for(var i=0;i<lib.config.hiddenCardPack.length;i++){ // pack.add(lib.config.hiddenCardPack[i]); // } // } // for(var i=0;i<pack.length;i++){ // if(lib.config.all.sgscards.contains(pack[i])){ // pack.splice(i--,1); // } // } // game.saveConfig('hiddenCardPack',pack); // // var pack=lib.config.all.characters.slice(0); // if(Array.isArray(lib.config.hiddenCharacterPack)){ // for(var i=0;i<lib.config.hiddenCharacterPack.length;i++){ // pack.add(lib.config.hiddenCharacterPack[i]); // } // } // for(var i=0;i<pack.length;i++){ // if(lib.config.all.sgscharacters.contains(pack[i])){ // pack.splice(i--,1); // } // } // game.saveConfig('hiddenCharacterPack',pack); // // var pack=lib.config.all.mode.slice(0); // if(Array.isArray(lib.config.hiddenModePack)){ // for(var i=0;i<lib.config.hiddenModePack.length;i++){ // pack.add(lib.config.hiddenModePack[i]); // } // } // for(var i=0;i<pack.length;i++){ // if(lib.config.all.sgsmodes.contains(pack[i])){ // pack.splice(i--,1); // } // } // game.saveConfig('hiddenModePack',pack); // // var that=this; // setTimeout(function(){ // that.innerHTML='隐藏非官方扩展包'; // },500); // } // }, // clear:true // } } } }, extensionMenu:{ cardpile:{ enable:{ name:'开启', init:false, restart:true, }, intro:{ name:'将杀闪等牌在牌堆中的比例维持在与军争牌堆相同,防止开启扩展包后被过多地稀释', clear:true, nopointer:true, }, sha:{ name:'杀', init:'1', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, huosha:{ name:'火杀', init:'1', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, leisha:{ name:'雷杀', init:'1', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, shan:{ name:'闪', init:'1', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, tao:{ name:'桃', init:'0', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, jiu:{ name:'酒', init:'0', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, wuxie:{ name:'无懈可击', init:'0.5', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, nanman:{ name:'南蛮入侵', init:'0', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, wanjian:{ name:'万箭齐发', init:'0', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, guohe:{ name:'过河拆桥', init:'0', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, shunshou:{ name:'顺手牵羊', init:'0', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, tiesuo:{ name:'铁索连环', init:'0', item:{ '1':'补充全部', '0.5':'补充一半', '0':'不补充' } }, hide:{ name:'隐藏此扩展', clear:true, onclick:function(){ if(this.firstChild.innerHTML=='隐藏此扩展'){ this.firstChild.innerHTML='此扩展将在重启后隐藏'; lib.config.hiddenPlayPack.add('cardpile'); if(!lib.config.prompt_hidepack){ alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); game.saveConfig('prompt_hidepack',true); } } else{ this.firstChild.innerHTML='隐藏此扩展'; lib.config.hiddenPlayPack.remove('cardpile'); } game.saveConfig('hiddenPlayPack',lib.config.hiddenPlayPack); } }, }, boss:{ enable:{ name:'开启', init:false, restart:true, onswitch:function(bool){ if(bool){ var storage={boss:{},versus:{},translate:{}}; var loadversus=function(){ game.loadModeAsync('versus',function(mode){ for(var i in mode.translate){ storage.translate[i]=mode.translate[i]; } for(var i in mode.jiangeboss){ if(mode.jiangeboss[i][4].contains('bossallowed')){ storage.versus[i]=mode.jiangeboss[i]; } } localStorage.setItem('boss_storage_playpackconfig',JSON.stringify(storage)); }); }; game.loadModeAsync('boss',function(mode){ for(var i in mode.translate){ storage.translate[i]=mode.translate[i]; } for(var i in mode.characterPack.mode_boss){ if(mode.characterPack.mode_boss[i][4].contains('bossallowed')){ storage.boss[i]=mode.characterPack.mode_boss[i]; } } loadversus(); }); } else{ localStorage.removeItem('boss_storage_playpackconfig'); } } }, intro:{ name:'将剑阁和挑战模式的武将添加到其它模式', clear:true, nopointer:true, }, enableai:{ name:'随机选将可用', init:false }, hide:{ name:'隐藏此扩展', clear:true, onclick:function(){ if(this.firstChild.innerHTML=='隐藏此扩展'){ this.firstChild.innerHTML='此扩展将在重启后隐藏'; lib.config.hiddenPlayPack.add('boss'); if(!lib.config.prompt_hidepack){ alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); game.saveConfig('prompt_hidepack',true); } } else{ this.firstChild.innerHTML='隐藏此扩展'; lib.config.hiddenPlayPack.remove('boss'); } game.saveConfig('hiddenPlayPack',lib.config.hiddenPlayPack); } }, }, wuxing:{ enable:{ name:'开启', init:false, restart:true, }, intro:{ name:'每名角色和部分卡牌在游戏开始时随机获得一个属性', clear:true, nopointer:true, }, num:{ name:'带属性卡牌', init:'0.3', item:{ '0.1':'10%', '0.2':'20%', '0.3':'30%', '0.5':'50%', } }, hide:{ name:'隐藏此扩展', clear:true, onclick:function(){ if(this.firstChild.innerHTML=='隐藏此扩展'){ this.firstChild.innerHTML='此扩展将在重启后隐藏'; lib.config.hiddenPlayPack.add('wuxing'); if(!lib.config.prompt_hidepack){ alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); game.saveConfig('prompt_hidepack',true); } } else{ this.firstChild.innerHTML='隐藏此扩展'; lib.config.hiddenPlayPack.remove('wuxing'); } game.saveConfig('hiddenPlayPack',lib.config.hiddenPlayPack); } }, }, coin:{ enable:{ name:'开启', init:false, restart:true, onclick:function(bool){ if(bool){ lib.config.plays.add('coin'); } else{ lib.config.plays.remove('coin'); } game.saveConfig('plays',lib.config.plays); } }, intro:{ name:'每完成一次对局,可获得一定数量的金币;金币可用于购买游戏特效', clear:true, nopointer:true, }, display:{ name:'金币显示', init:'text', item:{ symbol:'符号', text:'文字' }, onclick:function(item){ game.saveConfig('coin_display_playpackconfig',item); if(game.changeCoin) game.changeCoin(0); } }, canvas:{ name:'特效置顶', init:false, onclick:function(bool){ game.saveConfig('coin_canvas_playpackconfig',bool); if(bool){ ui.window.classList.add('canvas_top'); } else{ ui.window.classList.remove('canvas_top'); } } }, hide:{ name:'隐藏此扩展', clear:true, onclick:function(){ if(this.firstChild.innerHTML=='隐藏此扩展'){ this.firstChild.innerHTML='此扩展将在重启后隐藏'; lib.config.hiddenPlayPack.add('coin'); if(!lib.config.prompt_hidepack){ alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); game.saveConfig('prompt_hidepack',true); } } else{ this.firstChild.innerHTML='隐藏此扩展'; lib.config.hiddenPlayPack.remove('coin'); } game.saveConfig('hiddenPlayPack',lib.config.hiddenPlayPack); } }, }, }, mode:{ identity:{ name:'身份', connect:{ update:function(config,map){ if(config.connect_identity_mode=='zhong'){ map.connect_player_number.hide(); map.connect_limit_zhu.hide(); map.connect_enhance_zhu.hide(); map.connect_double_nei.hide(); map.connect_zhong_card.show(); map.connect_special_identity.hide(); map.connect_double_character.show(); } else if(config.connect_identity_mode=='purple'){ map.connect_player_number.hide(); map.connect_limit_zhu.hide(); map.connect_enhance_zhu.hide(); map.connect_double_nei.hide(); map.connect_zhong_card.hide(); map.connect_special_identity.hide(); map.connect_double_character.hide(); } else{ map.connect_double_character.show(); map.connect_player_number.show(); map.connect_limit_zhu.show(); map.connect_enhance_zhu.show(); if(config.connect_player_number!='2'){ map.connect_double_nei.show(); } else{ map.connect_double_nei.hide(); } map.connect_zhong_card.hide(); if(config.connect_player_number=='8'){ map.connect_special_identity.show(); } else{ map.connect_special_identity.hide(); } } }, connect_identity_mode:{ name:'游戏模式', init:'normal', item:{ normal:'标准', zhong:'明忠', purple:'3v3v2', }, restart:true, frequent:true, intro:'明忠模式和3v3v2模式详见帮助' }, connect_player_number:{ name:'游戏人数', init:'8', item:{ '2':'两人', '3':'三人', '4':'四人', '5':'五人', '6':'六人', '7':'七人', '8':'八人' }, frequent:true, restart:true, }, connect_limit_zhu:{ name:'常备主候选武将数', init:'group', restart:true, item:{ off:'不限制', group:'按势力筛选', '4':'四', '6':'六', '8':'八', }, }, connect_zhong_card:{ name:'明忠卡牌替换', init:true, frequent:true, restart:true }, connect_double_nei:{ name:'双内奸', init:false, restart:true, // frequent:true, intro:'开启后游戏中将有两个内奸(内奸胜利条件仍为主内1v1时击杀主公)' }, connect_double_character:{ name:'双将模式', init:false, frequent:true, restart:true, }, connect_change_card:{ name:'启用手气卡', init:false, frequent:true, restart:true, }, connect_special_identity:{ name:'特殊身份', init:false, restart:true, frequent:true, intro:'开启后游戏中将增加军师、大将、贼首三个身份' }, // connect_ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // connect_ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, connect_enhance_zhu:{ name:'加强主公', init:false, restart:true, intro:'为主公增加一个额外技能' }, }, config:{ update:function(config,map){ if(config.identity_mode=='zhong'){ map.player_number.hide(); map.enhance_zhu.hide(); map.double_nei.hide(); map.auto_identity.hide(); map.choice_zhu.hide(); map.limit_zhu.hide(); map.choice_zhong.hide(); map.choice_nei.hide(); map.choice_fan.hide(); map.ban_identity.hide(); map.ban_identity2.hide(); map.ban_identity3.hide(); map.zhong_card.show(); map.special_identity.hide(); map.choose_group.show(); map.change_choice.show(); map.auto_mark_identity.show(); map.double_character.show(); map.free_choose.show(); map.change_identity.show(); if(config.double_character){ map.double_hp.show(); } else{ map.double_hp.hide(); } map.continue_game.show(); } else if(config.identity_mode=='purple'){ map.player_number.hide(); map.enhance_zhu.hide(); map.double_nei.hide(); map.auto_identity.hide(); map.choice_zhu.hide(); map.limit_zhu.hide(); map.choice_zhong.hide(); map.choice_nei.hide(); map.choice_fan.hide(); map.ban_identity.hide(); map.ban_identity2.hide(); map.ban_identity3.hide(); map.zhong_card.hide(); map.special_identity.hide(); map.double_character.hide(); map.double_hp.hide(); map.choose_group.hide(); map.auto_mark_identity.hide(); map.change_choice.hide(); map.free_choose.hide(); map.change_identity.hide(); map.continue_game.hide(); } else{ map.continue_game.show(); map.player_number.show(); map.enhance_zhu.show(); map.auto_identity.show(); if(config.player_number!='2'){ map.double_nei.show(); } else{ map.double_nei.hide(); } map.choice_zhu.show(); map.limit_zhu.show(); map.choice_zhong.show(); map.choice_nei.show(); map.choice_fan.show(); map.ban_identity.show(); if(config.ban_identity=='off'){ map.ban_identity2.hide(); } else{ map.ban_identity2.show(); } if(config.ban_identity=='off'||config.ban_identity2=='off'){ map.ban_identity3.hide(); } else{ map.ban_identity3.show(); } map.zhong_card.hide(); map.choose_group.show(); map.auto_mark_identity.show(); map.change_choice.show(); map.free_choose.show(); map.change_identity.show(); if(config.player_number=='8'){ map.special_identity.show(); } else{ map.special_identity.hide(); } map.double_character.show(); if(config.double_character){ map.double_hp.show(); } else{ map.double_hp.hide(); } } }, identity_mode:{ name:'游戏模式', init:'normal', item:{ normal:'标准', zhong:'明忠', purple:'3v3v2', }, restart:true, frequent:true, intro:'明忠模式详见帮助' }, player_number:{ name:'游戏人数', init:'8', item:{ '2':'两人', '3':'三人', '4':'四人', '5':'五人', '6':'六人', '7':'七人', '8':'八人' }, frequent:true, restart:true, }, double_nei:{ name:'双内奸', init:false, restart:true, frequent:true, intro:'开启后游戏中将有两个内奸(内奸胜利条件仍为主内1v1时击杀主公)' }, choose_group:{ name:'神武将选择势力', init:true, restart:true, frequent:true, intro:'若开启此选项,选择神武将的玩家需在亮出自己的武将牌之前为自己选择一个势力。' }, nei_fullscreenpop:{ name:'主内单挑特效', intro:'在进入主内单挑时,弹出全屏文字特效', init:true, unfrequent:true, }, double_character:{ name:'双将模式', init:false, frequent:true, restart:true, }, special_identity:{ name:'特殊身份', init:false, restart:true, frequent:true, intro:'开启后游戏中将增加军师、大将、贼首三个身份' }, zhong_card:{ name:'明忠卡牌替换', init:true, frequent:true, restart:true }, double_hp:{ name:'双将体力上限', init:'pingjun', item:{ hejiansan:'和减三', pingjun:'平均值', zuidazhi:'最大值', zuixiaozhi:'最小值', zonghe:'相加', }, restart:true, }, auto_identity:{ name:'自动显示身份', item:{ off:'关闭', one:'一轮', two:'两轮', three:'三轮', always:'始终' }, init:'off', onclick:function(bool){ game.saveConfig('auto_identity',bool,this._link.config.mode); if(get.config('identity_mode')=='zhong') return; var num; switch(bool){ case '一轮':num=1;break; case '两轮':num=2;break; case '三轮':num=3;break; default:num=0;break; } if(num&!_status.identityShown&&game.phaseNumber>game.players.length*num&&game.showIdentity){ _status.identityShown=true; game.showIdentity(false); } }, intro:'游戏进行若干轮将自动显示所有角色的身份', }, auto_mark_identity:{ name:'自动标记身份', init:true, intro:'根据角色的出牌行为自动标记可能的身份', }, // ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, enhance_zhu:{ name:'加强主公', init:false, restart:true, intro:'为主公增加一个额外技能' }, free_choose:{ name:'自由选将', init:true, onclick:function(bool){ game.saveConfig('free_choose',bool,this._link.config.mode); if(get.mode()!=this._link.config.mode||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat2&&get.config('free_choose')) ui.create.cheat2(); else if(ui.cheat2&&!get.config('free_choose')){ ui.cheat2.close(); delete ui.cheat2; } } }, change_identity:{ name:'自由选择身份和座位', init:true, onclick:function(bool){ game.saveConfig('change_identity',bool,this._link.config.mode); if(get.mode()!='identity'||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; var dialog; if(ui.cheat2&&ui.cheat2.backup) dialog=ui.cheat2.backup; else dialog=_status.event.dialog; if(!_status.brawl||!_status.brawl.noAddSetting){ if(!dialog.querySelector('table')&&get.config('change_identity')) _status.event.getParent().addSetting(dialog); else _status.event.getParent().removeSetting(dialog); } ui.update(); } }, change_choice:{ name:'开启换将卡', init:true, onclick:function(bool){ game.saveConfig('change_choice',bool,this._link.config.mode); if(get.mode()!='identity'||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat&&get.config('change_choice')) ui.create.cheat(); else if(ui.cheat&&!get.config('change_choice')){ ui.cheat.close(); delete ui.cheat; } } }, change_card:{ name:'开启手气卡', init:'disabled', item:{ disabled:'禁用', once:'一次', twice:'两次', unlimited:'无限', }, }, continue_game:{ name:'显示再战', init:false, onclick:function(bool){ game.saveConfig('continue_game',bool,this._link.config.mode); if(get.config('continue_game')&&get.mode()=='identity'){ if(!ui.continue_game&&_status.over&&!_status.brawl&&!game.no_continue_game){ ui.continue_game=ui.create.control('再战',game.reloadCurrent); } } else if(ui.continue_game){ ui.continue_game.close(); delete ui.continue_game; } }, intro:'游戏结束后可选择用相同的武将再进行一局游戏' }, dierestart:{ name:'死亡后显示重来', init:true, onclick:function(bool){ game.saveConfig('dierestart',bool,this._link.config.mode); if(get.config('dierestart')&&get.mode()=='identity'){ if(!ui.restart&&game.me.isDead()&&!_status.connectMode){ ui.restart=ui.create.control('restart',game.reload); } } else if(ui.restart){ ui.restart.close(); delete ui.restart; } } }, revive:{ name:'死亡后显示复活', init:false, onclick:function(bool){ game.saveConfig('revive',bool,this._link.config.mode); if(get.config('revive')&&get.mode()=='identity'){ if(!ui.revive&&game.me.isDead()){ ui.revive=ui.create.control('revive',ui.click.dierevive); } } else if(ui.revive){ ui.revive.close(); delete ui.revive; } } }, ban_identity:{ name:'屏蔽身份', init:'off', item:{ off:'关闭', zhu:'主公', zhong:'忠臣', nei:'内奸', fan:'反贼', }, }, ban_identity2:{ name:'屏蔽身份2', init:'off', item:{ off:'关闭', zhu:'主公', zhong:'忠臣', nei:'内奸', fan:'反贼', }, }, ban_identity3:{ name:'屏蔽身份3', init:'off', item:{ off:'关闭', zhu:'主公', zhong:'忠臣', nei:'内奸', fan:'反贼', }, }, ai_strategy:{ name:'内奸策略', init:'ai_strategy_1', item:{ ai_strategy_1:'均衡', ai_strategy_2:'偏反', ai_strategy_3:'偏忠', ai_strategy_4:'酱油', ai_strategy_5:'天使', ai_strategy_6:'仇主', }, intro:'设置内奸对主忠反的态度' }, difficulty:{ name:'AI对人类态度', init:'normal', item:{ easy:'友好', normal:'一般', hard:'仇视', }, }, choice_zhu:{ name:'主公候选武将数', init:'3', restart:true, item:{ '3':'三', '4':'四', '5':'五', '6':'六', '8':'八', '10':'十', }, }, limit_zhu:{ name:'常备主候选武将数', init:'group', restart:true, item:{ off:'不限制', group:'按势力筛选', '4':'四', '6':'六', '8':'八', }, }, choice_zhong:{ name:'忠臣候选武将数', init:'4', restart:true, item:{ '3':'三', '4':'四', '5':'五', '6':'六', '8':'八', '10':'十', }, }, choice_nei:{ name:'内奸候选武将数', init:'5', restart:true, item:{ '3':'三', '4':'四', '5':'五', '6':'六', '8':'八', '10':'十', }, }, choice_fan:{ name:'反贼候选武将数', init:'3', restart:true, item:{ '3':'三', '4':'四', '5':'五', '6':'六', '8':'八', '10':'十', }, }, } }, guozhan:{ name:'国战', connect:{ connect_guozhan_mode:{ name:'游戏模式', init:'normal', item:{ normal:'势备', yingbian:'应变', old:'怀旧', }, frequent:true, restart:true, intro:'<li>势备:默认模式,使用线下《君临天下·势备篇》的牌堆进行游戏。<br><li>应变:使用OL的应变国战牌堆进行游戏。<br><li>怀旧:使用传统国战的牌堆进行游戏。', }, connect_player_number:{ name:'游戏人数', init:'8', item:{ '3':'三人', '4':'四人', '5':'五人', '6':'六人', '7':'七人', '8':'八人' }, frequent:true, restart:true, }, connect_initshow_draw:{ name:'首亮奖励', item:{ 'off':'关闭', 'draw':'摸牌', 'mark':'标记', }, init:'mark', frequent:true, intro:'第一个明置武将牌的角色可获得首亮奖励' }, connect_aozhan:{ name:'鏖战模式', init:true, intro:'若开启此选项,则将在游戏中引入“鏖战模式”的规则:<br>当游戏中仅剩四名或更少角色时(七人以下游戏时改为三名或更少),若此时全场没有超过一名势力相同的角色,则从一个新的回合开始,游戏进入鏖战模式直至游戏结束。<br>◇在鏖战模式下,【桃】只能当做【杀】或【闪】使用或打出,不能用来回复体力。<br>注:进入鏖战模式后,即使之后有两名或者更多势力相同的角色出现,仍然不会取消鏖战模式。', frequent:true, restart:true, }, connect_viewnext:{ name:'观看下家副将', init:false, intro:'若开启此选项,所有的玩家将在挑选武将后,分发起始手牌之前,分别观看自己下家的副将。', }, connect_zhulian:{ name:'珠联璧合', init:true, // frequent:true, intro:'主将和副将都明置后,若为特定组合,可获得【珠联璧合】标记' }, connect_junzhu:{ name:'替换君主', init:true, // frequent:true, restart:true, intro:'若开启此选项,玩家的第一个回合开始时,若其主武将牌有对应的君主武将牌,则其可以将此武将牌替换为对应的君主武将牌,然后重新调整体力上限。若玩家的体力上限因此增大,则玩家回复等量的体力。' }, connect_change_card:{ name:'启用手气卡', init:false, frequent:true, restart:true, }, // connect_ban_weak:{ // name:'屏蔽弱将', // init:false, // restart:true, // }, // connect_ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, }, config:{ update:function(config,map){ if(config.onlyguozhan){ map.junzhu.show(); } else{ map.junzhu.hide(); } ui.aozhan_bgm=map.aozhan_bgm; map.aozhan_bgm._link.config.updatex.call(map.aozhan_bgm,[]); }, guozhan_mode:{ name:'游戏模式', init:'normal', item:{ normal:'势备', yingbian:'应变', old:'怀旧', free:'自由', }, frequent:true, restart:true, intro:'<li>势备:默认模式,使用线下《君临天下·势备篇》的牌堆进行游戏。<br><li>应变:使用OL的应变国战牌堆进行游戏。<br><li>怀旧:使用传统国战的牌堆进行游戏。<br><li>自由:使用玩家的自定义牌堆进行游戏。', }, player_number:{ name:'游戏人数', init:'8', item:{ '3':'三人', '4':'四人', '5':'五人', '6':'六人', '7':'七人', '8':'八人' }, frequent:true, restart:true, }, initshow_draw:{ name:'首亮奖励', item:{ 'off':'关闭', 'draw':'摸牌', 'mark':'标记', }, init:'mark', frequent:true, intro:'第一个明置身份牌的角色可获得摸牌奖励' }, aozhan:{ name:'鏖战模式', init:true, frequent:true, restart:true, intro:'若开启此选项,则将在游戏中引入“鏖战模式”的规则:<br>当游戏中仅剩四名或更少角色时(七人以下游戏时改为三名或更少),若此时全场没有超过一名势力相同的角色,则从一个新的回合开始,游戏进入鏖战模式直至游戏结束。<br>◇在鏖战模式下,【桃】只能当做【杀】或【闪】使用或打出,不能用来回复体力。<br>注:进入鏖战模式后,即使之后有两名或者更多势力相同的角色出现,仍然不会取消鏖战模式。', }, viewnext:{ name:'观看下家副将', init:false, intro:'若开启此选项,所有的玩家将在挑选武将后,分发起始手牌之前,分别观看自己下家的副将。', }, aozhan_bgm:{ updatex:function(){ this.lastChild.innerHTML=this._link.config.item[lib.config.mode_config.guozhan.aozhan_bgm]; if(!Array.isArray(_status.aozhanBGMToRemove)) return; const menu=this._link.menu; for(let i=0;i<menu.childElementCount;i++){ const link=menu.childNodes[i]._link; if(['disabled','random'].includes(link)||!_status.aozhanBGMToRemove.includes(link)) continue; _status.aozhanBGMToRemove.remove(link); menu.childNodes[i].delete(); } }, name:'鏖战背景音乐', item:{ disabled:'不启用', online:'Online', rewrite:'Rewrite', chaoming:'潮鸣', random:'随机播放', }, init:'rewrite', onclick:function(item){ game.saveConfig('aozhan_bgm',item,this._link.config.mode); if(_status._aozhan==true) game.playBackgroundMusic(); }, }, zhulian:{ name:'珠联璧合', init:true, // frequent:true, intro:'主将和副将都明置后,若为特定组合,可获得【珠联璧合】标记' }, changeViceType:{ name:'副将变更方式', init:'default', item:{ default:'发现式', online:'随机式', }, frequent:true, restart:true, }, onlyguozhan:{ name:'使用国战武将', init:true, frequent:true, restart:true, intro:'开启武将技能将替换为国战版本并禁用非国战武将' }, guozhanSkin:{ name:'使用国战皮肤', init:true, frequent:true, restart:true, intro:'开启此选项后,将会把有国战专属皮肤的武将替换为国战皮肤' }, junzhu:{ name:'替换君主', init:true, // frequent:true, restart:true, intro:'若开启此选项,玩家的第一个回合开始时,若其主武将牌有对应的君主武将牌,则其可以将此武将牌替换为对应的君主武将牌,然后重新调整体力上限。若玩家的体力上限因此增大,则玩家回复等量的体力。' }, double_hp:{ name:'双将体力上限', init:'pingjun', item:{ hejiansan:'和减三', pingjun:'平均值', zuidazhi:'最大值', zuixiaozhi:'最小值', zonghe:'相加', }, restart:true, }, // ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, free_choose:{ name:'自由选将', init:true, onclick:function(bool){ game.saveConfig('free_choose',bool,this._link.config.mode); if(get.mode()!=this._link.config.mode||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat2&&get.config('free_choose')) ui.create.cheat2(); else if(ui.cheat2&&!get.config('free_choose')){ ui.cheat2.close(); delete ui.cheat2; } } }, onlyguozhanexpand:{ name:'默认展开自由选将', init:false, restart:true, intro:'开启后自由选将对话框将默认显示全部武将' }, change_identity:{ name:'自由选择座位', init:true, onclick:function(bool){ game.saveConfig('change_identity',bool,this._link.config.mode); if(get.mode()!='guozhan'||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; var dialog; if(ui.cheat2&&ui.cheat2.backup) dialog=ui.cheat2.backup; else dialog=_status.event.dialog; if(!_status.brawl||!_status.brawl.noAddSetting){ if(!dialog.querySelector('table')&&get.config('change_identity')) _status.event.getParent().addSetting(dialog); else _status.event.getParent().removeSetting(dialog); } ui.update(); } }, change_choice:{ name:'开启换将卡', init:true, onclick:function(bool){ game.saveConfig('change_choice',bool,this._link.config.mode); if(get.mode()!='guozhan'||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat&&get.config('change_choice')) ui.create.cheat(); else if(ui.cheat&&!get.config('change_choice')){ ui.cheat.close(); delete ui.cheat; } } }, change_card:{ name:'开启手气卡', init:'disabled', item:{ disabled:'禁用', once:'一次', twice:'两次', unlimited:'无限', } }, continue_game:{ name:'显示再战', init:true, intro:'游戏结束后可选择用相同的武将再进行一局游戏', onclick:function(bool){ game.saveConfig('continue_game',bool,this._link.config.mode); if(get.config('continue_game')&&get.mode()=='guozhan'){ if(!ui.continue_game&&_status.over&&!_status.brawl&&!game.no_continue_game){ ui.continue_game=ui.create.control('再战',game.reloadCurrent); } } else if(ui.continue_game){ ui.continue_game.close(); delete ui.continue_game; } } }, dierestart:{ name:'死亡后显示重来', init:true, onclick:function(bool){ game.saveConfig('dierestart',bool,this._link.config.mode); if(get.config('dierestart')&&get.mode()=='guozhan'){ if(!ui.restart&&game.me.isDead()&&!_status.connectMode){ ui.restart=ui.create.control('restart',game.reload); } } else if(ui.restart){ ui.restart.close(); delete ui.restart; } } }, revive:{ name:'死亡后显示复活', init:false, onclick:function(bool){ game.saveConfig('revive',bool,this._link.config.mode); if(get.config('revive')&&get.mode()=='guozhan'){ if(!ui.revive&&game.me.isDead()){ ui.revive=ui.create.control('revive',ui.click.dierevive); } } else if(ui.revive){ ui.revive.close(); delete ui.revive; } } }, difficulty:{ name:'AI对人类态度', init:'normal', item:{ easy:'友好', normal:'一般', hard:'仇视', } }, choice_num:{ name:'候选武将数', init:'7', restart:true, item:{ '5':'五', '6':'六', '7':'七', '8':'八', '9':'九', '10':'十', } }, } }, versus:{ name:'对决', connect:{ update:function(config,map){ if(config.connect_versus_mode=='1v1'){ map.connect_choice_num.show(); map.connect_replace_number.show(); } else{ map.connect_choice_num.hide(); map.connect_replace_number.hide(); } if(config.connect_versus_mode=='2v2'||config.connect_versus_mode=='3v3'){ map.connect_replace_handcard.show(); } else{ map.connect_replace_handcard.hide(); } }, connect_versus_mode:{ name:'游戏模式', init:'1v1', item:{ '1v1':'1v1', '2v2':'2v2', '3v3':'3v3', '4v4':'4v4', 'guandu':'官渡', }, frequent:true }, connect_replace_handcard:{ name:'四号位保护', init:true, frequent:true, intro:'最后行动的角色起始手牌数+1' }, connect_choice_num:{ name:'侯选武将数', init:'20', frequent:true, item:{ '12':'12人', '16':'16人', '20':'20人', '24':'24人', '40':'40人', } }, connect_replace_number:{ name:'替补人数', init:'2', frequent:true, item:{ '0':'无', '1':'1人', '2':'2人', '3':'3人', '4':'4人', '5':'5人', } }, // connect_ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // connect_ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, }, config:{ update:function(config,map){ if(config.versus_mode=='four'){ map.change_choice.hide(); map.ladder.show(); if(config.ladder){ map.ladder_monthly.show(); map.ladder_reset.show(); } else{ map.ladder_monthly.hide(); map.ladder_reset.hide(); } map.enable_all.show(); map.enable_all_cards_four.show(); map.four_assign.show(); map.four_phaseswap.show(); map.expand_dialog.show(); map.fouralign.show(); map.edit_character_four.show(); map.reset_character_four.show(); } else{ map.change_choice.show(); map.ladder.hide(); map.ladder_monthly.hide(); map.ladder_reset.hide(); map.enable_all.hide(); map.enable_all_cards_four.hide(); map.four_assign.hide(); map.four_phaseswap.hide(); map.expand_dialog.hide(); map.fouralign.hide(); map.edit_character_four.hide(); map.reset_character_four.hide(); } if(config.versus_mode=='three'){ map.edit_character_three.show(); map.reset_character_three.show(); } else{ map.edit_character_three.hide(); map.reset_character_three.hide(); } if(config.versus_mode=='three'||config.versus_mode=='one'){ map.enable_all_three.show(); map.enable_all_cards.show(); } else{ map.enable_all_three.hide(); map.enable_all_cards.hide(); } if(config.versus_mode=='jiange'||config.versus_mode=='two'||config.versus_mode=='endless'|| config.versus_mode=='three'||config.versus_mode=='one'||config.versus_mode=='siguo'){ map.free_choose.show(); } else{ map.free_choose.hide(); } if(config.versus_mode=='jiange'){ map.double_character_jiange.show(); } else{ map.double_character_jiange.hide(); } if(config.versus_mode=='two'){ map.replace_handcard_two.show(); map.replace_character_two.show(); map.two_assign.show(); map.two_phaseswap.show(); } else{ map.replace_handcard_two.hide(); map.replace_character_two.hide(); map.two_assign.hide(); map.two_phaseswap.hide(); } if(config.versus_mode=='two'||config.versus_mode=='siguo'||config.versus_mode=='four'){ if(config.versus_mode=='four'&&(config.four_assign||config.four_phaseswap)){ map.change_identity.hide(); } else{ map.change_identity.show(); } } else{ map.change_identity.hide(); } if(config.versus_mode=='siguo'){ map.siguo_character.show(); } else{ map.siguo_character.hide(); } }, versus_mode:{ name:'游戏模式', init:'four', item:{ four:'对抗', three:'统率', two:'欢乐', guandu:'官渡', jiange:'剑阁', siguo:'四国', standard:'自由' // endless:'无尽', // triple:'血战', // one:'<span style="display:inline-block;width:100%;text-align:center">1v1</span>', }, restart:true, frequent:true, }, ladder:{ name:'天梯模式', init:true, frequent:true, restart:true }, ladder_monthly:{ name:'每月重置天梯', init:true, frequent:true, }, enable_all:{ name:'启用全部武将', init:false, frequent:true, restart:true, }, enable_all_cards_four:{ name:'启用全部卡牌', init:false, frequent:true, restart:true, }, enable_all_three:{ name:'启用全部武将', init:false, frequent:true, restart:true, }, enable_all_cards:{ name:'启用全部卡牌', init:false, frequent:true, restart:true, }, four_assign:{ name:'代替队友选将', init:false, restart:true, }, four_phaseswap:{ name:'代替队友行动', init:false, restart:true, }, two_assign:{ name:'代替队友选将', init:false, restart:true, }, two_phaseswap:{ name:'代替队友行动', init:false, restart:true, }, free_choose:{ name:'自由选将', init:true, frequent:true, onclick:function(bool){ game.saveConfig('free_choose',bool,this._link.config.mode); if(!ui.create.cheat2) return; if(get.mode()!=this._link.config.mode||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat2&&get.config('free_choose')) ui.create.cheat2(); else if(ui.cheat2&&!get.config('free_choose')){ ui.cheat2.close(); delete ui.cheat2; } } }, fouralign:{ name:'自由选择阵型', init:false }, change_identity:{ name:'自由选择座位', init:true, onclick:function(bool){ game.saveConfig('change_identity',bool,this._link.config.mode); if(!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(_status.mode=='four'){ if(get.config('four_assign')||get.config('four_phaseswap')) return; if(bool){ if(_status.event.parent.addSetting){ _status.event.parent.addSetting(); } } else{ var seats=_status.event.parent.seatsbutton; if(seats){ while(seats.length){ seats.shift().remove(); } delete _status.event.parent.seatsbutton; } } } else{ var dialog; if(ui.cheat2&&ui.cheat2.backup) dialog=ui.cheat2.backup; else dialog=_status.event.dialog; if(!_status.brawl||!_status.brawl.noAddSetting){ if(!dialog.querySelector('table')&&get.config('change_identity')) _status.event.getParent().addSetting(dialog); else _status.event.getParent().removeSetting(dialog); } ui.update(); } } }, change_choice:{ name:'开启换将卡', init:true, onclick:function(bool){ game.saveConfig('change_choice',bool,this._link.config.mode); if(!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat&&get.config('change_choice')) ui.create.cheat(); else if(ui.cheat&&!get.config('change_choice')){ ui.cheat.close(); delete ui.cheat; } }, frequent:true, }, double_character_jiange:{ name:'双将模式', init:false, frequent:true, }, replace_handcard_two:{ name:'四号位保护', init:true, frequent:true, intro:'最后行动的角色起始手牌+1' }, replace_character_two:{ name:'替补模式', init:false, frequent:true, intro:'每个额外选择一名武将,死亡后用该武将代替重新上场,替补武将用完时失败' }, expand_dialog:{ name:'默认展开选将框', intro:'选将框打开时直接显示全部武将(可能使游戏在开始时卡顿)', init:false, }, siguo_character:{ name:'专属武将出场率', init:'increase', item:{ increase:'大概率', normal:'默认概率', off:'不出现', }, frequent:true }, // ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true // }, ladder_reset:{ name:'重置天梯数据', onclick:function(){ var node=this; if(node._clearing){ game.save('ladder',{ current:900, top:900, month:(new Date()).getMonth() }); ui.ladder.innerHTML='卫士五'; clearTimeout(node._clearing); node.firstChild.innerHTML='重置天梯数据'; delete node._clearing; return; } node.firstChild.innerHTML='单击以确认 (3)'; node._clearing=setTimeout(function(){ node.firstChild.innerHTML='单击以确认 (2)'; node._clearing=setTimeout(function(){ node.firstChild.innerHTML='单击以确认 (1)'; node._clearing=setTimeout(function(){ node.firstChild.innerHTML='重置天梯数据'; delete node._clearing; },1000); },1000); },1000); }, clear:true, }, edit_character_three:{ name:'编辑统率将池', clear:true, onclick:function(){ if(get.mode()!='versus'){ alert('请进入对决模式,然后再编辑将池'); return; } var container=ui.create.div('.popup-container.editor'); var node=container; var map=get.config('character_three')||lib.choiceThree; var str='character=[\n '; for(var i=0;i<map.length;i++){ str+='"'+map[i]+'",'; if(i+1<map.length&&(i+1)%5==0) str+='\n '; } str+='\n];'; node.code=str; ui.window.classList.add('shortcutpaused'); ui.window.classList.add('systempaused'); var saveInput=function(){ var code; if(container.editor){ code=container.editor.getValue(); } else if(container.textarea){ code=container.textarea.value; } try{ var character=null; eval(code); if(!Array.isArray(character)){ throw('err'); } } catch(e){ var tip=lib.getErrorTip(e)||''; alert('代码语法有错误,请仔细检查(' + e + ')' + tip); window.focus(); if(container.editor){ container.editor.focus(); } else if(container.textarea){ container.textarea.focus(); } return; } game.saveConfig('character_three',character,'versus'); ui.window.classList.remove('shortcutpaused'); ui.window.classList.remove('systempaused'); container.delete(); container.code=code; delete window.saveNonameInput; }; window.saveNonameInput=saveInput; var editor=ui.create.editor(container,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){ lib.init.js(lib.assetURL+'game','codemirror',()=>lib.codeMirrorReady(node,editor)); lib.init.css(lib.assetURL+'layout/default','codemirror'); } else{ lib.codeMirrorReady(node,editor); } }; }, }, reset_character_three:{ name:'重置统率将池', intro:'将统率三军模式下的将池重置为默认将池', clear:true, onclick:function(){ if(confirm('该操作不可撤销!是否清除统率三军模式的自定义将池,并将其重置为默认将池?')){ game.saveConfig('character_three',null,'versus'); alert('将池已重置'); } }, }, edit_character_four:{ name:'编辑4v4将池', clear:true, onclick:function(){ if(get.mode()!='versus'){ alert('请进入对决模式,然后再编辑将池'); return; } var container=ui.create.div('.popup-container.editor'); var node=container; var map=get.config('character_four')||lib.choiceFour; var str='character=[\n '; for(var i=0;i<map.length;i++){ str+='"'+map[i]+'",'; if(i+1<map.length&&(i+1)%5==0) str+='\n '; } str+='\n];'; node.code=str; ui.window.classList.add('shortcutpaused'); ui.window.classList.add('systempaused'); var saveInput=function(){ var code; if(container.editor){ code=container.editor.getValue(); } else if(container.textarea){ code=container.textarea.value; } try{ var character=null; eval(code); if(!Array.isArray(character)){ throw('err'); } } catch(e){ var tip=lib.getErrorTip(e)||''; alert('代码语法有错误,请仔细检查('+e+')'+tip); window.focus(); if(container.editor){ container.editor.focus(); } else if(container.textarea){ container.textarea.focus(); } return; } game.saveConfig('character_four',character,'versus'); ui.window.classList.remove('shortcutpaused'); ui.window.classList.remove('systempaused'); container.delete(); container.code=code; delete window.saveNonameInput; }; window.saveNonameInput=saveInput; var editor=ui.create.editor(container,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){ lib.init.js(lib.assetURL+'game','codemirror',()=>lib.codeMirrorReady(node,editor)); lib.init.css(lib.assetURL+'layout/default','codemirror'); } else{ lib.codeMirrorReady(node,editor); } }; }, }, reset_character_four:{ name:'重置4v4将池', intro:'将4v4模式下的将池重置为默认将池', clear:true, onclick:function(){ if(confirm('该操作不可撤销!是否清除4v4模式的自定义将池,并将其重置为默认将池?')){ game.saveConfig('character_four',null,'versus'); alert('将池已重置'); } }, }, } }, connect:{ name:'联机', config:{ connect_nickname:{ name:'联机昵称', input:true, frequent:true, }, connect_avatar:{ name:'联机头像', init:'caocao', item:{}, frequent:true, onclick:function(item){ game.saveConfig('connect_avatar',item); game.saveConfig('connect_avatar',item,'connect'); } }, hall_ip:{ name:'联机大厅', input:true, frequent:true, }, hall_button:{ name:'联机大厅按钮', init:true, frequent:true, onclick:function(bool){ game.saveConfig('hall_button',bool,'connect'); if(ui.hall_button){ if(bool){ ui.hall_button.style.display=''; } else{ ui.hall_button.style.display='none'; } } } }, wss_mode:{ name:'使用WSS协议', init:false, frequent:true, intro:'在用户填写的IP地址没有直接指定使用WS/WSS协议的情况下,默认使用WSS协议,而非WS协议来连接到联机服务器。<br>请不要轻易勾选此项!', }, } }, boss:{ name:'挑战', config:{ free_choose:{ name:'自由选将', init:true, frequent:true, onclick:function(bool){ game.saveConfig('free_choose',bool,this._link.config.mode); if(get.mode()!=this._link.config.mode||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat2&&get.config('free_choose')) ui.create.cheat2(); else if(ui.cheat2&&!get.config('free_choose')){ ui.cheat2.close(); delete ui.cheat2; } } }, change_choice:{ name:'开启换将卡', init:true, onclick:function(bool){ game.saveConfig('change_choice',bool,this._link.config.mode); if(!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat&&get.config('change_choice')) ui.create.cheat(); else if(ui.cheat&&!get.config('change_choice')){ ui.cheat.close(); delete ui.cheat; } }, frequent:true, }, single_control:{ name:'单人控制', init:true, frequent:true, onclick:function(bool){ game.saveConfig('single_control',bool,this._link.config.mode); if(ui.single_swap&&game.me!=game.boss){ if(bool){ ui.single_swap.style.display='none'; } else{ ui.single_swap.style.display=''; } } }, intro:'只控制一名角色,其他角色由AI控制' }, // ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, } }, doudizhu:{ name:'斗地主', connect:{ update:function(config,map){ if(config.connect_doudizhu_mode=='online'){ map.connect_change_card.hide(); } else{ map.connect_change_card.show(); } if(config.connect_doudizhu_mode!='normal'){ map.connect_double_character.hide(); } else{ map.connect_double_character.show(); } }, connect_doudizhu_mode:{ name:'游戏模式', init:'normal', item:{ normal:'休闲', kaihei:'开黑', huanle:'欢乐', binglin:'兵临', online:'智斗', }, restart:true, frequent:true, }, connect_double_character:{ name:'双将模式', init:false, frequent:true, restart:true, }, connect_change_card:{ name:'启用手气卡', init:false, frequent:true, restart:true, }, }, config:{ update:function(config,map){ if(config.doudizhu_mode=='online'){ map.change_card.hide(); map.edit_character.show(); map.reset_character.show(); } else{ map.change_card.show(); map.edit_character.hide(); map.reset_character.hide(); } if(config.doudizhu_mode!='normal'){ map.double_character.hide(); map.free_choose.hide(); map.change_identity.hide(); map.change_choice.hide(); map.continue_game.hide(); map.dierestart.hide(); map.choice_zhu.hide(); map.choice_fan.hide(); map.revive.hide(); } else{ map.double_character.show(); map.free_choose.show(); map.change_identity.show(); map.change_choice.show(); map.continue_game.show(); map.dierestart.show(); map.choice_zhu.show(); map.choice_fan.show(); map.revive.show(); } if(config.double_character&&config.doudizhu_mode=='normal'){ map.double_hp.show(); } else{ map.double_hp.hide(); } }, doudizhu_mode:{ name:'游戏模式', init:'normal', item:{ normal:'休闲', kaihei:'开黑', huanle:'欢乐', binglin:'兵临', online:'智斗', }, restart:true, frequent:true, }, double_character:{ name:'双将模式', init:false, frequent:true, restart:true, }, double_hp:{ name:'双将体力上限', init:'pingjun', item:{ hejiansan:'和减三', pingjun:'平均值', zuidazhi:'最大值', zuixiaozhi:'最小值', zonghe:'相加', }, restart:true, }, free_choose:{ name:'自由选将', init:true, onclick:function(bool){ game.saveConfig('free_choose',bool,this._link.config.mode); if(get.mode()!=this._link.config.mode||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat2&&get.config('free_choose')) ui.create.cheat2(); else if(ui.cheat2&&!get.config('free_choose')){ ui.cheat2.close(); delete ui.cheat2; } } }, change_identity:{ name:'自由选择身份和座位', init:true, onclick:function(bool){ game.saveConfig('change_identity',bool,this._link.config.mode); if(!_status.event.getParent().showConfig&&!_status.event.showConfig) return; var dialog; if(ui.cheat2&&ui.cheat2.backup) dialog=ui.cheat2.backup; else dialog=_status.event.dialog; if(!_status.brawl||!_status.brawl.noAddSetting){ if(!dialog.querySelector('table')&&get.config('change_identity')) _status.event.getParent().addSetting(dialog); else _status.event.getParent().removeSetting(dialog); } ui.update(); } }, change_choice:{ name:'开启换将卡', init:true, onclick:function(bool){ game.saveConfig('change_choice',bool,this._link.config.mode); if(!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat&&get.config('change_choice')) ui.create.cheat(); else if(ui.cheat&&!get.config('change_choice')){ ui.cheat.close(); delete ui.cheat; } } }, change_card:{ name:'开启手气卡', init:'disabled', item:{ disabled:'禁用', once:'一次', twice:'两次', unlimited:'无限', }, }, continue_game:{ name:'显示再战', init:false, onclick:function(bool){ game.saveConfig('continue_game',bool,this._link.config.mode); if(get.config('continue_game')){ if(!ui.continue_game&&_status.over&&!_status.brawl&&!game.no_continue_game){ ui.continue_game=ui.create.control('再战',game.reloadCurrent); } } else if(ui.continue_game){ ui.continue_game.close(); delete ui.continue_game; } }, intro:'游戏结束后可选择用相同的武将再进行一局游戏' }, dierestart:{ name:'死亡后显示重来', init:true, onclick:function(bool){ game.saveConfig('dierestart',bool,this._link.config.mode); if(get.config('dierestart')){ if(!ui.restart&&game.me.isDead()&&!_status.connectMode){ ui.restart=ui.create.control('restart',game.reload); } } else if(ui.restart){ ui.restart.close(); delete ui.restart; } } }, revive:{ name:'死亡后显示复活', init:false, onclick:function(bool){ game.saveConfig('revive',bool,this._link.config.mode); if(get.config('revive')){ if(!ui.revive&&game.me.isDead()){ ui.revive=ui.create.control('revive',ui.click.dierevive); } } else if(ui.revive){ ui.revive.close(); delete ui.revive; } } }, choice_zhu:{ name:'地主候选武将数', init:'3', restart:true, item:{ '3':'三', '4':'四', '5':'五', '6':'六', '8':'八', '10':'十', }, }, choice_fan:{ name:'农民候选武将数', init:'3', restart:true, item:{ '3':'三', '4':'四', '5':'五', '6':'六', '8':'八', '10':'十', }, }, edit_character:{ name:'编辑将池', clear:true, onclick:function(){ if(get.mode()!='doudizhu'){ alert('请进入斗地主模式,然后再编辑将池'); return; } var container=ui.create.div('.popup-container.editor'); var node=container; var map=get.config('character_online')||lib.characterOnline; node.code='character='+get.stringify(map)+'\n/*\n 这里是智斗三国模式的武将将池。\n 您可以在这里编辑对武将将池进行编辑,然后点击“保存”按钮即可保存。\n 将池中的Key势力武将,仅同时在没有被禁用的情况下,才会出现在选将框中。\n 而非Key势力的武将,只要所在的武将包没有被隐藏,即可出现在选将框中。\n 该将池为单机模式/联机模式通用将池。在这里编辑后,即使进入联机模式,也依然会生效。\n 但联机模式本身禁用的武将(如神貂蝉)不会出现在联机模式的选将框中。\n*/'; ui.window.classList.add('shortcutpaused'); ui.window.classList.add('systempaused'); var saveInput=function(){ var code; if(container.editor){ code=container.editor.getValue(); } else if(container.textarea){ code=container.textarea.value; } try{ var character=null; eval(code); if(!get.is.object(character)){ throw('err'); } var groups=[]; for(var i in character){ if(!Array.isArray(character[i])) throw('type'); if(character[i].length>=3) groups.push(i); } if(groups.length<3) throw('enough'); } catch(e){ if(e=='type'){ alert('请严格按照格式填写,不要写入不为数组的数据'); } else if(e=='enough'){ alert('请保证至少写入了3个势力,且每个势力至少有3个武将'); } else 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; } game.saveConfig('character_online',character,'doudizhu'); ui.window.classList.remove('shortcutpaused'); ui.window.classList.remove('systempaused'); container.delete(); container.code=code; delete window.saveNonameInput; }; window.saveNonameInput=saveInput; var editor=ui.create.editor(container,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){ lib.init.js(lib.assetURL+'game','codemirror',()=>lib.codeMirrorReady(node,editor)); lib.init.css(lib.assetURL+'layout/default','codemirror'); } else{ lib.codeMirrorReady(node,editor); } }; }, }, reset_character:{ name:'重置将池', intro:'将智斗三国模式下的将池重置为默认将池', clear:true, onclick:function(){ if(confirm('该操作不可撤销!是否清除智斗三国模式的自定义将池,并将其重置为默认将池?')){ game.saveConfig('character_online',null,'doudizhu'); alert('将池已重置'); } }, }, } }, single:{ name:'单挑', connect:{ connect_single_mode:{ name:'游戏模式', init:'normal', item:{ normal:'新1v1', dianjiang:'点将单挑', changban:'血战长坂坡', }, restart:true, frequent:true, }, connect_enable_jin:{ name:'启用晋势力武将', init:false, restart:true, frequent:true, }, update:function(config,map){ if(config.connect_single_mode!='normal'){ map.connect_enable_jin.hide(); } else{ map.connect_enable_jin.show(); } }, }, config:{ single_mode:{ name:'游戏模式', init:'normal', item:{ normal:'新1v1', dianjiang:'点将单挑', changban:'血战长坂坡', }, restart:true, frequent:true, }, enable_jin:{ name:'启用晋势力武将', init:false, restart:true, frequent:true, }, update:function(config,map){ if(config.single_mode!='normal'){ map.enable_jin.hide(); } else{ map.enable_jin.show(); } }, } }, chess:{ name:'战棋', config:{ chess_mode:{ name:'游戏模式', init:'combat', item:{ combat:'自由', three:'统率', leader:'君主', }, restart:true, frequent:true, }, update:function(config,map){ if(config.chess_mode=='leader'){ map.chess_leader_save.show(); map.chess_leader_clear.show(); map.chess_leader_allcharacter.show(); map.chess_character.hide(); } else{ map.chess_leader_save.hide(); map.chess_leader_clear.hide(); map.chess_leader_allcharacter.hide(); map.chess_character.show(); } if(config.chess_mode=='combat'){ // map.battle_number.show(); // map.chess_ordered.show(); map.free_choose.show(); map.change_choice.show(); } else{ // map.battle_number.hide(); // map.chess_ordered.hide(); map.free_choose.hide(); map.change_choice.hide(); } // if(config.chess_mode!='leader'){ // map.ban_weak.show(); // map.ban_strong.show(); // } // else{ // map.ban_weak.hide(); // map.ban_strong.hide(); // } }, chess_leader_save:{ name:'选择历程', init:'save1', item:{ save1:'一', save2:'二', save3:'三', save4:'四', save5:'五', }, restart:true, frequent:true, }, chess_leader_allcharacter:{ name:'启用全部角色', init:true, onclick:function(bool){ if(confirm('调整该设置将清除所有进度,是否继续?')){ for(var i=1;i<6;i++) game.save('save'+i,null,'chess'); game.saveConfig('chess_leader_allcharacter',bool,'chess') if(get.mode()=='chess') game.reload(); return; } else this.classList.toggle('on'); }, }, chess_leader_clear:{ name:'清除进度', onclick:function(){ var node=this; if(node._clearing){ for(var i=1;i<6;i++) game.save('save'+i,null,'chess'); game.reload(); return; } node._clearing=true; node.firstChild.innerHTML='单击以确认 (3)'; setTimeout(function(){ node.firstChild.innerHTML='单击以确认 (2)'; setTimeout(function(){ node.firstChild.innerHTML='单击以确认 (1)'; setTimeout(function(){ node.firstChild.innerHTML='清除进度'; delete node._clearing; },1000); },1000); },1000); }, clear:true, frequent:true, }, // chess_treasure:{ // name:'战场机关', // init:'0', // frequent:true, // item:{ // '0':'关闭', // '0.1':'较少出现', // '0.2':'偶尔出现', // '0.333':'时常出现', // '0.5':'频繁出现', // } // }, chess_obstacle:{ name:'随机路障', init:'0.2', item:{ '0':'关闭', '0.2':'少量', '0.333':'中量', '0.5':'大量', }, frequent:true, }, show_range:{ name:'显示卡牌范围', init:true, }, show_distance:{ name:'显示距离', init:true, }, chess_character:{ name:'战棋武将', init:true, frequent:true, }, chess_card:{ name:'战棋卡牌', init:true, frequent:true, }, free_choose:{ name:'自由选将', init:true, onclick:function(bool){ game.saveConfig('free_choose',bool,this._link.config.mode); if(get.mode()!=this._link.config.mode||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat2&&get.config('free_choose')) ui.create.cheat2(); else if(ui.cheat2&&!get.config('free_choose')){ ui.cheat2.close(); delete ui.cheat2; } }, }, change_choice:{ name:'开启换将卡', init:true, onclick:function(bool){ game.saveConfig('change_choice',bool,this._link.config.mode); if(!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat&&get.config('change_choice')) ui.create.cheat(); else if(ui.cheat&&!get.config('change_choice')){ ui.cheat.close(); delete ui.cheat; } }, }, // ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, chessscroll_speed:{ name:'边缘滚动速度', init:'20', intro:'鼠标移至屏幕边缘时自动滚屏', item:{ '0':'不滚动', '10':'10格/秒', '20':'20格/秒', '30':'30格/秒', } }, } }, tafang:{ name:'塔防', config:{ tafang_turn:{ name:'游戏胜利', init:'10', frequent:true, item:{ '10':'十回合', '20':'二十回合', '30':'三十回合', '1000':'无限', } }, // tafang_size:{ // name:'战场大小', // init:'9', // frequent:true, // item:{ // '6':'小', // '9':'中', // '12':'大', // } // }, tafang_difficulty:{ name:'战斗难度', init:'2', frequent:true, item:{ '1':'简单', '2':'普通', '3':'困难', } }, show_range:{ name:'显示卡牌范围', init:true, }, show_distance:{ name:'显示距离', init:true, }, // ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, chessscroll_speed:{ name:'边缘滚动速度', intro:'鼠标移至屏幕边缘时自动滚屏', init:'20', item:{ '0':'不滚动', '10':'10格/秒', '20':'20格/秒', '30':'30格/秒', } }, } }, brawl:{ name:'乱斗', config:{ huanhuazhizhan:{ name:'幻化之战', init:true, frequent:true }, qunxionggeju:{ name:'群雄割据', init:true, frequent:true }, duzhansanguo:{ name:'毒战三国', init:true, frequent:true }, daozhiyueying:{ name:'导师月英', init:true, frequent:true }, weiwoduzun:{ name:'唯我独尊', init:true, frequent:true }, tongxingzhizheng:{ name:'同姓之争', init:true, frequent:true }, jiazuzhizheng:{ name:'家族之争', init:true, frequent:true }, tongqueduopao:{ name:'铜雀夺袍', init:true, frequent:true }, tongjiangmoshi:{ name:'同将模式', init:true, frequent:true }, baiyidujiang:{ name:'白衣渡江', init:true, frequent:true }, qianlidanji:{ name:'千里单骑', init:true, frequent:true }, liangjunduilei:{ name:'两军对垒', init:true, frequent:true }, scene:{ name:'创建场景', init:true, frequent:true } } }, stone:{ name:'炉石', config:{ // update:function(config,map){ // if(config.stone_mode=='deck'){ // // map.deck_length.show(); // // map.deck_repeat.show(); // map.random_length.hide(); // map.skill_bar.show(); // } // else{ // // map.deck_length.hide(); // // map.deck_repeat.hide(); // map.random_length.show(); // map.skill_bar.hide(); // } // }, // stone_mode:{ // name:'游戏模式', // init:'deck', // item:{ // deck:'构筑', // random:'随机' // }, // restart:true, // frequent:true, // }, // deck_length:{ // name:'卡组长度', // init:'30', // item:{ // '30':'30张', // '50':'50张', // '80':'80张', // }, // frequent:true, // }, // deck_repeat:{ // name:'重复卡牌', // init:'2', // item:{ // '2':'2张', // '3':'3张', // '5':'5张', // '80':'无限', // }, // frequent:true, // }, // random_length:{ // name:'随从牌数量', // init:'1/80', // item:{ // '1/120':'少', // '1/80':'中', // '1/50':'多', // }, // frequent:true, // }, battle_number:{ name:'出场人数', init:'1', frequent:true, item:{ '1':'一人', '2':'两人', '3':'三人', '4':'四人', '6':'六人', '8':'八人', '10':'十人', }, onclick:function(num){ game.saveConfig('battle_number',num,this._link.config.mode); if(_status.connectMode) return; if(!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(_status.event.getParent().changeDialog){ _status.event.getParent().changeDialog(); } }, }, mana_mode:{ name:'行动值变化', init:'inc', item:{ inf:'涨落', inc:'递增' }, frequent:true }, skill_bar:{ name:'怒气值', init:true, frequent:true, restart:true, }, double_character:{ name:'双将模式', init:false, frequent:true, restart:function(){ return _status.event.getParent().name!='chooseCharacter'||_status.event.name!='chooseButton'; } }, free_choose:{ name:'自由选将', init:true, onclick:function(bool){ game.saveConfig('free_choose',bool,this._link.config.mode); if(_status.connectMode) return; if(get.mode()!=this._link.config.mode||!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat2&&get.config('free_choose')) ui.create.cheat2(); else if(ui.cheat2&&!get.config('free_choose')){ ui.cheat2.close(); delete ui.cheat2; } }, }, change_choice:{ name:'开启换将卡', init:true, onclick:function(bool){ game.saveConfig('change_choice',bool,this._link.config.mode); if(_status.connectMode) return; if(!_status.event.getParent().showConfig&&!_status.event.showConfig) return; if(!ui.cheat&&get.config('change_choice')) ui.create.cheat(); else if(ui.cheat&&!get.config('change_choice')){ ui.cheat.close(); delete ui.cheat; } }, }, // ban_weak:{ // name:'屏蔽弱将', // init:true, // restart:true, // }, // ban_strong:{ // name:'屏蔽强将', // init:false, // restart:true, // }, } }, }, status:{ running:false, canvas:false, time:0, reload:0, delayed:0, frameId:0, videoId:0, globalId:0, }, help:{ '关于游戏':'<div style="margin:10px">关于无名杀</div><ul style="margin-top:0"><li>无名杀官方发布地址仅有GitHub仓库!<br><a href="https://github.com/libccy/noname">点击前往Github仓库</a><br><li>无名杀基于GPLv3开源协议。<br><a href="https://www.gnu.org/licenses/gpl-3.0.html">点击查看GPLv3协议</a><br><li>其他所有的所谓“无名杀”社群(包括但不限于绝大多数“官方”QQ群、QQ频道等)均为玩家自发组织,与无名杀官方无关!', '游戏操作':'<ul><li>长按/鼠标悬停/右键单击显示信息。<li>触屏模式中,双指点击切换暂停;下划显示菜单,上划切换托管。<li>键盘快捷键<br>'+ '<table><tr><td>A<td>切换托管<tr><td>W<td>切换不询问无懈<tr><td>空格<td>暂停</table><li>编辑牌堆<br>在卡牌包中修改牌堆后,将自动创建一个临时牌堆,在所有模式中共用,当保存当前牌堆后,临时牌堆被清除。每个模式可设置不同的已保存牌堆,设置的牌堆优先级大于临时牌堆。</ul>', '游戏命令':'<div style="margin:10px">变量名</div><ul style="margin-top:0"><li>场上角色<br>game.players<li>阵亡角色<br>game.dead'+ '<li>玩家<br>game.me<li>玩家的上/下家<br>game.me.previous/next'+ '<li>玩家的上/下家(含阵亡)<br>game.me.previousSeat/<br>nextSeat'+ '<li>牌堆<br>ui.cardPile<li>弃牌堆<br>ui.discardPile</ul>'+ '<div style="margin:10px">角色属性</div><ul style="margin-top:0"><li>体力值<br>player.hp'+ '<li>体力上限<br>player.maxHp<li>身份<br>player.identity<li>手牌<br>player.getCards("h")<li>装备牌<br>player.getCards("e")<li>判定牌<br>player.getCards("j")'+ '<li>是否存活/横置/翻面<br>player.isAlive()/<br>isLinked()/<br>isTurnedOver()</ul>'+ '<div style="margin:10px">角色操作</div><ul style="margin-top:0"><li>受到伤害<br>player.damage(source,<br>num)'+ '<li>回复体力<br>player.recover(num)<li>摸牌<br>player.draw(num)<li>获得牌<br>player.gain(cards)<li>弃牌<br>player.discard(cards)'+ '<li>使用卡牌<br>player.useCard(card,<br>targets)<li>死亡<br>player.die()<li>复活<br>player.revive(hp)</ul>'+ '<div style="margin:10px">游戏操作</div><ul style="margin-top:0"><li>在命令框中输出结果<br>game.print(str)<li>清除命令框中的内容<br>cls<li>上一条/下一条输入的内容<br>up/down<li>游戏结束<br>game.over(bool)'+ '<li>角色资料<br>lib.character<li>卡牌资料<br>lib.card</ul>', '游戏名词':'<ul><li>智囊:无名杀默认为过河拆桥/无懈可击/无中生有/洞烛先机。牌堆中没有的智囊牌会被过滤。可在卡牌设置中自行增减。若没有可用的智囊,则改为随机选取的三种锦囊牌的牌名。'+ '<li>仁库:部分武将使用的游戏外共通区域。至多包含六张牌。当有新牌注入后,若牌数超过上限,则将最早进入仁库的溢出牌置入弃牌堆。'+ '<li>护甲:和体力类似,每点护甲可抵挡一点伤害,但不影响手牌上限。'+ '<li>随从:通过技能获得,拥有独立的技能、手牌区和装备区(共享判定区),出场时替代主武将的位置;随从死亡时自动切换回主武将。'+ '<li>发现:从三张随机亮出的牌中选择一张,若无特殊说明,则获得此牌。'+ '<li>蓄能技:发动时可以增大黄色的数字。若如此做,红色数字于技能的结算过程中改为原来的两倍。'+ '<li>施法:若技能的拥有者未拥有等待执行的同名“施法”效果,则其可以发动“施法”技能。其须选择声明一个数字X(X∈[1, 3]),在此之后的第X个回合结束时,其执行“施法”效果,且效果中的数字X视为与技能发动者声明的X相同。'+ '<li>共同拼点:一种特殊的拼点结算。发起者与被指定的拼点目标同时亮出拼点牌,进行一次决算:其中拼点牌点数唯一最大的角色赢,其他角色均没赢;若没有点数唯一最大的拼点牌,则所有角色拼点均没赢。'+ '<li>强令:若一名角色拥有带有“强令”的技能,则该技能的发动时机为“出牌阶段开始时”。若技能拥有者发动该技能,其须发布“强令”给一名其他角色,并在对应技能的时间节点加以判断目标角色是否成功完成该强令所要求的任务条件。成功或失败则会根据技能效果执行不同结算流程。'+ '<li>摧坚:若一名角色拥有带有“摧坚”的技能,则该技能的发动时机为“当你使用伤害牌指定第一个目标后”。你可以对其中一个目标发动“摧坚”技能,然后执行后续效果。其中,后续效果里的X等于该目标的非charlotte技能的数量。'+ '<li>妄行:一种特殊的选项。若一名角色拥有带有“妄行”的技能,则该技能触发时,你须选择声明一个数字X(X∈{1,2,3,4}),技能后续中的X即为你选择的数字。选择完毕后,你获得如下效果:回合结束时,你选择一项:1.弃置X张牌;2.减1点体力上限。'+ '<li>搏击:若一名角色拥有带有“搏击”的技能,则当该搏击技能触发时,若本次技能的目标角色在你攻击范围内,且你在其攻击范围内,则你执行技能主体效果时,同时额外执行“搏击”后的额外效果。'+ '<li>游击:若一名角色拥有带有“游击”的技能,则当该游击技能执行至“游击”处时,若本次技能的目标角色在你的攻击范围内,且你不在其攻击范围内,则你可以执行“游击”后的额外效果。'+ '<li>激昂:一名角色发动“昂扬技”标签技能后,此技能失效,直至从此刻至满足此技能“激昂”条件后。'+ '' }, path:{}, getErrorTip:msg=>{ if(typeof msg!='string'){ try{ msg=msg.toString(); if(typeof msg!='string') throw 'err'; }catch(_){ throw '传参错误:'+msg; } } if (msg.startsWith('Uncaught ')) msg=msg.slice(9); let newMessage=msg; if (/RangeError/.test(newMessage)){ if(newMessage.includes("Maximum call stack size exceeded")){ newMessage="堆栈溢出"; }else if(/argument must be between 0 and 20/.test(newMessage)){ let funName=newMessage.slice(newMessage.indexOf('RangeError: ')+12,newMessage.indexOf(')')+1); newMessage=funName+"参数必须在0和20之间"; } else { newMessage="传递错误值到数值计算方法"; } }else if(/ReferenceError/.test(newMessage)){ let messageName; if (newMessage.includes("is not defined")){ messageName=newMessage.replace('ReferenceError: ', '').replace(' is not defined', ''); newMessage="引用了一个未定义的变量:"+messageName; }else if(newMessage.includes("invalid assignment left-hand side")){ newMessage = "赋值运算符或比较运算符不匹配"; }else if(newMessage.includes("Octal literals are not allowed in strict mode")){ newMessage = "八进制字面量与八进制转义序列语法已经被废弃"; }else if(newMessage.includes("Illegal 'use strict' directive in function with non-simple parameter list")){ newMessage = "'use strict'指令不能使用在带有‘非简单参数’列表的函数"; }else if(newMessage.includes("Invalid left-hand side in assignment")){ newMessage = "赋值中的左侧无效,即number,string等不可赋值的非变量数据"; } }else if(/SyntaxError/.test(newMessage)){ let messageName; if(newMessage.includes("Unexpected token ")){ messageName=newMessage.replace('SyntaxError: Unexpected token ',''); newMessage="使用了未定义或错误的语法 : ("+messageName+")"; }else if(newMessage.includes( "Block-scoped declarations (let, const, function, class) not yet supported outside strict mode")){ newMessage="请在严格模式下运行let,const,class"; }else if(newMessage.includes("for-of loop variable declaration may not have an initializer.")){ newMessage="for...of 循环的头部包含有初始化表达式"; }else if(newMessage.includes("for-in loop variable declaration may not have an initializer.")){ newMessage="for...in 循环的头部包含有初始化表达式"; }else if(newMessage.includes("Delete of an unqualified identifier in strict mode.")){ newMessage="普通变量不能通过 delete 操作符来删除"; }else if(newMessage.includes("Unexpected identifier")){ newMessage="不合法的标识符或错误的语法"; }else if(newMessage.includes("Invalid or unexpected token")){ newMessage="非法的或者不期望出现的标记符号出现在不该出现的位置"; }else if(newMessage.includes("Invalid regular expression flags")){ newMessage="无效的正则表达式的标记"; }else if(newMessage.includes("missing ) after argument list")){ newMessage="参数列表后面缺少 \')\' (丢失运算符或者转义字符等)"; }else if(newMessage.includes("Invalid shorthand property initializer")){ newMessage="在定义一个{}对象时,应该使用\':\'而不是\'=\'"; }else if(newMessage.includes("Missing initializer in const declaration")){ newMessage="在使用const定义一个对象时,必须指定初始值"; }else if(newMessage.includes("Unexpected number")||newMessage.includes("Unexpected string")){ newMessage="在定义函数时,函数参数必须为合法标记符"; }else if(newMessage.includes("Unexpected end of input")){ newMessage="遗漏了符号或符号顺序不对(小括号,花括号等)"; }else if(newMessage.includes("has already been declared")){ messageName=newMessage.replace('SyntaxError: Identifier ', '').replace(' has already been declared', ''); newMessage=messageName +"变量已经被声明过,不能被重新声明"; }else if(newMessage.includes("Invalid or unexpected token")){ newMessage="查询无效或意外的标记,可能是字符串的引号不成对,错误使用了转义序列,字符串在多行中解析异常"; }else if(newMessage.includes("Duplicate parameter name not allowed in this context")) { newMessage="参数名不允许重复"; }else if(newMessage.includes("Unexpected reserved word")||newMessage.includes( "Unexpected strict mode reserved word")){ newMessage = "保留字被用作标记符"; } }else if(/TypeError/.test(newMessage)){ let messageName; if(newMessage.includes(" is not a function")){ messageName=newMessage.replace('TypeError: ', '').replace(' is not a function', ''); newMessage=messageName+"不是一个函数"; }else if(newMessage.includes(" is not a constructor")){ messageName=newMessage.replace('TypeError: ', '').replace(' is not a constructor', ''); newMessage=messageName+"不是一个构造函数"; }else if(newMessage.includes("Cannot read property")){ messageName=newMessage.replace('TypeError: Cannot read property ', '').replace(' of null', '').replace(' of undefined', ''); let ofName=newMessage.slice(newMessage.indexOf(" of ")+4); newMessage="无法读取\'"+ofName+"\'的属性值"+messageName; }else if(newMessage.includes("Cannot read properties")){ messageName=newMessage.slice(newMessage.indexOf("reading '")+9,-2); let ofName=newMessage.slice(newMessage.indexOf(" of ")+4,newMessage.indexOf("(")-1); newMessage="无法读取\'"+ofName+"\'的属性值"+messageName; }else if(newMessage.includes("Property description must be an object")){ messageName=newMessage.replace('TypeError: Property description must be an object: ', ''); newMessage=messageName+"是非对象类型的值"; }else if(newMessage.includes("Cannot assign to read only property ")){ messageName=newMessage.slice(47,newMessage.lastIndexOf(' of ')+1); newMessage=messageName+"属性禁止写入"; }else if(newMessage.includes("Object prototype may only be an Object or null")){ newMessage=messageName+"对象原型只能是对象或null"; }else if(newMessage.includes("Cannot create property")){ messageName=newMessage.slice(newMessage.indexOf('\'')+1); messageName=messageName.slice(0,messageName.indexOf('\'')); let obj=newMessage.slice(newMessage.indexOf(messageName)+16); newMessage=obj+"不能添加或修改\'"+messageName+"\'属性,任何 Primitive 值都不允许有property"; }else if(newMessage.includes("Can't add property")&&newMessage.includes("is not extensible")){ newMessage="对象不可添加属性(不可扩展)"; }else if(newMessage.includes("Cannot redefine property")){ messageName=newMessage.slice(37); newMessage=messageName+"不可配置"; }else if(newMessage.includes("Converting circular structure to JSON")){ messageName=newMessage.slice(37); newMessage="JSON.stringify() 方法处理循环引用结构的JSON会失败"; }else if(newMessage.includes("Cannot use 'in' operator to search for ")){ newMessage="in不能用来在字符串、数字或者其他基本类型的数据中进行检索"; }else if(newMessage.includes("Right-hand side of 'instanceof' is not an object")){ newMessage="instanceof 操作符 希望右边的操作数为一个构造对象,即一个有 prototype 属性且可以调用的对象"; }else if(newMessage.includes("Assignment to constant variable")){ newMessage="const定义的变量不可修改"; }else if(newMessage.includes("Cannot delete property")){ newMessage="不可配置的属性不能删除"; }else if(newMessage.includes("which has only a getter")){ newMessage="仅设置了getter特性的属性不可被赋值"; }else if(newMessage.includes("called on incompatible receiver undefined")){ newMessage="this提供的绑定对象与预期的不匹配"; } }else if(/URIError/.test(newMessage)){ newMessage="一个不合法的URI"; }else if(/EvalError/.test(newMessage)){ newMessage="非法调用 eval()"; }else if(/InternalError/.test(newMessage)){ if(newMessage.includes("too many switch cases")){ newMessage="过多case子句"; }else if(newMessage.includes("too many parentheses in regular expression")){ newMessage="正则表达式中括号过多"; }else if(newMessage.includes("array initializer too large")){ newMessage="超出数组大小的限制"; }else if(newMessage.includes("too much recursion")){ newMessage="递归过深"; } } if(newMessage!=msg){ return newMessage; } }, codeMirrorReady:(node,editor)=>{ ui.window.appendChild(node); node.style.fontSize=20/game.documentZoom+'px'; const mirror=window.CodeMirror(editor,{ value:node.code, mode:"javascript", lineWrapping:!lib.config.touchscreen&&lib.config.mousewheel, lineNumbers:true, indentUnit:4, autoCloseBrackets:true, fixedGutter:false, hintOptions:{completeSingle:false}, theme:lib.config.codeMirror_theme||'mdn-like', extraKeys:{ "Ctrl-Z":"undo",//撤销 "Ctrl-Y":"redo",//恢复撤销 //"Ctrl-A":"selectAll",//全选 }, }); lib.setScroll(editor.querySelector('.CodeMirror-scroll')); node.aced=true; node.editor=mirror; setTimeout(()=>mirror.refresh(),0); node.editor.on('change',(e,change)=>{ let code; if(node.editor){ code=node.editor.getValue(); }else if(node.textarea){ code=node.textarea.value; }; //动态绑定文本 if(code.length&&change.origin=="+input" && /{|}|\s|=|;|:|,|,|。|?|!|\!|\?|&|#|%|@|‘|’|;/.test(change.text[0])==false&& change.text.length==1) { //输入了代码,并且不包括空格,{},=, ; , : , 逗号等,才可以自动提示 node.editor.showHint(); } }); //防止每次输出字符都创建以下元素 const event=_status.event; const trigger=_status.event; const player=ui.create.player().init('sunce'); const target=player; const targets=[player]; const source=player; const card=game.createCard(); const cards=[card]; const result={bool:true}; function forEach(arr,f) { Array.from(arr).forEach(v=>f(v)); } function forAllProps(obj,callback){ if(!Object.getOwnPropertyNames||!Object.getPrototypeOf){ for(let name in obj) callback(name); }else{ for(let o=obj;o;o=Object.getPrototypeOf(o)) Object.getOwnPropertyNames(o).forEach(callback); } } function scriptHint(editor,keywords,getToken,options){ //Find the token at the cursor let cur=editor.getCursor(),token=editor.getTokenAt(cur); if(/\b(?:string|comment)\b/.test(token.type)) return; const innerMode=CodeMirror.innerMode(editor.getMode(),token.state); if (innerMode.mode.helperType==="json") return; token.state=innerMode.state; //If it's not a 'word-style' token, ignore the token. if (!/^[\w$_]*$/.test(token.string)){ token={ start:cur.ch, end:cur.ch, string:"", state:token.state, type:token.string=="."?"property":null }; }else if(token.end>cur.ch){ token.end=cur.ch; token.string=token.string.slice(0,cur.ch-token.start); } let tprop=token,context; //If it is a property, find out what it is a property of. while (tprop.type=="property"){ tprop=editor.getTokenAt(CodeMirror.Pos(cur.line,tprop.start)); if(tprop.string!=".") return; tprop=editor.getTokenAt(CodeMirror.Pos(cur.line,tprop.start)); if(!context) context=[]; context.push(tprop); } const list=[]; let obj; if(Array.isArray(context)){ try { const code=context.length==1?context[0].string:context.reduceRight((pre,cur)=>(pre.string||pre)+'.'+cur.string); obj=eval(code); if(![null,undefined].includes(obj)){ const keys=Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(obj))).filter(key=>key.startsWith(token.string)); list.addArray(keys); } }catch(_){ return;} }else if(token&&typeof token.string=='string'){ //非开发者模式下,提示这些单词 list.addArray(['player','card','cards','result','trigger','source','target','targets','lib','game','ui','get','ai','_status']); } return { list:[...new Set(getCompletions(token,context,keywords,options).concat(list))] .filter(key=>key.startsWith(token.string)) .sort((a,b)=>(a+'').localeCompare(b+'')) .map(text=>{ return { render(elt,data,cur) { var icon=document.createElement("span"); var className="cm-completionIcon cm-completionIcon-"; if(obj){ const type=typeof obj[text]; if(type== 'function') { className+='function'; } else if(type== 'string') { className+='text'; } else if(type== 'boolean') { className+='variable'; } else{ className+='namespace'; } }else{ if(javascriptKeywords.includes(text)){ className+='keyword'; } else if(window[text]) { const type=typeof window[text]; if(type=='function'){ className+='function'; } else if(type=='string'){ className+='text'; } else if(text=='window'||type=='boolean'){ className+='variable'; } else{ className+='namespace'; } }else{ className+='namespace'; } } icon.className=className; elt.appendChild(icon); elt.appendChild(document.createTextNode(text)); }, displayText: text, text: text, } }), from:CodeMirror.Pos(cur.line,token.start), to:CodeMirror.Pos(cur.line,token.end) }; } function javascriptHint(editor,options){ return scriptHint(editor,javascriptKeywords,function(e,cur){return e.getTokenAt(cur);},options); }; //覆盖原本的javascript提示 CodeMirror.registerHelper("hint","javascript",javascriptHint); const stringProps=Object.getOwnPropertyNames(String.prototype); const arrayProps=Object.getOwnPropertyNames(Array.prototype); const funcProps=Object.getOwnPropertyNames(Array.prototype); const javascriptKeywords=("break case catch class const continue debugger default delete do else export extends from false finally for function " + "if in import instanceof let new null return super switch this throw true try typeof var void while with yield").split(" "); function getCompletions(token,context,keywords,options){ let found=[],start=token.string,global=options&&options.globalScope||window; function maybeAdd(str){ if(str.lastIndexOf(start,0)==0&&!found.includes(str)) found.push(str); } function gatherCompletions(obj){ if(typeof obj=="string") forEach(stringProps,maybeAdd); else if(obj instanceof Array) forEach(arrayProps,maybeAdd); else if(obj instanceof Function) forEach(funcProps,maybeAdd); forAllProps(obj, maybeAdd); } if(context&&context.length){ //If this is a property, see if it belongs to some object we can //find in the current environment. let obj=context.pop(),base; if (obj.type&&obj.type.indexOf("variable")=== 0){ if(options&&options.additionalContext) base=options.additionalContext[obj.string]; if(!options||options.useGlobalScope!==false) base=base||global[obj.string]; }else if(obj.type=="string"){ base=""; }else if(obj.type == "atom"){ base=1; }else if(obj.type == "function"){ if(global.jQuery!=null&&(obj.string=='$'||obj.string=='jQuery')&&(typeof global.jQuery=='function')) base=global.jQuery(); else if(global._!=null&&(obj.string=='_')&&(typeof global._=='function')) base=global._(); } while(base!=null&&context.length) base=base[context.pop().string]; if (base!=null) gatherCompletions(base); }else{ //If not, just look in the global object, any local scope, and optional additional-context //(reading into JS mode internals to get at the local and global variables) for(let v=token.state.localVars;v;v=v.next) maybeAdd(v.name); for(let c=token.state.context;c;c=c.prev) for(let v=c.vars;v;v=v.next) maybeAdd(v.name) for(let v=token.state.globalVars;v;v=v.next) maybeAdd(v.name); if(options&&options.additionalContext!=null) for(let key in options.additionalContext) maybeAdd(key); if(!options||options.useGlobalScope!==false) gatherCompletions(global); forEach(keywords,maybeAdd); } return found.sort((a,b)=>(a+'').localeCompare(b+'')); } }, setIntro:function(node,func,left){ if(lib.config.touchscreen){ if(left){ node.listen(ui.click.touchintro); } else{ lib.setLongPress(node,ui.click.intro); } } else{ if(left){ node.listen(ui.click.intro); } if(lib.config.hover_all&&!lib.device){ lib.setHover(node,ui.click.hoverplayer); } if(lib.config.right_info){ node.oncontextmenu=ui.click.rightplayer; } } // if(!left){ // lib.setPressure(node,ui.click.rightpressure); // } if(func){ node._customintro=func; } }, // setPressure:function(node,func){ // if(window.Pressure){ // window.Pressure.set(node,{change: func}, {polyfill: false}); // } // }, setPopped:function(node,func,width,height,forceclick,paused2){ node._poppedfunc=func; node._poppedwidth=width; node._poppedheight=height; if(forceclick){ node.forceclick=true; } if(lib.config.touchscreen||forceclick){ node.listen(ui.click.hoverpopped); } else{ node.addEventListener('mouseenter',ui.click.hoverpopped); // node.addEventListener('mouseleave',ui.click.hoverpopped_leave); } if(paused2){ node._paused2=true; } }, placePoppedDialog:function(dialog,e){ if(dialog._place_text){ if(dialog._place_text.firstChild.offsetWidth>=190||dialog._place_text.firstChild.offsetHeight>=30){ dialog._place_text.style.marginLeft='14px'; dialog._place_text.style.marginRight='14px'; dialog._place_text.style.textAlign='left'; dialog._place_text.style.width='calc(100% - 28px)'; } } if(e.touches&&e.touches[0]){ e=e.touches[0]; } var height=Math.min(ui.window.offsetHeight-20,dialog.content.scrollHeight); if(dialog._mod_height){ height+=dialog._mod_height; } dialog.style.height=height+'px'; if(e.clientX/game.documentZoom<ui.window.offsetWidth/2){ dialog.style.left=(e.clientX/game.documentZoom+10)+'px'; } else{ dialog.style.left=(e.clientX/game.documentZoom-dialog.offsetWidth-10)+'px'; } var idealtop=(e.clientY||0)/game.documentZoom-dialog.offsetHeight/2; if(typeof idealtop!='number'||isNaN(idealtop)||idealtop<=5){ idealtop=5; } else if(idealtop+dialog.offsetHeight+10>ui.window.offsetHeight){ idealtop=ui.window.offsetHeight-10-dialog.offsetHeight; } dialog.style.top=idealtop+'px'; }, setHover:function(node,func,hoveration,width){ node._hoverfunc=func; if(typeof hoveration=='number'){ node._hoveration=hoveration; } if(typeof width=='number'){ node._hoverwidth=width } node.addEventListener('mouseenter',ui.click.mouseenter); node.addEventListener('mouseleave',ui.click.mouseleave); node.addEventListener('mousedown',ui.click.mousedown); node.addEventListener('mousemove',ui.click.mousemove); return node; }, setScroll:function(node){ node.ontouchstart=ui.click.touchStart; node.ontouchmove=ui.click.touchScroll; node.style.WebkitOverflowScrolling='touch'; return node; }, setMousewheel:function(node){ if(lib.config.mousewheel) node.onmousewheel=ui.click.mousewheel; }, setLongPress:function(node,func){ node.addEventListener('touchstart',ui.click.longpressdown); node.addEventListener('touchend',ui.click.longpresscancel); node._longpresscallback=func; return node; }, updateCanvas:function(time){ if(lib.canvasUpdates.length===0){ lib.status.canvas=false; return false; } 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.lineCap='round'; ctx.lineWidth=3; ctx.save(); for(var i=0;i<lib.canvasUpdates.length;i++){ ctx.restore(); ctx.save(); var update=lib.canvasUpdates[i]; if(!update.starttime){ update.starttime=time; } if(update(time-update.starttime,ctx)===false){ lib.canvasUpdates.splice(i--,1); } } }, run:function(time){ lib.status.time=time; for(var i=0;i<lib.updates.length;i++){ if(!lib.updates[i].hasOwnProperty('_time')){ lib.updates[i]._time=time; } if(lib.updates[i](time-lib.updates[i]._time-lib.status.delayed)===false){ lib.updates.splice(i--,1); } } if(lib.updates.length){ lib.status.frameId=requestAnimationFrame(lib.run); } else{ lib.status.time=0; lib.status.delayed=0; } }, getUTC:function(date){ return date.getTime(); }, saveVideo:function(){ if(_status.videoToSave){ game.export(lib.init.encode(JSON.stringify(_status.videoToSave)), '无名杀 - 录像 - '+_status.videoToSave.name[0]+' - '+_status.videoToSave.name[1]); } }, genAsync:fn=>gnc.of(fn), genAwait:item=>gnc.is.generator(item)?gnc.of(function*(){for(const content of item){yield content;}})():Promise.resolve(item), gnc:{ of:fn=>gnc.of(fn), is:{ coroutine:item=>gnc.is.coroutine(item), generatorFunc:item=>gnc.is.generatorFunc(item), generator:item=>gnc.is.generator(item) } }, comparator:{ equals:function(){ if(arguments.length==0) return false; if(arguments.length==1) return true; for(let i=1;i<arguments.length;++i) if(arguments[i]!==arguments[0])return false; return true; }, equalAny:function(){ if(arguments.length==0) return false; if(arguments.length==1) return true; for(let i=1;i<arguments.length;++i) if(arguments[i]===arguments[0])return true; return false; }, notEquals:function(){ if(arguments.length==0) return false; if(arguments.length==1) return true; for(let i=1;i<arguments.length;++i) if(arguments[i]===arguments[0])return false; return true; }, notEqualAny:function(){ if(arguments.length==0) return false; if(arguments.length==1) return true; for(let i=1;i<arguments.length;++i) if(arguments[i]!==arguments[0])return true; return false; }, typeEquals:function(){ if(arguments.length==0)return false; if(arguments.length==1)return arguments[0]!==null; const type=typeof arguments[0]; for(let i=1;i<arguments.length;++i) if(type!==arguments[i])return false; return true; } }, creation:{ get array(){ return []; }, get object(){ return {}; }, get nullObject(){ return Object.create(null); }, get string(){ return ""; } }, linq:{ cselector:{ hasAttr:name=>`[${name}]`, isAttr:(name,item)=>`[${name}=${item}]`, inAttr:(name,item)=>`[${name}~=${item}]`, conAttr:(name,item)=>`[${name}*=${item}]`, onAttr:(name,item)=>`[${name}|=${item}]`, bgnAttr:(name,item)=>`[${name}^=${item}]`, endAttr:(name,item)=>`[${name}^=${item}]`, merge:function(){return Array.from(arguments).join(" ");}, of:function(){return Array.from(arguments).join("");}, class:function(){return `.${Array.from(arguments).join(".")}`;}, group:function(){return Array.from(arguments).join(",");}, media:type=>`@media ${type}` }, dom:{ attributes:{ style(name,value){ return { _type:"style", name:name, value:value } } }, inject(element,options){ //处理id和class if(options.identity){ for(const item of options.identity){ if (item.startsWith("#")) element.id = item.slice(1); else element.classList.add(item); } } //处理属性 if(options.attributes){ for(const item in options.attributes) element.setAttribute(item,options.attributes[item]); } //处理样式 if(options.style){ for(const item in options.style) element.style[item] = options.style[item]; } //处理内容 if(options.content){ element.innerHTML=options.content; } //处理子元素 if(options.childs){ for(const item of options.childs){ element.appendChild(item); } } return element; }, generate(){ let result=lib.creation.nullObject; const args=Array.from(arguments); for(const item of args) { switch(typeof item) { case "object": switch (item.constructor) { case Object: case null: if("_type" in item){ const type=item["_type"]; if(!(type in result)) result[type]=lib.creation.nullObject; result[type][item.name]=item.value; } else{ if(!("style" in result)) result.style=lib.creation.nullObject; for(const name in item){ result.style[name]=item[name]; } } break; default: if(!("childs" in result)) result.childs=lib.creation.array; result.childs.add(item); break; } break; case "string": if(/^\.|#/.test(item)){ if(!("identity" in result)) result.identity=lib.creation.array; const identities=item.split(".").filter(Boolean); for(const item of identities) result.identity.add(item); } else result.content = item; break; } } return result; }, attribute(name,value){ return { _type:"attributes", name:name, value:value } }, div(){ const dom=lib.linq.dom; return dom.inject(document.createElement("div"),dom.generate(...arguments)); } } }, init:{ init:function(){ if(typeof __dirname==='string'&&__dirname.length){ var dirsplit=__dirname.split('/'); for(var 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+='_'; } window.resetGameTimeout=setTimeout(lib.init.reset,parseInt(localStorage.getItem(lib.configprefix+'loadtime'))||10000); if(window.cordovaLoadTimeout){ clearTimeout(window.cordovaLoadTimeout); delete window.cordovaLoadTimeout; } var links=document.head.querySelectorAll('link'); for(var i=0;i<links.length;i++){ if(links[i].href.includes('app/color.css')){ links[i].remove(); break; } } var index=window.location.href.indexOf('index.html?server='); if(index!=-1){ window.isNonameServer=window.location.href.slice(index+18); window.nodb=true; } else{ index=localStorage.getItem(lib.configprefix+'asserver'); if(index){ window.isNonameServer=index; window.isNonameServerIp=lib.hallURL; } } var htmlbg=localStorage.getItem(lib.configprefix+'background'); if(htmlbg){ if(htmlbg[0]=='['){ try{ htmlbg=JSON.parse(htmlbg); 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%'; } } lib.get=get; lib.ui=ui; lib.ai=ai; lib.game=game; for(let i in lib.element.event){ _status.event[i]=lib.element.event[i]; } HTMLDivElement.prototype.animate=function(name,time){ var that; if(get.is.mobileMe(this)&&name=='target'){ that=ui.mebg; } else{ that=this; } that.classList.add(name); setTimeout(function(){ that.classList.remove(name); },time||1000); return this; }; HTMLDivElement.prototype.hide=function(){ this.classList.add('hidden'); return this; }; HTMLDivElement.prototype.unfocus=function(){ if(lib.config.transparent_dialog) this.classList.add('transparent'); return this; }; HTMLDivElement.prototype.refocus=function(){ this.classList.remove('transparent'); return this; }; HTMLDivElement.prototype.show=function(){ this.classList.remove('hidden'); return this; }; HTMLDivElement.prototype.delete=function(time,callback){ if(this.timeout){ clearTimeout(this.timeout); delete this.timeout; } if(!this._listeningEnd||this._transitionEnded){ if(typeof time!='number') time=500; this.classList.add('removing'); var that=this; this.timeout=setTimeout(function(){ that.remove(); that.classList.remove('removing'); if(typeof callback=='function'){ callback(); } },time); } else{ this._onEndDelete=true; } return this; }; HTMLDivElement.prototype.goto=function(position,time){ if(this.timeout){ clearTimeout(this.timeout); delete this.timeout; } if(typeof time!='number') time=500; this.classList.add('removing'); var that=this; this.timeout=setTimeout(function(){ if(!that.destroyed){ position.appendChild(that); } that.classList.remove('removing'); delete that.destiny; },time); this.destiny=position; return this; }; HTMLDivElement.prototype.fix=function(){ clearTimeout(this.timeout); delete this.timeout; delete this.destiny; this.classList.remove('removing'); return this; }; Object.defineProperty(HTMLDivElement.prototype,'setBackground',{ configurable:true, enumerable:false, writable:true, value:function(name,type,ext,subfolder){ if(!name) return; let src; if(ext=='noskin') ext='.jpg'; ext=ext||'.jpg'; subfolder=subfolder||'default'; if(type){ let dbimage=null,extimage=null,modeimage=null,nameinfo,gzbool=false; const mode=get.mode(); if(type=='character'){ if(lib.characterPack[`mode_${mode}`]&&lib.characterPack[`mode_${mode}`][name]){ if(mode=='guozhan'){ nameinfo=lib.character[name]; if(name.startsWith('gz_shibing')) name=name.slice(3,11); else{ if(lib.config.mode_config.guozhan.guozhanSkin&&lib.character[name]&&lib.character[name][4].contains('gzskin')) gzbool=true; name=name.slice(3); } } else modeimage=mode; } else if(name.includes('::')){ name=name.split('::'); modeimage=name[0]; name=name[1]; } else{ nameinfo=get.character(name); } } if(!modeimage&&nameinfo&&nameinfo[4]) for(const value of nameinfo[4]){ if(value.startsWith('ext:')){ extimage=value; break; } else if(value.startsWith('db:')){ dbimage=value; break; } else if(value.startsWith('mode:')){ modeimage=value.slice(5); break; } else if(value.startsWith('character:')){ name=value.slice(10); break; } } if(extimage) src=extimage.replace(/^ext:/,'extension/'); else if(dbimage){ this.setBackgroundDB(dbimage.slice(3)); return this; } else if(modeimage) src=`image/mode/${modeimage}/character/${name}${ext}`; else if(type=='character'&&lib.config.skin[name]&&arguments[2]!='noskin') src=`image/skin/${name}/${lib.config.skin[name]}${ext}`; else if(type=='character') src=`image/character/${gzbool?'gz_':''}${name}${ext}`; else src=`image/${type}/${subfolder}/${name}${ext}`; } else src=`image/${name}${ext}`; this.setBackgroundImage(src); this.style.backgroundPositionX='center'; this.style.backgroundSize='cover'; return this; } }); HTMLDivElement.prototype.setBackgroundDB=function(img){ return game.getDB('image',img).then(src=>{ this.style.backgroundImage=`url('${src}')`; this.style.backgroundSize="cover"; return this; }); }; HTMLDivElement.prototype.setBackgroundImage=function(img){ this.style.backgroundImage=`url("${lib.assetURL}${img}")`; return this; }, HTMLDivElement.prototype.listen=function(func){ if(lib.config.touchscreen){ this.addEventListener('touchend',function(e){ if(!_status.dragged){ func.call(this,e); } }); var fallback=function(e){ if(!_status.touchconfirmed){ func.call(this,e); } else{ this.removeEventListener('click',fallback); } } this.addEventListener('click',fallback); } else{ this.addEventListener('click',func); } return this; }; HTMLDivElement.prototype.listenTransition=function(func,time){ let done=false; const callback=()=>{ if(!done){ done=true; func.call(this); } clearTimeout(timer); this.removeEventListener('webkitTransitionEnd',callback); }; const timer=setTimeout(callback,time||1000); this.addEventListener('webkitTransitionEnd',callback); return timer; }; HTMLDivElement.prototype.setPosition=function(){ var position; if(arguments.length==4){ position=[]; for(var i=0;i<arguments.length;i++) position.push(arguments[i]); } else if(arguments.length==1&&Array.isArray(arguments[0])&&arguments[0].length==4){ position=arguments[0]; } else{ return this; } var top='calc('+position[0]+'% '; if(position[1]>0) top+='+ '+position[1]+'px)'; else top+='- '+Math.abs(position[1])+'px)'; var left='calc('+position[2]+'% '; if(position[3]>0) left+='+ '+position[3]+'px)'; else left+='- '+Math.abs(position[3])+'px)'; this.style.top=top; this.style.left=left; return this; }; HTMLDivElement.prototype.css=function(style){ for(var i in style){ if(i=='innerHTML'){ this.innerHTML=style[i]; } else{ this.style[i]=style[i]; } } return this; }; HTMLTableElement.prototype.get=function(row,col){ if(row<this.childNodes.length){ return this.childNodes[row].childNodes[col]; } }; /*处理lib.nature的兼容性问题*/ const mapHasFunc=function(item){ return this.has(item) }; Object.defineProperty(Map.prototype, "contains",{ configurable:true, enumerable:false, writable:true, value:mapHasFunc }); Object.defineProperty(Map.prototype, "includes",{ configurable:true, enumerable:false, writable:true, value:mapHasFunc }); const mapAddFunc=function(item){ this.set(item,0); return this; } Object.defineProperty(Map.prototype, "add", { configurable:true, enumerable:false, writable:true, value:mapAddFunc }); Object.defineProperty(Map.prototype, "push", { configurable:true, enumerable:false, writable:true, value:mapAddFunc }); Object.defineProperty(Map.prototype, "addArray", { configurable:true, enumerable:false, writable:true, value:function(arr){ for(var i=0;i<arr.length;i++){ this.add(arr[i]); } return this; } }); Object.defineProperty(Map.prototype, "remove", { configurable:true, enumerable:false, writable:true, value:function(item){ this.delete(item); return this; } }); /*Map prototype end*/ Object.defineProperty(Array.prototype,"filterInD",{ configurable:true, enumerable:false, writable:true, value:function(pos){ if(typeof pos!='string') pos='o'; return this.filter(card=>pos.includes(get.position(card,true))); } }); Object.defineProperty(Array.prototype,"someInD",{ configurable:true, enumerable:false, writable:true, value:function(pos){ if(typeof pos!='string') pos='o'; return this.some(card=>pos.includes(get.position(card,true))); } }); Object.defineProperty(Array.prototype,"everyInD",{ configurable:true, enumerable:false, writable:true, value:function(pos){ if(typeof pos!='string') pos='o'; return this.every(card=>pos.includes(get.position(card,true))); } }); /** *@legacy Use `Array.prototype.includes(searchElement)` instead. */ Object.defineProperty(Array.prototype,"contains",{ configurable:true, enumerable:false, writable:true, value:Array.prototype.includes }); Object.defineProperty(Array.prototype,"containsSome",{ configurable:true, enumerable:false, writable:true, value:function(){ return Array.from(arguments).some(i=>this.includes(i)); } }); Object.defineProperty(Array.prototype,"containsAll",{ configurable:true, enumerable:false, writable:true, value:function(){ return Array.from(arguments).every(i=>this.includes(i)); } }); Object.defineProperty(Array.prototype,"add",{ configurable:true, enumerable:false, writable:true, value:function(){ for(const arg of arguments){ if(this.contains(arg)) continue; this.push(arg); } return this; } }); Object.defineProperty(Array.prototype,"addArray",{ configurable:true, enumerable:false, writable:true, value:function(){ for(const arr of arguments){ for(const item of arr) this.add(item); } return this; } }); Object.defineProperty(Array.prototype,"remove",{ configurable:true, enumerable:false, writable:true, value:function(){ for(const item of arguments){ const pos=this.indexOf(item); if(pos==-1) continue; this.splice(pos,1); } return this; } }); Object.defineProperty(Array.prototype,"removeArray",{ configurable:true, enumerable:false, writable:true, value:function(){ for(const i of Array.from(arguments)) this.remove(...i); return this; } }); Object.defineProperty(Array.prototype,"unique",{ configurable:true, enumerable:false, writable:true, value:function(){ let uniqueArray=[...new Set(this)]; this.length=uniqueArray.length; for(let i=0;i<uniqueArray.length;i++) this[i]=uniqueArray[i]; return this; } }); Object.defineProperty(Array.prototype,"toUniqued",{ configurable:true, enumerable:false, writable:true, value:function(){ return [...new Set(this)]; } }); Object.defineProperty(Array.prototype,"randomGet",{ configurable:true, enumerable:false, writable:true, value:function(){ let arr=this.slice(0); arr.removeArray(Array.from(arguments)); return arr[Math.floor(Math.random()*arr.length)]; } }); Object.defineProperty(Array.prototype,"randomGets",{ configurable:true, enumerable:false, writable:true, value:function(num){ if(num>this.length) num=this.length; let arr=this.slice(0); let list=[]; for(let i=0;i<num;i++){ list.push(arr.splice(Math.floor(Math.random()*arr.length),1)[0]); } return list; } }); Object.defineProperty(Array.prototype,"randomRemove",{ configurable:true, enumerable:false, writable:true, value:function(num){ if(typeof num=='number'){ let list=[]; for(let i=0;i<num;i++){ if(!this.length) break; list.push(this.randomRemove()); } return list; } return this.splice(Math.floor(Math.random()*this.length),1)[0]; } }); Object.defineProperty(Array.prototype,"randomSort",{ configurable:true, enumerable:false, writable:true, value:function(){ let list=[]; while(this.length){ list.push(this.randomRemove()); } for(let i=0;i<list.length;i++){ this.push(list[i]); } return this; } }); Object.defineProperty(Array.prototype,"sortBySeat",{ configurable:true, enumerable:false, writable:true, value:function(target){ lib.tempSortSeat=target; this.sort(lib.sort.seat); delete lib.tempSortSeat; return this; } }); /** *@description 从数组中寻找某个特征最大的,且通过筛选的第一个元素 */ Object.defineProperty(Array.prototype,"maxBy",{ configurable:true, enumerable:false, writable:true, value:function(sortBy,filter){ let list=this.filter(filter||(()=>true)); if(sortBy&&typeof sortBy=='function') list.sort((a,b)=>sortBy(a)-sortBy(b)); else list.sort(); return list[list.length-1]; } }); Object.defineProperty(Array.prototype,"minBy",{ configurable:true, enumerable:false, writable:true, value:function(sortBy,filter){ let list=this.filter(filter||(()=>true)); if(sortBy&&typeof sortBy=='function') list.sort((a,b)=>sortBy(a)-sortBy(b)); else list.sort(); return list[0]; } }); //!!!WARNING!!! //Will be deprecated in next verision Object.defineProperty(Object.prototype,'hasNature',{ configurable:true, enumerable:false, writable:true, value:function(nature,player){ var natures=get.natureList(this,player); if(!nature) return natures.length>0; if(nature=='linked') return natures.some(n=>lib.linked.includes(n)); return get.is.sameNature(natures,nature); } }); window.onkeydown=function(e){ if(!ui.menuContainer||!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(window.saveNonameInput){ window.saveNonameInput(); } e.preventDefault(); e.stopPropagation(); return false; } else if(e.keyCode==74&&(e.ctrlKey||e.metaKey)&&lib.node){ lib.node.debug(); } } else{ game.closePopped(); var dialogs=document.querySelectorAll('#window>.dialog.popped:not(.static)'); for(var i=0;i<dialogs.length;i++){ dialogs[i].delete(); } if(e.keyCode==32){ var node=ui.window.querySelector('pausedbg'); if(node){ node.click(); } else{ ui.click.pause(); } } else if(e.keyCode==65){ if(ui.auto) ui.auto.click(); } else if(e.keyCode==87){ if(ui.wuxie&&ui.wuxie.style.display!='none'){ ui.wuxie.classList.toggle('glow') } else if(ui.tempnowuxie){ 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)&&lib.node){ lib.node.debug(); } // else if(e.keyCode==27){ // if(!ui.arena.classList.contains('paused')) ui.click.config(); // } } }; window.onload=function(){ if(lib.device){ var script=document.createElement('script'); script.src='cordova.js'; document.body.appendChild(script); document.addEventListener('deviceready',function(){ if(lib.init.cordovaReady){ lib.init.cordovaReady(); delete lib.init.cordovaReady; } }); } if(_status.packLoaded){ delete _status.packLoaded; lib.init.onload(); } else{ _status.windowLoaded=true; } }; window.onerror=function(msg,src,line,column,err){ 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=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}`; if(evt.parent) str+=`\nevent.parent.name: ${evt.parent.name}\nevent.parent.step: ${evt.parent.step}`; 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 game.readFile=='function'||location.origin!='file://')){ function createShowCode(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,'')); 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); window.ea=Array.from(arguments); window.em=msg; window.el=line; window.ec=column; window.eo=err; game.print(str); if(!lib.config.errstop){ _status.withError=true; game.loop(); } }; if(window.noname_update){ 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; } var noname_inited=localStorage.getItem('noname_inited'); if(noname_inited&&noname_inited!=='nodejs'){ var ua=navigator.userAgent.toLowerCase(); if(ua.includes('android')){ lib.device='android'; } else if(ua.includes('iphone')||ua.includes('ipad')||ua.includes('macintosh')){ lib.device='ios'; } } if(lib.assetURL.includes('com.widget.noname.qingyao')){ alert('您正在一个不受信任的闭源客户端上运行《无名杀》。建议您更换为其他开源的无名杀客户端,避免给您带来不必要的损失。'); } var config3=null; var proceed=function(config2){ if(config3===null){ config3=config2; return; } if(config2.mode) lib.config.mode=config2.mode; if(lib.config.mode_config[lib.config.mode]==undefined) lib.config.mode_config[lib.config.mode]={}; for(var i in lib.config.mode_config.global){ if(lib.config.mode_config[lib.config.mode][i]==undefined){ lib.config.mode_config[lib.config.mode][i]=lib.config.mode_config.global[i]; } } if(lib.config.characters){ lib.config.defaultcharacters=lib.config.characters.slice(0); } if(lib.config.cards){ lib.config.defaultcards=lib.config.cards.slice(0); } for(var i in config2){ if(i.includes('_mode_config')){ var thismode=i.substr(i.indexOf('_mode_config')+13); if(!lib.config.mode_config[thismode]){ lib.config.mode_config[thismode]={}; } lib.config.mode_config[thismode][i.substr(0,i.indexOf('_mode_config'))]=config2[i]; } else{ lib.config[i]=config2[i]; } } for(var i in lib.config.translate){ lib.translate[i]=lib.config.translate[i]; } lib.config.all.characters=[]; lib.config.all.cards=[]; lib.config.all.plays=[]; lib.config.all.mode=[]; if(lib.config.debug){ lib.init.js(lib.assetURL+'game','asset',function(){ lib.skin=window.noname_skin_list; delete window.noname_skin_list; delete window.noname_asset_list; }); } if(window.isNonameServer){ lib.config.mode='connect'; } var pack=window.noname_package; delete window.noname_package; for(i in pack.character){ if(lib.config.all.sgscharacters.contains(i)||lib.config.hiddenCharacterPack.indexOf(i)==-1){ lib.config.all.characters.push(i); lib.translate[i+'_character_config']=pack.character[i]; } } for(i in pack.card){ if(lib.config.all.sgscards.contains(i)||lib.config.hiddenCardPack.indexOf(i)==-1){ lib.config.all.cards.push(i); lib.translate[i+'_card_config']=pack.card[i]; } } for(i in pack.play){ lib.config.all.plays.push(i); lib.translate[i+'_play_config']=pack.play[i]; } for(i in pack.submode){ for(var j in pack.submode[i]){ lib.translate[i+'|'+j]=pack.submode[i][j]; } } if(!lib.config.gameRecord){ lib.config.gameRecord={}; } for(i in pack.mode){ if(lib.config.hiddenModePack.indexOf(i)==-1){ lib.config.all.mode.push(i); lib.translate[i]=pack.mode[i]; if(!lib.config.gameRecord[i]){ lib.config.gameRecord[i]={data:{}}; } } } if(lib.config.all.mode.length==0){ lib.config.all.mode.push('identity'); lib.translate.identity='身份'; if(!lib.config.gameRecord.identity){ lib.config.gameRecord.identity={data:{}}; } } if(pack.background){ for(i in pack.background){ if(lib.config.hiddenBackgroundPack.contains(i)) continue; lib.configMenu.appearence.config.image_background.item[i]=pack.background[i]; } for(var i=0;i<lib.config.customBackgroundPack.length;i++){ var link=lib.config.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(lib.device||typeof window.require=='function'){ lib.configMenu.audio.config.background_music.item.music_custom='自定义音乐'; } lib.config.all.background_music=['music_default']; for(i in pack.music){ lib.config.all.background_music.push(i); lib.configMenu.audio.config.background_music.item[i]=pack.music[i]; } if(lib.config.customBackgroundMusic){ for(i in lib.config.customBackgroundMusic){ lib.config.all.background_music.push(i); lib.configMenu.audio.config.background_music.item[i]=lib.config.customBackgroundMusic[i]; } } lib.configMenu.audio.config.background_music.item.music_random='随机播放'; lib.configMenu.audio.config.background_music.item.music_off='关闭'; } if(pack.theme){ for(i in pack.theme){ lib.configMenu.appearence.config.theme.item[i]=pack.theme[i]; } } if(lib.config.extension_sources){ for(i in lib.config.extension_sources){ lib.configMenu.general.config.extension_source.item[i]=i; } } if(pack.font){ ui.css.fontsheet=lib.init.sheet(); const appearenceConfig=lib.configMenu.appearence.config,fontSheet=ui.css.fontsheet.sheet,suitsFont=lib.config.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='默认'; } var ua=navigator.userAgent.toLowerCase(); if('ontouchstart' in document){ if(!lib.config.totouched){ game.saveConfig('totouched',true); if(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(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(lib.config.touchscreen){ game.saveConfig('touchscreen',false); } if(!lib.config.toscrolled&&ua.includes('macintosh')){ game.saveConfig('toscrolled',true); game.saveConfig('mousewheel',false); } var show_splash=lib.config.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'); var extensionlist=[]; if(!localStorage.getItem(lib.configprefix+'disable_extension')){ if(lib.config.extensions&&lib.config.extensions.length){ window.resetExtension=function(){ for(var i=0;i<lib.config.extensions.length;i++){ game.saveConfig('extension_'+lib.config.extensions[i]+'_enable',false); } localStorage.setItem(lib.configprefix+'disable_extension',true); } } for(var i=0;i<lib.config.plays.length;i++){ if(lib.config.all.plays.includes(lib.config.plays[i])){ extensionlist.push(lib.config.plays[i]); } } var alerted=false; for(var i=0;i<lib.config.extensions.length;i++){ if(window.bannedExtensions.contains(lib.config.extensions[i])){ //if(!alerted) alert('读取某些扩展时出现问题。'); alerted=true; continue; } var extcontent=localStorage.getItem(lib.configprefix+'extension_'+lib.config.extensions[i]); 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(lib.config.mode!='connect'||(!localStorage.getItem(lib.configprefix+'directstart')&&show_splash)){ extensionlist.push(lib.config.extensions[i]); } } } else{ if(lib.config.mode!='connect'||(!localStorage.getItem(lib.configprefix+'directstart')&&show_splash)){ var alerted=false; for(var i=0;i<lib.config.extensions.length;i++){ if(window.bannedExtensions.contains(lib.config.extensions[i])){ //if(!alerted) alert('读取某些扩展时出现问题。'); alerted=true; continue; } game.import('extension',{name:lib.config.extensions[i]}); } } } const loadPack=()=>{ 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)(); })); } let toLoad=lib.config.all.cards.length+lib.config.all.characters.length+1; if(_status.javaScriptExtensions) toLoad+=_status.javaScriptExtensions.reduce((constructingToLoad,javaScriptExtension)=>{ const lengths=Object.values(javaScriptExtension).reduce((constructingLengths,value)=>{ if(isArray(value)) constructingLengths.push(value.length); return constructingLengths; },[]); if(!lengths.length) return constructingToLoad+1; return constructingToLoad+Math.min(...lengths); },0); const packLoaded=gnc.of(function*(){ toLoad--; if(toLoad) return; if(_status.importing){ let promises=lib.creation.array; for(const type in _status.importing){ promises.addArray(_status.importing[type]) } yield Promise.allSettled(promises); delete _status.importing; } if(_status.windowLoaded){ delete _status.windowLoaded; lib.init.onload(); } else _status.packLoaded=true; }); if(localStorage.getItem(`${lib.configprefix}playback`)){ toLoad++; lib.init.js(`${lib.assetURL}mode`,lib.config.mode,packLoaded,packLoaded); } else if((localStorage.getItem(`${lib.configprefix}directstart`)||!show_splash)&&lib.config.all.mode.includes(lib.config.mode)){ toLoad++; lib.init.js(`${lib.assetURL}mode`,lib.config.mode,packLoaded,packLoaded); } lib.init.js(`${lib.assetURL}card`,lib.config.all.cards,packLoaded,packLoaded); lib.init.js(`${lib.assetURL}character`,lib.config.all.characters,packLoaded,packLoaded); lib.init.js(`${lib.assetURL}character`,'rank',packLoaded,packLoaded); if(!_status.javaScriptExtensions) return; const loadJavaScriptExtension=(javaScriptExtension,pathArray,fileArray,onLoadArray,onErrorArray,index)=>{ if(!pathArray&&!fileArray&&!onLoadArray&&!onErrorArray){ lib.init.js(javaScriptExtension.path,javaScriptExtension.file,()=>{ if(typeof javaScriptExtension.onload=='function') javaScriptExtension.onload(); packLoaded(); },()=>{ if(typeof javaScriptExtension.onerror=='function') javaScriptExtension.onerror(); packLoaded(); }); 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; const javaScriptExtensionOnLoad=()=>{ if(typeof onLoad=='function') onLoad(); loadJavaScriptExtension(javaScriptExtension,pathArray,fileArray,onLoadArray,onErrorArray,index+1); packLoaded(); },jsExtOnError=()=>{ if(typeof onError=='function') onError(); loadJavaScriptExtension(javaScriptExtension,pathArray,fileArray,onLoadArray,onErrorArray,index+1); packLoaded(); }; lib.init.js(path,file,javaScriptExtensionOnLoad,jsExtOnError); }; _status.javaScriptExtensions.forEach(javaScriptExtension=>{ const pathArray=isArray(javaScriptExtension.path); const fileArray=isArray(javaScriptExtension.file); const onLoadArray=isArray(javaScriptExtension.onLoad); const onErrorArray=isArray(javaScriptExtension.onError); loadJavaScriptExtension(javaScriptExtension,pathArray,fileArray,onLoadArray,onErrorArray); }); }; var layout=lib.config.layout; if(layout=='default'||lib.layoutfixed.indexOf(lib.config.mode)!==-1){ layout='mobile'; } if(layout=='phone'){ layout='mobile'; game.saveConfig('layout','mobile'); game.saveConfig('phonelayout',true); } game.layout=layout; if(lib.config.image_background_random){ if(_status.htmlbg){ game.saveConfig('image_background',_status.htmlbg); } else{ var list=[]; for(var i in lib.configMenu.appearence.config.image_background.item){ if(i=='default') continue; list.push(i); } game.saveConfig('image_background',list.randomGet(lib.config.image_background)); } lib.init.background(); } delete _status.htmlbg; window.game=game; game.dynamicStyle.init(); lib.announce.init(); // node:path library alternative if (typeof module!="object"||typeof module.exports!="object") lib.init.js(`${lib.assetURL}game`,"path",()=>{ lib.path=window._noname_path; delete window._noname_path; },e=>{ console.log(e); }); var styleToLoad=6; var styleLoaded=gnc.of(function*(){ --styleToLoad; if(styleToLoad==0){ if(extensionlist.length&&(lib.config.mode!='connect'||show_splash)){ _status.extensionLoading=[]; let extToLoad=extensionlist.length; const extLoaded=gnc.of(function*(){ --extToLoad; if(extToLoad==0){ yield Promise.allSettled(_status.extensionLoading); delete _status.extensionLoading; loadPack(); } }); //读取扩展 var alerted=false; for(var i=0;i<extensionlist.length;i++){ if(window.bannedExtensions.contains(extensionlist[i])){ alerted=true; --extToLoad; if(extToLoad==0){ yield Promise.allSettled(_status.extensionLoading); delete _status.extensionLoading; loadPack(); } continue; } lib.init.js(lib.assetURL+'extension/'+extensionlist[i],'extension',extLoaded,(function(i){ return gnc.of(function*(){ game.removeExtension(i); --extToLoad; if(extToLoad==0){ yield Promise.allSettled(_status.extensionLoading); delete _status.extensionLoading; loadPack(); } }); }(extensionlist[i]))); } } else{ loadPack(); } } }); if(lib.config.layout=='default'){ lib.config.layout='mobile'; } ui.css.layout=lib.init.css(lib.assetURL+'layout/'+layout,'layout',styleLoaded); if(get.is.phoneLayout()){ ui.css.phone=lib.init.css(lib.assetURL+'layout/default','phone',styleLoaded); } else{ ui.css.phone=lib.init.css(); styleToLoad--; } ui.css.theme=lib.init.css(lib.assetURL+'theme/'+lib.config.theme,'style',styleLoaded); ui.css.card_style=lib.init.css(lib.assetURL+'theme/style/card',lib.config.card_style,styleLoaded); ui.css.cardback_style=lib.init.css(lib.assetURL+'theme/style/cardback',lib.config.cardback_style,styleLoaded); ui.css.hp_style=lib.init.css(lib.assetURL+'theme/style/hp',lib.config.hp_style,styleLoaded); if(lib.config.player_style&&lib.config.player_style!='default'&&lib.config.player_style!='custom'){ var str=''; switch(lib.config.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; } ui.css.player_stylesheet=lib.init.sheet('#window .player{background-image:'+str+'}'); } if(lib.config.border_style&&lib.config.border_style!='default'&&lib.config.border_style!='custom'&&lib.config.border_style!='auto'){ ui.css.border_stylesheet=lib.init.sheet(); var bstyle=lib.config.border_style; if(bstyle.startsWith('dragon_')){ bstyle=bstyle.slice(7); } 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); 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); ui.css.border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}',0); } if(lib.config.control_style&&lib.config.control_style!='default'&&lib.config.control_style!='custom'){ var str=''; switch(lib.config.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(lib.config.control_style=='wood'){ ui.css.control_stylesheet=lib.init.sheet('#window .control,#window .menubutton,#window #system>div>div,#window #system>div>.pressdown2{background-image:'+str+'}'); } else{ 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(lib.config.menu_style&&lib.config.menu_style!='default'&&lib.config.menu_style!='custom'){ var str=''; switch(lib.config.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; } ui.css.menu_stylesheet=lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:'+str+'}'); } lib.config.duration=500; if(!lib.config.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); } }; var proceed2=()=>{ if(config3){ proceed(config3); } else{ config3=true; } }; ui.css={menu:lib.init.css(lib.assetURL+'layout/default','menu',function(){ ui.css.default=lib.init.css(lib.assetURL+'layout/default','layout'); proceed2(); })}; if(lib.device){ lib.init.cordovaReady=function(){ if(lib.device=='android'){ document.addEventListener("pause", function(){ if(!_status.paused2&&(typeof _status.event.isMine=='function'&&!_status.event.isMine())){ ui.click.pause(); } if(ui.backgroundMusic){ ui.backgroundMusic.pause(); } }); document.addEventListener("resume", ()=>{ if(ui.backgroundMusic) ui.backgroundMusic.play(); }); document.addEventListener("backbutton", function(){ if(ui.arena&&ui.arena.classList.contains('menupaused')){ if(window.saveNonameInput){ window.saveNonameInput(); } else{ ui.click.configMenu(); } } else if(lib.config.confirm_exit){ navigator.notification.confirm( '是否退出游戏?', function(index){ switch(index){ case 2:game.saveConfig('null');game.reload();break; case 3:navigator.app.exitApp();break; } }, '确认退出', ['取消','重新开始','退出'] ); } else{ navigator.app.exitApp(); } }); } game.download=function(url,folder,onsuccess,onerror,dev,onprogress){ if(!url.startsWith('http')){ url=get.url(dev)+url; } var fileTransfer = new FileTransfer(); folder=lib.assetURL+folder; if(onprogress){ fileTransfer.onprogress=function(progressEvent){ onprogress(progressEvent.loaded,progressEvent.total); }; } lib.config.brokenFile.add(folder); game.saveConfigValue('brokenFile'); fileTransfer.download(encodeURI(url),encodeURI(folder),function(){ lib.config.brokenFile.remove(folder); game.saveConfigValue('brokenFile'); if(onsuccess){ onsuccess(); } },onerror); }; game.readFile=function(filename,callback,onerror){ window.resolveLocalFileSystemURL(lib.assetURL,function(entry){ entry.getFile(filename,{},function(fileEntry){ fileEntry.file(function(fileToLoad){ var fileReader = new FileReader(); fileReader.onload = function(e){ callback(e.target.result); }; fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); },onerror); },onerror); },onerror); }; game.readFileAsText=function(filename,callback,onerror){ window.resolveLocalFileSystemURL(lib.assetURL,function(entry){ entry.getFile(filename,{},function(fileEntry){ fileEntry.file(function(fileToLoad){ var fileReader = new FileReader(); fileReader.onload = function(e){ callback(e.target.result); }; fileReader.readAsText(fileToLoad, "UTF-8"); },onerror); },onerror); },onerror); }; game.writeFile=function(data,path,name,callback){ game.ensureDirectory(path,function(){ if(Object.prototype.toString.call(data)=='[object File]'){ var fileReader = new FileReader(); fileReader.onload = function(e){ game.writeFile(e.target.result,path,name,callback); }; fileReader.readAsArrayBuffer(data, "UTF-8"); } else{ window.resolveLocalFileSystemURL(lib.assetURL+path,function(entry){ entry.getFile(name,{create:true},function(fileEntry){ fileEntry.createWriter(function(fileWriter){ fileWriter.onwriteend=callback; fileWriter.write(data); }); }); }); } }); }; game.removeFile=function(dir,callback){ window.resolveLocalFileSystemURL(lib.assetURL,function(entry){ entry.getFile(dir,{},function(fileEntry){ fileEntry.remove(); if(callback){ callback(); } }); }); }; game.getFileList=(dir,success,failure)=>{ var files=[],folders=[]; window.resolveLocalFileSystemURL(lib.assetURL+dir,entry=>{ var dirReader=entry.createReader(); var entries=[]; var readEntries=()=>{ dirReader.readEntries(results=>{ if(!results.length){ entries.sort(); for(var i=0;i<entries.length;i++){ if(entries[i].isDirectory){ folders.push(entries[i].name); } else{ files.push(entries[i].name); } } success(folders,files); } else{ entries=entries.concat(Array.from(results)); readEntries(); } },failure); }; readEntries(); },failure); }; game.ensureDirectory=(list,callback,file)=>{ const directoryList=typeof list=='string'?[list]:list.slice().reverse(),num=file?1:0,access=(entry,directory,createDirectory)=>{ if(directory.length<=num){ createDirectory(); return; } const str=directory.pop(); return new Promise((resolve,reject)=>entry.getDirectory(str,{ create:false },resolve,reject)).catch(()=>new Promise(resolve=>entry.getDirectory(str,{ create:true },resolve))).then(directoryEntry=>access(directoryEntry,directory,createDirectory)); }; return new Promise((resolve,reject)=>window.resolveLocalFileSystemURL(lib.assetURL,rootEntry=>{ const createDirectory=()=>{ if(directoryList.length) access(rootEntry,directoryList.pop().split('/').reverse(),createDirectory); if(typeof callback=='function') callback(); resolve(); }; createDirectory(); },reject)); }; if(ui.updateUpdate){ ui.updateUpdate(); } var showbar=function(){ if(window.StatusBar){ if(lib.device=='android'){ if(lib.config.show_statusbar_android){ window.StatusBar.overlaysWebView(false); window.StatusBar.backgroundColorByName('black'); window.StatusBar.show(); } } else if(lib.device=='ios'){ if(lib.config.show_statusbar_ios!='off'&&lib.config.show_statusbar_ios!='auto'){ if(lib.config.show_statusbar_ios=='default'){ window.StatusBar.overlaysWebView(false); } else{ window.StatusBar.overlaysWebView(true); } window.StatusBar.backgroundColorByName('black'); window.StatusBar.show(); } } } } if(lib.arenaReady){ lib.arenaReady.push(showbar); } else{ showbar(); } } } else if(typeof window.require=='function'){ lib.node={ fs:require('fs'), path:require("path"), debug:function(){ require('electron').remote.getCurrentWindow().toggleDevTools(); } }; lib.path=lib.node.path; game.download=function(url,folder,onsuccess,onerror,dev,onprogress){ if(!url.startsWith('http')){ url=get.url(dev)+url; } game.ensureDirectory(folder,function(){ try{ var file = lib.node.fs.createWriteStream(__dirname+'/'+folder); } catch(e){ onerror(); } lib.config.brokenFile.add(folder); game.saveConfigValue('brokenFile'); if(!lib.node.http) lib.node.http=require('http'); if(!lib.node.https) lib.node.https=require('https'); var opts = require('url').parse(encodeURI(url)); opts.headers={'User-Agent': 'AppleWebkit'}; (url.startsWith('https')?lib.node.https:lib.node.http).get(opts, function(response) { var stream=response.pipe(file); stream.on('finish',function(){ lib.config.brokenFile.remove(folder); game.saveConfigValue('brokenFile'); if(onsuccess){ onsuccess(); } }); stream.on('error',onerror); if(onprogress){ var streamInterval=setInterval(function(){ if(stream.closed){ clearInterval(streamInterval); } else{ onprogress(stream.bytesWritten); } },200); } }); },true); }; game.readFile=function(filename,callback,onerror){ lib.node.fs.readFile(__dirname+'/'+filename,function(err,data){ if(err){ onerror(err); } else{ callback(data); } }); }; game.readFileAsText=function(filename,callback,onerror){ lib.node.fs.readFile(__dirname+'/'+filename,'utf-8',function(err,data){ if(err){ onerror(err); } else{ callback(data); } }); }; game.writeFile=function(data,path,name,callback){ game.ensureDirectory(path,function(){ if(Object.prototype.toString.call(data)=='[object File]'){ var fileReader = new FileReader(); fileReader.onload = function(e){ game.writeFile(e.target.result,path,name,callback); }; fileReader.readAsArrayBuffer(data, "UTF-8"); } else{ get.zip(function(zip){ zip.file('i',data); lib.node.fs.writeFile(__dirname+'/'+path+'/'+name,zip.files.i.asNodeBuffer(),null,callback); }); } }); }; game.removeFile=function(filename,callback){ lib.node.fs.unlink(__dirname+'/'+filename,callback||function(){}); }; game.getFileList=(dir,success,failure)=>{ var files=[],folders=[]; dir=__dirname+'/'+dir; if(typeof failure=="undefined"){ failure=err=>{ throw err; }; } else if(failure == null){ failure=()=>{}; } try{ lib.node.fs.readdir(dir,(err,filelist)=>{ if(err){ failure(err); return; } for(var i=0;i<filelist.length;i++){ if(filelist[i][0]!='.'&&filelist[i][0]!='_'){ if(lib.node.fs.statSync(dir+'/'+filelist[i]).isDirectory()){ folders.push(filelist[i]); } else{ files.push(filelist[i]); } } } success(folders,files); }); } catch(e){ failure(e); } }; game.ensureDirectory=(list,callback,file)=>{ const directoryList=typeof list=='string'?[list]:list.slice().reverse(),number=file?1:0,access=(path,directory,createDirectory)=>{ if(directory.length<=number){ createDirectory(); return; } path+=`/${directory.pop()}`; const fullPath=`${__dirname}${path}`; return new Promise((resolve,reject)=>lib.node.fs.access(fullPath,errnoException=>{ if(errnoException) reject(); else resolve(); })).catch(()=>new Promise((resolve,reject)=>lib.node.fs.mkdir(fullPath,errnoException=>{ if(errnoException) reject(errnoException); else resolve(); }))).then(()=>access(path,directory,createDirectory),console.log); }; return new Promise(resolve=>{ const createDirectory=()=>{ if(directoryList.length) access('',directoryList.pop().split('/').reverse(),createDirectory); else{ if(typeof callback=='function') callback(); resolve(); } }; createDirectory(); }); }; if(ui.updateUpdate){ ui.updateUpdate(); } } else{ window.onbeforeunload=function(){ if(lib.config.confirm_exit&&!_status.reloading){ return '是否离开游戏?' } else{ return null; } } } lib.config=window.config; lib.configOL={}; delete window.config; let config2; if(localStorage.getItem(`${lib.configprefix}nodb`)) window.nodb=true; if(window.indexedDB&&!window.nodb) new Promise((resolve,reject)=>{ const idbOpenDBRequest=window.indexedDB.open(`${lib.configprefix}data`,4); idbOpenDBRequest.onerror=reject; idbOpenDBRequest.onsuccess=resolve; idbOpenDBRequest.onupgradeneeded=idbVersionChangeEvent=>{ 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'); }; }).then(event=>{ lib.db=event.target.result; return game.getDB('config'); }).then(object=>{ if(!object.storageImported){ try{ config2=JSON.parse(localStorage.getItem(`${lib.configprefix}config`)); if(!config2||typeof config2!='object') throw 'err'; } catch(err){ config2={}; } Object.keys(config2).forEach(key=>game.saveConfig(key,config2[key])); Object.keys(lib.mode).forEach(key=>{ try{ config2=JSON.parse(localStorage.getItem(`${lib.configprefix}${key}`)); if(!config2||typeof config2!='object'||get.is.empty(config2)) throw 'err'; } catch(err){ config2=false; } localStorage.removeItem(`${lib.configprefix}${key}`); if(config2) game.putDB('data',key,config2); }); game.saveConfig('storageImported',true); lib.init.background(); localStorage.removeItem(`${lib.configprefix}config`); } else config2=object; proceed(config2); }); else{ try{ config2=JSON.parse(localStorage.getItem(lib.configprefix+'config')); if(!config2||typeof config2!='object') throw 'err' } catch(err){ config2={}; localStorage.setItem(lib.configprefix+'config',JSON.stringify({})); } proceed(config2); } }, reset:function(){ if(window.inSplash) return; if(window.resetExtension){ if(confirm('游戏似乎未正常载入,有可能因为部分扩展未正常载入,或者因为部分扩展未载入完毕。\n是否禁用扩展并重新打开?')){ window.resetExtension(); window.location.reload(); } } else{ if(lib.device){ if(navigator.notification){ navigator.notification.confirm( '游戏似乎未正常载入,是否重置游戏?', function(index){ if(index==2){ localStorage.removeItem('noname_inited'); window.location.reload(); } else if(index==3){ 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'); setTimeout(function(){ window.location.reload(); },200); } }, '确认退出', ['取消','重新下载','重置设置'] ); } else{ if(confirm('游戏似乎未正常载入,是否重置游戏?')){ localStorage.removeItem('noname_inited'); window.location.reload(); } } } else{ if(confirm('游戏似乎未正常载入,是否重置游戏?')){ var onlineKey=localStorage.getItem(lib.configprefix+'key'); localStorage.clear(); if(onlineKey){ localStorage.setItem(lib.configprefix+'key',onlineKey); } if(indexedDB) indexedDB.deleteDatabase(lib.configprefix+'data'); setTimeout(function(){ window.location.reload(); },200); } } } }, //lib.onload支持传入GeneratorFunction以解决异步函数的问题 by诗笺 onload:gnc.of(function*(){ const libOnload=lib.onload; delete lib.onload; while(Array.isArray(libOnload)&&libOnload.length){ const fun=libOnload.shift(); if(typeof fun!="function") continue; yield (gnc.is.generatorFunc(fun)?gnc.of(fun):fun)(); } ui.updated(); game.documentZoom=game.deviceZoom; if(game.documentZoom!=1){ ui.updatez(); } ui.background=ui.create.div('.background'); ui.background.style.backgroundSize="cover"; ui.background.style.backgroundPosition='50% 50%'; if(lib.config.image_background&&lib.config.image_background!='default'&&!lib.config.image_background.startsWith('custom_')){ ui.background.setBackgroundImage('image/background/'+lib.config.image_background+'.jpg'); if(lib.config.image_background_blur){ ui.background.style.filter='blur(8px)'; ui.background.style.webkitFilter='blur(8px)'; ui.background.style.transform='scale(1.05)'; } } document.documentElement.style.backgroundImage=''; document.documentElement.style.backgroundSize=''; document.documentElement.style.backgroundPosition=''; document.body.insertBefore(ui.background,document.body.firstChild); document.body.onresize=ui.updatexr; if(lib.config.touchscreen){ document.body.addEventListener('touchstart',function(e){ this.startX=e.touches[0].clientX/game.documentZoom; this.startY=e.touches[0].clientY/game.documentZoom; _status.dragged=false; }); document.body.addEventListener('touchmove',function(e){ if(_status.dragged) return; 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(lib.config.image_background.startsWith('custom_')){ ui.background.style.backgroundImage="none"; game.getDB('image',lib.config.image_background,function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { var data = fileLoadedEvent.target.result; ui.background.style.backgroundImage='url('+data+')'; if(lib.config.image_background_blur){ ui.background.style.filter='blur(8px)'; ui.background.style.webkitFilter='blur(8px)'; ui.background.style.transform='scale(1.05)'; } }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } if(lib.config.card_style=='custom'){ game.getDB('image','card_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.card_stylesheet){ ui.css.card_stylesheet.remove(); } ui.css.card_stylesheet=lib.init.sheet('.card:not(*:empty){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } if(lib.config.cardback_style=='custom'){ game.getDB('image','cardback_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.cardback_stylesheet){ ui.css.cardback_stylesheet.remove(); } ui.css.cardback_stylesheet=lib.init.sheet('.card:empty,.card.infohidden{background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); game.getDB('image','cardback_style2',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.cardback_stylesheet2){ ui.css.cardback_stylesheet2.remove(); } ui.css.cardback_stylesheet2=lib.init.sheet('.card.infohidden:not(.infoflip){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } if(lib.config.hp_style=='custom'){ game.getDB('image','hp_style1',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.hp_stylesheet1){ ui.css.hp_stylesheet1.remove(); } ui.css.hp_stylesheet1=lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="high"]>div:not(.lost){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); game.getDB('image','hp_style2',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.hp_stylesheet2){ ui.css.hp_stylesheet2.remove(); } ui.css.hp_stylesheet2=lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="mid"]>div:not(.lost){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); game.getDB('image','hp_style3',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.hp_stylesheet3){ ui.css.hp_stylesheet3.remove(); } ui.css.hp_stylesheet3=lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="low"]>div:not(.lost){background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); game.getDB('image','hp_style4',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.hp_stylesheet4){ ui.css.hp_stylesheet4.remove(); } ui.css.hp_stylesheet4=lib.init.sheet('.hp:not(.text):not(.actcount)>.lost{background-image:url('+fileLoadedEvent.target.result+')}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } if(lib.config.player_style=='custom'){ ui.css.player_stylesheet=lib.init.sheet('#window .player{background-image:none;background-size:100% 100%;}'); game.getDB('image','player_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.player_stylesheet){ ui.css.player_stylesheet.remove(); } ui.css.player_stylesheet=lib.init.sheet('#window .player{background-image:url("'+fileLoadedEvent.target.result+'");background-size:100% 100%;}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } if(lib.config.border_style=='custom'){ game.getDB('image','border_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.border_stylesheet){ ui.css.border_stylesheet.remove(); } ui.css.border_stylesheet=lib.init.sheet(); ui.css.border_stylesheet.sheet.insertRule('#window .player>.framebg{display:block;background-image:url("'+fileLoadedEvent.target.result+'")}',0); ui.css.border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}',0); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } if(lib.config.control_style=='custom'){ game.getDB('image','control_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.control_stylesheet){ ui.css.control_stylesheet.remove(); } ui.css.control_stylesheet=lib.init.sheet('#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:url("'+fileLoadedEvent.target.result+'")}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } if(lib.config.menu_style=='custom'){ game.getDB('image','menu_style',function(fileToLoad){ if(!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent){ if(ui.css.menu_stylesheet){ ui.css.menu_stylesheet.remove(); } ui.css.menu_stylesheet=lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:url("'+fileLoadedEvent.target.result+'");background-size:cover}'); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } var proceed2=gnc.of(function*(){ var mode=lib.imported.mode; var card=lib.imported.card; var character=lib.imported.character; var play=lib.imported.play; delete window.game; var i,j,k; for(i in mode[lib.config.mode].element){ if(!lib.element[i]) lib.element[i]=[]; for(j in mode[lib.config.mode].element[i]){ if(j=='init'){ if(!lib.element[i].inits) lib.element[i].inits=[]; lib.element[i].inits.push(mode[lib.config.mode].element[i][j]); } else{ lib.element[i][j]=mode[lib.config.mode].element[i][j]; } } } for(i in mode[lib.config.mode].ai){ if(typeof mode[lib.config.mode].ai[i]=='object'){ if(ai[i]==undefined) ai[i]={}; for(j in mode[lib.config.mode].ai[i]){ ai[i][j]=mode[lib.config.mode].ai[i][j]; } } else{ ai[i]=mode[lib.config.mode].ai[i]; } } for(i in mode[lib.config.mode].ui){ if(typeof mode[lib.config.mode].ui[i]=='object'){ if(ui[i]==undefined) ui[i]={}; for(j in mode[lib.config.mode].ui[i]){ ui[i][j]=mode[lib.config.mode].ui[i][j]; } } else{ ui[i]=mode[lib.config.mode].ui[i]; } } for(i in mode[lib.config.mode].game){ game[i]=mode[lib.config.mode].game[i]; } for(i in mode[lib.config.mode].get){ get[i]=mode[lib.config.mode].get[i]; } lib.init.start=mode[lib.config.mode].start; lib.init.startBefore=mode[lib.config.mode].startBefore; if(game.onwash){ lib.onwash.push(game.onwash); delete game.onwash; } if(game.onover){ lib.onover.push(game.onover); delete game.onover; } lib.config.banned=lib.config[lib.config.mode+'_banned']||[]; lib.config.bannedcards=lib.config[lib.config.mode+'_bannedcards']||[]; lib.rank=window.noname_character_rank; delete window.noname_character_rank; for(i in mode[lib.config.mode]){ if(i=='element') continue; if(i=='game') continue; if(i=='ai') continue; if(i=='ui') continue; if(i=='get') continue; if(i=='config') continue; if(i=='onreinit') continue; if(i=='start') continue; if(i=='startBefore') continue; if(lib[i]==undefined) lib[i]=(Array.isArray(mode[lib.config.mode][i]))?[]:{}; for(j in mode[lib.config.mode][i]){ lib[i][j]=mode[lib.config.mode][i][j]; } } if(typeof mode[lib.config.mode].init=='function'){ mode[lib.config.mode].init(); } var connectCharacterPack=[]; var connectCardPack=[]; for(i in character){ if(character[i].character){ const characterPack=lib.characterPack[i]; if(characterPack) Object.assign(characterPack,character[i].character); else lib.characterPack[i]=character[i].character; } for(j in character[i]){ if(j=='mode'||j=='forbid') continue; if(j=='connect'){ connectCharacterPack.push(i); continue; } if(j=='character'&&!lib.config.characters.contains(i)&&lib.config.mode!='connect'){ if(lib.config.mode=='chess'&&get.config('chess_mode')=='leader'&&get.config('chess_leader_allcharacter')){ for(k in character[i][j]){ lib.hiddenCharacters.push(k); } } else if(lib.config.mode!='boss'||i!='boss'){ continue; } } if(Array.isArray(lib[j])&&Array.isArray(character[i][j])){ lib[j].addArray(character[i][j]); 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].contains('boss')|| character[i][j][k][4].contains('hiddenboss')){ lib.config.forbidai.add(k); } if(lib.config.forbidai_user&&lib.config.forbidai_user.contains(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=='skill'&&k[0]=='_'&&(lib.config.mode!='connect'?(!lib.config.characters.contains(i)):(!character[i].connect))){ continue; } if(j=='translate'&&k==i){ lib[j][k+'_character_config']=character[i][j][k]; } else{ if(lib[j][k]==undefined){ if(j=='skill'&&!character[i][j][k].forceLoad&&lib.config.mode=='connect'&&!character[i].connect){ lib[j][k]={ nopop:character[i][j][k].nopop, derivation:character[i][j][k].derivation }; } else{ Object.defineProperty(lib[j],k,Object.getOwnPropertyDescriptor(character[i][j],k)); } if(j=='card'&&lib[j][k].derivation){ if(!lib.cardPack.mode_derivation){ lib.cardPack.mode_derivation=[k]; } else{ lib.cardPack.mode_derivation.push(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] ); } } } } } var connect_avatar_list=[]; for(var i in lib.character){ connect_avatar_list.push(i); } connect_avatar_list.sort(lib.sort.capt); for(var i=0;i<connect_avatar_list.length;i++){ var ia=connect_avatar_list[i]; lib.mode.connect.config.connect_avatar.item[ia]=lib.translate[ia]; } if(lib.config.mode!='connect'){ var pilecfg=lib.config.customcardpile[get.config('cardpilename')||'当前牌堆']; if(pilecfg){ lib.config.bannedpile=get.copy(pilecfg[0]||{}); lib.config.addedpile=get.copy(pilecfg[1]||{}); } else{ lib.config.bannedpile={}; lib.config.addedpile={}; } } else{ lib.cardPackList={}; } for(i in card){ const 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=='connect'){ connectCardPack.push(i); continue; } if(j=='list'){ if(lib.config.mode=='connect'){ const cardPackList=lib.cardPackList[i]; if(cardPackList) cardPackList.addArray(card[i][j]); else lib.cardPackList[i]=card[i][j]; } else{ if(lib.config.cards.contains(i)){ var pile; if(typeof card[i][j]=='function'){ pile=card[i][j](); } else{ pile=card[i][j]; } const cardPile=lib.cardPile[i]; if(cardPile) cardPile.addArray(pile); else lib.cardPile[i]=pile.slice(0); if(lib.config.bannedpile[i]){ for(var k=0;k<lib.config.bannedpile[i].length;k++){ pile[lib.config.bannedpile[i][k]]=null; } } for(var k=0;k<pile.length;k++){ if(!pile[k]){ pile.splice(k--,1); } } if(lib.config.addedpile[i]){ for(var k=0;k<lib.config.addedpile[i].length;k++){ pile.push(lib.config.addedpile[i][k]); } } lib.card.list.addArray(pile); } } } else{ for(k in card[i][j]){ if(j=='skill'&&k[0]=='_'&&!card[i][j][k].forceLoad&&(lib.config.mode!='connect'?(!lib.config.cards.contains(i)):(!card[i].connect))){ continue; } if(j=='translate'&&k==i){ lib[j][k+'_card_config']=card[i][j][k]; } else{ if(lib[j][k]==undefined){ if(j=='skill'&&!card[i][j][k].forceLoad&&lib.config.mode=='connect'&&!card[i].connect){ lib[j][k]={ nopop:card[i][j][k].nopop, derivation:card[i][j][k].derivation }; } else{ 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] ); } if(j=='card'&&lib[j][k].derivation){ if(!lib.cardPack.mode_derivation){ lib.cardPack.mode_derivation=[k]; } else{ lib.cardPack.mode_derivation.push(k); } } } } } } } if(lib.cardPack.mode_derivation){ for(var i=0;i<lib.cardPack.mode_derivation.length;i++){ if(typeof lib.card[lib.cardPack.mode_derivation[i]].derivation=='string'&&!lib.character[lib.card[lib.cardPack.mode_derivation[i]].derivation]){ lib.cardPack.mode_derivation.splice(i--,1); } else if(typeof lib.card[lib.cardPack.mode_derivation[i]].derivationpack=='string'&&!lib.config.cards.contains(lib.card[lib.cardPack.mode_derivation[i]].derivationpack)){ lib.cardPack.mode_derivation.splice(i--,1); } } if(lib.cardPack.mode_derivation.length==0){ delete lib.cardPack.mode_derivation; } } if(lib.config.mode!='connect'){ for(i in play){ if(lib.config.hiddenPlayPack.contains(i)) continue; if(play[i].forbid&&play[i].forbid.contains(lib.config.mode)) continue; if(play[i].mode&&play[i].mode.contains(lib.config.mode)==false) continue; for(j in play[i].element){ if(!lib.element[j]) lib.element[j]=[]; for(k in play[i].element[j]){ if(k=='init'){ if(!lib.element[j].inits) lib.element[j].inits=[]; lib.element[j].inits.push(play[i].element[j][k]); } else{ lib.element[j][k]=play[i].element[j][k]; } } } for(j in play[i].ui){ if(typeof play[i].ui[j]=='object'){ if(ui[j]==undefined) ui[j]={}; for(k in play[i].ui[j]){ ui[j][k]=play[i].ui[j][k]; } } else{ ui[j]=play[i].ui[j]; } } for(j in play[i].game){ game[j]=play[i].game[j]; } for(j in play[i].get){ get[j]=play[i].get[j]; } for(j in play[i]){ if(j=='mode'||j=='forbid'||j=='init'||j=='element'|| j=='game'||j=='get'||j=='ui'||j=='arenaReady') continue; for(k in play[i][j]){ if(j=='translate'&&k==i){ // lib[j][k+'_play_config']=play[i][j][k]; } else{ if(lib[j][k]!=undefined){ console.log( `dublicate ${j} in play ${i}:\n${k}:\nlib.${j}.${k}`, lib[j][k], `\nplay.${i}.${j}.${k}`, play[i][j][k] ); } lib[j][k]=play[i][j][k]; } } } if(typeof play[i].init=='function') play[i].init(); if(typeof play[i].arenaReady=='function') lib.arenaReady.push(play[i].arenaReady); } } lib.connectCharacterPack=[]; lib.connectCardPack=[]; for(var i=0;i<lib.config.all.characters.length;i++){ var packname=lib.config.all.characters[i]; if(connectCharacterPack.contains(packname)){ lib.connectCharacterPack.push(packname) } } for(var i=0;i<lib.config.all.cards.length;i++){ var packname=lib.config.all.cards[i]; if(connectCardPack.contains(packname)){ lib.connectCardPack.push(packname) } } if(lib.config.mode!='connect'){ for(i=0;i<lib.card.list.length;i++){ if(lib.card.list[i][2]=='huosha'){ lib.card.list[i]=lib.card.list[i].slice(0); lib.card.list[i][2]='sha'; lib.card.list[i][3]='fire'; } else if(lib.card.list[i][2]=='leisha'){ lib.card.list[i]=lib.card.list[i].slice(0); lib.card.list[i][2]='sha'; lib.card.list[i][3]='thunder'; } if(!lib.card[lib.card.list[i][2]]){ lib.card.list.splice(i,1);i--; } else if(lib.card[lib.card.list[i][2]].mode&& lib.card[lib.card.list[i][2]].mode.contains(lib.config.mode)==false){ lib.card.list.splice(i,1);i--; } } } if(lib.config.mode=='connect'){ _status.connectMode=true; } if(window.isNonameServer){ lib.cheat.i(); } else if(lib.config.dev&&(!_status.connectMode||lib.config.debug)){ lib.cheat.i(); } lib.config.sort_card=get.sortCard(lib.config.sort); delete lib.imported.character; delete lib.imported.card; delete lib.imported.mode; delete lib.imported.play; for(var i in lib.init){ if(i.startsWith('setMode_')){ delete lib.init[i]; } } if(!_status.connectMode){ for(var i=0;i<lib.extensions.length;i++){ try{ _status.extension=lib.extensions[i][0]; _status.evaluatingExtension=lib.extensions[i][3]; if (typeof lib.extensions[i][1]=="function") yield (gnc.is.coroutine(lib.extensions[i][1])?gnc.of(lib.extensions[i][1]):lib.extensions[i][1]).call(lib.extensions[i],lib.extensions[i][2],lib.extensions[i][4]); if(lib.extensions[i][4]){ if(lib.extensions[i][4].character){ for(var j in lib.extensions[i][4].character.character){ game.addCharacterPack(get.copy(lib.extensions[i][4].character)); break; } } if(lib.extensions[i][4].card){ for(var j in lib.extensions[i][4].card.card){ game.addCardPack(get.copy(lib.extensions[i][4].card)); break; } } if(lib.extensions[i][4].skill){ for(var j in lib.extensions[i][4].skill.skill){ game.addSkill(j,lib.extensions[i][4].skill.skill[j], lib.extensions[i][4].skill.translate[j], lib.extensions[i][4].skill.translate[j+'_info'], lib.extensions[i][4].skill.translate[j+'_append']); } } } delete _status.extension; delete _status.evaluatingExtension; } catch(e){ console.log(e); } } } delete lib.extensions; if(lib.init.startBefore){ lib.init.startBefore(); delete lib.init.startBefore; } ui.create.arena(); game.createEvent('game',false).setContent(lib.init.start); if(lib.mode[lib.config.mode]&&lib.mode[lib.config.mode].fromextension){ var startstr=mode[lib.config.mode].start.toString(); if(startstr.indexOf('onfree')==-1){ setTimeout(lib.init.onfree,500); } } delete lib.init.start; if(Array.isArray(_status.onprepare)&&_status.onprepare.length){ yield Promise.allSettled(_status.onprepare); delete _status.onprepare; } game.loop(); }) var proceed=gnc.of(function*(){ if(!lib.db){ try{ lib.storage=JSON.parse(localStorage.getItem(lib.configprefix+lib.config.mode)); if(typeof lib.storage!='object') throw('err'); if(lib.storage==null) throw('err'); } catch(err){ lib.storage={}; localStorage.setItem(lib.configprefix+lib.config.mode,"{}"); } yield proceed2(); } else{ game.getDB('data',lib.config.mode,function(obj){ lib.storage=obj||{}; proceed2(); }); } }); if(!lib.imported.mode||!lib.imported.mode[lib.config.mode]){ window.inSplash=true; clearTimeout(window.resetGameTimeout); delete window.resetGameTimeout; var clickedNode=false; var clickNode=function(){ if(clickedNode) return; this.classList.add('clicked'); clickedNode=true; lib.config.mode=this.link; game.saveConfig('mode',this.link); if(this.link=='connect'){ localStorage.setItem(lib.configprefix+'directstart',true); game.reload(); } else{ if(game.layout!='mobile'&&lib.layoutfixed.indexOf(lib.config.mode)!==-1){ game.layout='mobile'; ui.css.layout.href=lib.assetURL+'layout/'+game.layout+'/layout.css'; } else if(game.layout=='mobile'&&lib.config.layout!='mobile'&&lib.layoutfixed.indexOf(lib.config.mode)===-1){ game.layout=lib.config.layout; if(game.layout=='default'){ ui.css.layout.href=''; } else{ ui.css.layout.href=lib.assetURL+'layout/'+game.layout+'/layout.css'; } } splash.delete(1000); delete window.inSplash; window.resetGameTimeout=setTimeout(lib.init.reset,10000); this.listenTransition(function(){ lib.init.js(lib.assetURL+'mode',lib.config.mode,proceed); },500); } } var downNode=function(){ this.classList.add('glow'); } var upNode=function(){ this.classList.remove('glow'); } var splash=ui.create.div('#splash',document.body); if(lib.config.touchscreen){ splash.classList.add('touch'); lib.setScroll(splash); } if(lib.config.player_border!='wide'){ splash.classList.add('slim'); } splash.dataset.radius_size=lib.config.radius_size; for(var i=0;i<lib.config.all.mode.length;i++){ var node=ui.create.div('.hidden',splash,clickNode); node.link=lib.config.all.mode[i]; ui.create.div(node,'.splashtext',get.verticalStr(get.translation(lib.config.all.mode[i]))); if(lib.config.all.stockmode.includes(lib.config.all.mode[i])){ // 初始启动页设置 if(lib.config.splash_style==undefined) game.saveConfig('splash_style','style1'); splash.dataset.splash_style=lib.config.splash_style; // 扩展可通过window.splashurl设置素材读取路径 if(window.splashurl==undefined)window.splashurl='image/splash/'; if(lib.config.splash_style=='style1'||lib.config.splash_style=='style2'){ ui.create.div(node,'.avatar').setBackgroundImage('image/splash/'+lib.config.splash_style+'/'+lib.config.all.mode[i]+'.jpg'); }else{ ui.create.div(node,'.avatar').setBackgroundImage(splashurl+lib.config.splash_style+'/'+lib.config.all.mode[i]+'.jpg'); } } else{ var avatarnode=ui.create.div(node,'.avatar'); var avatarbg=lib.mode[lib.config.all.mode[i]].splash; if(avatarbg.startsWith('ext:')){ avatarnode.setBackgroundImage(avatarbg.replace(/^ext:/,'extension/')); } else{ avatarnode.setBackgroundDB(avatarbg); } } if(!lib.config.touchscreen){ node.addEventListener('mousedown',downNode); node.addEventListener('mouseup',upNode); node.addEventListener('mouseleave',upNode); } setTimeout((function(node){ return function(){ node.show(); } }(node)),i*100); } if(lib.config.mousewheel){ splash.onmousewheel=ui.click.mousewheel; } } else{ yield proceed(); } localStorage.removeItem(lib.configprefix+'directstart'); delete lib.init.init; const libOnload2=lib.onload2; delete lib.onload2; while(Array.isArray(libOnload2)&&libOnload2.length){ const fun=libOnload2.shift(); if(typeof fun!="function") continue; yield (gnc.is.generatorFunc(fun)?gnc.of(fun):fun)(); } }), startOnline:function(){ 'step 0' event._resultid=null; event._result=null; game.pause(); 'step 1' if(result){ if(event._resultid){ result.id=event._resultid; } game.send('result',result); } event.goto(0); }, onfree:function(){ if(lib.onfree){ clearTimeout(window.resetGameTimeout); delete window.resetGameTimeout; if(!game.syncMenu){ delete window.resetExtension; localStorage.removeItem(lib.configprefix+'disable_extension'); } if(game.removeFile&&lib.config.brokenFile.length){ while(lib.config.brokenFile.length){ game.removeFile(lib.config.brokenFile.shift()); } game.saveConfigValue('brokenFile'); } var onfree=lib.onfree; delete lib.onfree; var loop=function(){ if(onfree.length){ (onfree.shift())(); setTimeout(loop,100); } }; setTimeout(loop,500); if(!_status.new_tutorial) game.saveConfig('menu_loadondemand',true,lib.config.mode); } }, connection:function(ws){ var client={ ws:ws, id:ws.wsid||get.id(), closed:false }; lib.node.clients.push(client); for(var i in lib.element.client){ client[i]=lib.element.client[i]; } if(window.isNonameServer){ document.querySelector('#server_count').innerHTML=lib.node.clients.length; } ws.on('message',function(messagestr){ var message; try{ message=JSON.parse(messagestr); if(!Array.isArray(message)|| typeof lib.message.server[message[0]]!=='function'){ throw('err'); } for(var i=1;i<message.length;i++){ message[i]=get.parsedResult(message[i]); } } catch(e){ console.log(e); console.log('invalid message: '+messagestr); return; } lib.message.server[message.shift()].apply(client,message); }); ws.on('close',function(){ client.close(); }); client.send('opened'); }, sheet:function(){ var style=document.createElement('style'); document.head.appendChild(style); for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='string'){ style.sheet.insertRule(arguments[i],0); } } return style; }, css:(path,file,before)=>{ const style=document.createElement("link"); style.rel="stylesheet"; if(path){ if(path[path.length-1]=='/') path=path.slice(0,path.length-1); if(file) path=`${path}${/^db:extension-[^:]*$/.test(path)?':':'/'}${file}.css`; (path.startsWith('db:')?game.getDB('image',path.slice(3)).then(get.objectURL):new Promise(resolve=>resolve(path))).then(resolvedPath=>{ style.href=resolvedPath; if(typeof before=='function'){ style.addEventListener('load',before); document.head.appendChild(style); } else if(before) document.head.insertBefore(style,before); else document.head.appendChild(style); }); } return style; }, //在扩展的precontent中调用,用于加载扩展必需的JS文件。 //If any of the parameters is an Array, corresponding files will be loaded in order //如果任意参数为数组,则按顺序加载加载相应的文件 jsForExtension:(path,file,onLoad,onError)=>{ if(!_status.javaScriptExtensions) _status.javaScriptExtensions=[]; _status.javaScriptExtensions.push({ path:path, file:file, onLoad:onLoad, onError:onError }); }, js:(path,file,onLoad,onError)=>{ if(path[path.length-1]=='/') path=path.slice(0,path.length-1); if(path==`${lib.assetURL}mode`&&lib.config.all.stockmode.indexOf(file)==-1){ lib.genAwait(lib.init[`setMode_${file}`]()).then(onLoad); return; } if(Array.isArray(file)){ file.forEach(value=>lib.init.js(path,value,onLoad,onError)); return; } let scriptSource=file?`${path}${/^db:extension-[^:]*$/.test(path)?':':'/'}${file}.js`:path; if(path.startsWith('http')) scriptSource+=`?rand=${get.id()}`; else if(lib.config.fuck_sojson&&scriptSource.includes('extension')!=-1&&scriptSource.startsWith(lib.assetURL)){ const pathToRead=scriptSource.slice(lib.assetURL.length); const alertMessage=`检测到您安装了使用免费版sojson进行加密的扩展。请谨慎使用这些扩展,避免游戏数据遭到破坏。\n扩展文件:${pathToRead}`; if(typeof game.readFileAsText=='function') game.readFileAsText(pathToRead,result=>{ if(result.includes('sojson')||result.includes('jsjiami')||result.includes('var _0x')) alert(alertMessage); },()=>void 0); else if(location.origin!='file://') lib.init.reqSync(pathToRead,function(){ const result = this.responseText; if(result.includes('sojson')||result.includes('jsjiami')||result.includes('var _0x')) alert(alertMessage); },()=>void 0); } const script=document.createElement('script'); (scriptSource.startsWith('db:')?game.getDB('image',scriptSource.slice(3)).then(get.objectURL):new Promise(resolve=>resolve(scriptSource))).then(resolvedScriptSource=>{ script.src=resolvedScriptSource; if(path.startsWith('http')) script.addEventListener('load',()=>script.remove()); document.head.appendChild(script); if(typeof onLoad=='function') script.addEventListener('load',onLoad); if(typeof onError=='function') script.addEventListener('error',onError); }); return script; }, /** * 同步lib.init.js * @returns { void } */ jsSync:(path,file,onLoad,onError)=>{ if(lib.assetURL.length==0&&location.origin=='file://'&&typeof game.readFile=='undefined'){ const e=new Error('浏览器file协议下无法使用此api,请在http/https协议下使用此api'); if(typeof onError=='function') onError(e); else throw e; return; } if(path[path.length-1]=='/') path=path.slice(0,path.length-1); if(path==`${lib.assetURL}mode`&&lib.config.all.stockmode.indexOf(file)==-1){ lib.genAwait(lib.init[`setMode_${file}`]()).then(onLoad); return; } if(Array.isArray(file)){ return file.forEach(value=>lib.init.js(path,value,onLoad,onError)); } let scriptSource; if(!file) scriptSource=path; else scriptSource=`${path}/${file}.js`; if(path.startsWith('http')) scriptSource+=`?rand=${get.id()}`; const xmlHttpRequest=new XMLHttpRequest(); let data; xmlHttpRequest.addEventListener("load",()=>{ data=xmlHttpRequest.responseText; if(!data) { if(typeof onError=='function') onError(new Error(`${scriptSource}加载失败!`)); return; } if(lib.config.fuck_sojson&&scriptSource.includes('extension')!=-1&&scriptSource.startsWith(lib.assetURL)){ const pathToRead=scriptSource.slice(lib.assetURL.length); if(data.includes('sojson')||data.includes('jsjiami')||data.includes('var _0x')) alert(`检测到您安装了使用免费版sojson进行加密的扩展。请谨慎使用这些扩展,避免游戏数据遭到破坏。\n扩展文件:${pathToRead}`); } try{ window.eval(data); if(typeof onLoad=='function') onLoad(); } catch(error){ if(typeof onError=='function') onError(error); } }); if(typeof onError=='function') xmlHttpRequest.addEventListener("error",onError); xmlHttpRequest.open("GET",scriptSource,false); xmlHttpRequest.send(); }, req:(str,onload,onerror,master)=>{ let sScriptURL; if(str.startsWith('http')) sScriptURL=str; else if(str.startsWith('local:')){ if(lib.assetURL.length==0&&location.origin=='file://'&&typeof game.readFile=='undefined'){ const e=new Error('浏览器file协议下无法使用此api,请在http/https协议下使用此api'); if(typeof onerror=='function') onerror(e); else throw e; return; } sScriptURL=lib.assetURL+str.slice(6); } else{ let url=get.url(master); if(url[url.length-1]!='/') url+='/'; sScriptURL=url+str; } const oReq=new XMLHttpRequest(); if(typeof onload=='function') oReq.addEventListener("load",onload); if(typeof onerror=='function') oReq.addEventListener("error",onerror); oReq.open("GET",sScriptURL); oReq.send(); }, /** * 同步lib.init.req */ reqSync:(str,onload,onerror,master)=>{ let sScriptURL; if(str.startsWith('http')) sScriptURL=str; else if(str.startsWith('local:')){ if(lib.assetURL.length==0&&location.origin=='file://'&&typeof game.readFile=='undefined'){ const e=new Error('浏览器file协议下无法使用此api,请在http/https协议下使用此api'); if(typeof onerror=='function') onerror(e); else throw e; return; } sScriptURL=lib.assetURL+str.slice(6); } else{ let url=get.url(master); if(url[url.length-1]!='/')url+='/'; sScriptURL=url+str; } const oReq=new XMLHttpRequest(); if(typeof onload=='function') oReq.addEventListener("load",onload); if(typeof onerror=='function') oReq.addEventListener("error",onerror); oReq.open("GET",sScriptURL,false); oReq.send(); if(typeof onload!=='function') return oReq.responseText; }, json:(url,onload,onerror)=>{ const oReq=new XMLHttpRequest(); if(typeof onload=='function') oReq.addEventListener("load",()=>{ let result; try{ result=JSON.parse(oReq.responseText); if(!result) throw('err'); } catch(e){ if(typeof onerror=='function') onerror(e); return; } onload(result); }); if(typeof onerror=='function') oReq.addEventListener("error",onerror); oReq.open("GET",url); oReq.send(); }, /** * 同步lib.init.json */ jsonSync:(url,onload,onerror)=>{ if(lib.assetURL.length==0&&location.origin=='file://'&&typeof game.readFile=='undefined'){ const e=new Error('浏览器file协议下无法使用此api,请在http/https协议下使用此api'); if(typeof onerror=='function') onerror(e); else throw e; return; } const oReq=new XMLHttpRequest(); if(typeof onload=='function') oReq.addEventListener("load",()=>{ let result; try{ result=JSON.parse(oReq.responseText); if(!result) throw('err'); } catch(e){ if(typeof onerror=='function') onerror(e); return; } onload(result); }); if(typeof onerror=='function') oReq.addEventListener("error",onerror); oReq.open("GET",url,false); oReq.send(); }, cssstyles:function(){ if(ui.css.styles){ ui.css.styles.remove(); } ui.css.styles=lib.init.sheet(); ui.css.styles.sheet.insertRule('#arena .player>.name,#arena .button.character>.name {font-family: '+(lib.config.name_font||'xinwei')+',xinwei}',0); ui.css.styles.sheet.insertRule('#arena .player>.name,.button.character>.name {font-family: '+(lib.config.name_font||'xinwei')+',xinwei}',0); ui.css.styles.sheet.insertRule('#arena .player .identity>div {font-family: '+(lib.config.identity_font||'huangcao')+',xinwei}',0); ui.css.styles.sheet.insertRule('.button.character.newstyle>.identity {font-family: '+(lib.config.identity_font||'huangcao')+',xinwei}',0); if(lib.config.cardtext_font&&lib.config.cardtext_font!='default'){ ui.css.styles.sheet.insertRule('.card div:not(.info):not(.background) {font-family: '+lib.config.cardtext_font+';}',0); } if(lib.config.global_font&&lib.config.global_font!='default'){ ui.css.styles.sheet.insertRule('#window {font-family: '+lib.config.global_font+',xinwei}',0); ui.css.styles.sheet.insertRule('#window #control{font-family: STHeiti,SimHei,Microsoft JhengHei,Microsoft YaHei,WenQuanYi Micro Hei,Suits,Helvetica,Arial,sans-serif}',0); } switch(lib.config.glow_phase){ case 'yellow':ui.css.styles.sheet.insertRule('#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgb(217, 152, 62) 0 0 15px, rgb(217, 152, 62) 0 0 15px !important;}',0);break; case 'green':ui.css.styles.sheet.insertRule('#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(10, 155, 67, 1) 0 0 15px, rgba(10, 155, 67, 1) 0 0 15px !important;}',0);break; case 'purple':ui.css.styles.sheet.insertRule('#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgb(189, 62, 170) 0 0 15px, rgb(189, 62, 170) 0 0 15px !important;}',0);break; } }, layout:function(layout,nosave){ if(layout=='default') layout='mobile'; if(!nosave) game.saveConfig('layout',layout); game.layout=layout; ui.arena.hide(); setTimeout(function(){ if(game.layout=='default'){ ui.css.layout.href=''; } else{ ui.css.layout.href=lib.assetURL+'layout/'+game.layout+'/layout.css'; } if(game.layout=='mobile'||game.layout=='long'){ ui.arena.classList.add('mobile'); } else{ ui.arena.classList.remove('mobile'); } if(game.layout=='mobile'||game.layout=='long'||game.layout=='long2'||game.layout=='nova'){ if(game.me&&game.me.node.handcards2.childNodes.length){ while(game.me.node.handcards2.childNodes.length){ game.me.node.handcards1.appendChild(game.me.node.handcards2.firstChild); } } } if(game.layout=='default'){ ui.arena.classList.add('oldlayout'); } else{ ui.arena.classList.remove('oldlayout'); } if(lib.config.cardshape=='oblong'&&(game.layout=='long'||game.layout=='mobile'||game.layout=='long2'||game.layout=='nova')){ ui.arena.classList.add('oblongcard'); ui.window.classList.add('oblongcard'); } else{ ui.arena.classList.remove('oblongcard'); ui.window.classList.remove('oblongcard'); } //if(lib.config.textequip=='text'&&(game.layout=='long'||game.layout=='mobile')){ if(game.layout=='long'||game.layout=='mobile'){ ui.arena.classList.add('textequip'); } else{ ui.arena.classList.remove('textequip'); } if(get.is.phoneLayout()){ ui.css.phone.href=lib.assetURL+'layout/default/phone.css'; ui.arena.classList.add('phone'); } else{ ui.css.phone.href=''; ui.arena.classList.remove('phone'); } for(var i=0;i<game.players.length;i++){ if(get.is.linked2(game.players[i])){ if(game.players[i].classList.contains('linked')){ game.players[i].classList.remove('linked'); game.players[i].classList.add('linked2'); } } else{ if(game.players[i].classList.contains('linked2')){ game.players[i].classList.remove('linked2'); game.players[i].classList.add('linked'); } } } if(game.layout=='long'||game.layout=='long2'){ ui.arena.classList.add('long'); } else{ ui.arena.classList.remove('long'); } if(lib.config.player_border!='wide'||game.layout=='long'||game.layout=='long2'){ ui.arena.classList.add('slim_player'); } else{ ui.arena.classList.remove('slim_player'); } if(lib.config.player_border=='normal'&&lib.config.mode!='brawl'&&(game.layout=='long'||game.layout=='long2')){ ui.arena.classList.add('lslim_player'); } else{ ui.arena.classList.remove('lslim_player'); } if(lib.config.player_border=='slim'){ ui.arena.classList.add('uslim_player'); } else{ ui.arena.classList.remove('uslim_player'); } if(lib.config.player_border=='narrow'){ ui.arena.classList.add('mslim_player'); } else{ ui.arena.classList.remove('mslim_player'); } ui.updatej(); ui.updatem(); setTimeout(function(){ ui.arena.show(); if(game.me) game.me.update(); setTimeout(function(){ ui.updatex(); },500); setTimeout(function(){ ui.updatec(); },1000); },100); },500); }, background:function(){ if(lib.config.image_background_random){ var list=[]; for(var i in lib.configMenu.appearence.config.image_background.item){ if(i=='default') continue; list.push(i); } list.remove(lib.config.image_background); localStorage.setItem(lib.configprefix+'background',JSON.stringify(list)); } else if(lib.config.image_background&&lib.config.image_background!='default'&&!lib.config.image_background.startsWith('custom_')){ localStorage.setItem(lib.configprefix+'background',lib.config.image_background); } else if(lib.config.image_background=='default'&&lib.config.theme=='simple'){ localStorage.setItem(lib.configprefix+'background','ol_bg'); } else{ localStorage.removeItem(lib.configprefix+'background'); } }, parsex:function(item){ //by 诗笺、Tipx-L function Legacy(func){ //Remove all comments //移除所有注释 var str=func.toString().replace(/((?:(?:^[ \t]*)?(?:\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\/(?:[ \t]*\r?\n(?=[ \t]*(?:\r?\n|\/\*|\/\/)))?|\/\/(?:[^\\]|\\(?:\r?\n)?)*?(?:\r?\n(?=[ \t]*(?:\r?\n|\/\*|\/\/))|(?=\r?\n))))+)|("(?:\\[\s\S]|[^"\\])*"|'(?:\\[\s\S]|[^'\\])*'|(?:\r?\n|[\s\S])[^\/"'\\\s]*)/mg,'$2').trim(); //获取第一个 { 后的所有字符 str=str.slice(str.indexOf('{')+1); //func中要写步骤的话,必须要写step 0 if(str.indexOf('step 0')==-1){ str='{if(event.step==1) {event.finish();return;}\n'+str; }else{ var skip=0; //每层最多找99个step for (var k=0;k<99;k++) { //正则表达式 var reg=new RegExp(`['"]step ${k}['"]`); var result=str.slice(skip).match(reg); if(result==null) break; var insertStr; if(k==0){ insertStr=`switch(step){case 0:`; }else{ insertStr=`break;case ${k}:`; } var copy=str; copy=copy.slice(0,skip+result.index)+insertStr+copy.slice(skip+result.index+result[0].length); //测试是否有错误 try{ new Function(copy); str=copy; skip+=result.index+insertStr.length; }catch(error){ k--; skip+=result.index+result[0].length; } } str=`if(event.step==${k}){event.finish();return;}`+str; } return (new Function('event','step','source','player','target','targets', 'card','cards','skill','forced','num','trigger','result', '_status','lib','game','ui','get','ai',str)); } switch(typeof item){ case "object": if(Array.isArray(item)){ let lastEvent=null; return (event,step,source,player,target,targets,card,cards,skill,forced,num,trigger,result,_status,lib,game,ui,get,ai)=>{ if(step>=item.length) return event.finish(); var current=item[step]; lastEvent=current(event,{ event:event, step:step, source:source, player:player, target:target, targets:targets, card:card, cards:cards, skill:skill, forced:forced, num:num, trigger:trigger, result:result },(lastEvent&&("result" in lastEvent))?lastEvent.result:null); } } else{ if(Symbol.iterator in item) return lib.init.parsex(Array.from(item)); if("toString" in item) return lib.init.parsex(item.toString()); if("render" in item) { // TODO: Object Render Parse throw new Error("NYI: Object Render Parse"); } // TODO: Object Other Parse throw new Error("NYI: Object Other Parse"); } case "function": if (gnc.is.generatorFunc(item)) { let gen,lastEvent; return (event,step,source,player,target,targets,card,cards,skill,forced,num,trigger,result,_status,lib,game,ui,get,ai)=>{ if(!gen)gen=item(event,{ event:event, step:step, source:source, player:player, target:target, targets:targets, card:card, cards:cards, skill:skill, forced:forced, num:num, trigger:trigger, result:result }); var res=gen.next((lastEvent&&("result" in lastEvent))?lastEvent.result:null); if(res.done) event.finish(); else lastEvent=res.value; } } default: return Legacy(item); } }, eval:function(func){ if(typeof func=='function'){ return eval('('+func.toString()+')'); } else if(typeof func=='object'){ for(var i in func){ if(func.hasOwnProperty(i)){ func[i]=lib.init.eval(func[i]); } } } return func; }, encode:function(strUni){ var strUtf = strUni.replace( /[\u0080-\u07ff]/g,function(c){ var cc = c.charCodeAt(0); return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }); strUtf = strUtf.replace( /[\u0800-\uffff]/g,function(c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }); return btoa(strUtf); }, decode:function(str){ var strUtf=atob(str); var strUni = strUtf.replace( /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,function(c) { var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f); return String.fromCharCode(cc); }); strUni = strUni.replace( /[\u00c0-\u00df][\u0080-\u00bf]/g,function(c){ var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f; return String.fromCharCode(cc); }); return strUni; }, stringify:function(obj){ var str='{' for(var i in obj){ str+='"'+i+'":' if(Object.prototype.toString.call(obj[i])=='[object Object]'){ str+=lib.init.stringify(obj[i]); } else if(typeof obj[i]=='function'){ str+=obj[i].toString(); } else{ str+=JSON.stringify(obj[i]); } str+=',' } str+='}'; return str; }, stringifySkill:function(obj){ var str=''; for(var i in obj){ str+=i+':' if(Object.prototype.toString.call(obj[i])=='[object Object]'){ str+='{\n'+lib.init.stringifySkill(obj[i])+'}'; } else if(typeof obj[i]=='function'){ str+=obj[i].toString().replace(/\t/g,''); } else{ str+=JSON.stringify(obj[i]); } str+=',\n' } return str; } }, cheat:{ i:function(){ window.cheat=lib.cheat; window.game=game; window.ui=ui; window.get=get; window.ai=ai; window.lib=lib; window._status=_status; }, dy:function(){ var next=game.me.next; for(var i=0;i<10;i++){ if(next.identity!='zhu'){ break; } next=next.next; } next.die(); }, x:function(){ var gl=function(dir,callback){ var files=[],folders=[]; dir='/Users/widget/Documents/extension/'+dir; lib.node.fs.readdir(dir,function(err,filelist){ for(var i=0;i<filelist.length;i++){ if(filelist[i][0]!='.'&&filelist[i][0]!='_'){ if(lib.node.fs.statSync(dir+'/'+filelist[i]).isDirectory()){ folders.push(filelist[i]); } else{ files.push(filelist[i]); } } } callback(folders,files); }); } var args=Array.from(arguments); for(var i=0;i<args.length;i++){ args[i]=args[i][0]; } gl('',function(list){ if(args.length){ for(var i=0;i<list.length;i++){ if(!args.contains(list[i][0])){ list.splice(i--,1); } } } if(list.length){ for(var i=0;i<list.length;i++){ (function(str){ gl(str,function(folders,files){ if(files.length>1){ for(var i=0;i<files.length;i++){ if(files[i].includes('extension.js')){ files.splice(i--,1); } else{ if(i%5==0){ str+='\n\t\t\t'; } str+='"'+files[i]+'",'; } } console.log(str.slice(0,str.length-1)); } }); }(list[i])); } } }); }, cfg:function(){ var mode=lib.config.all.mode.slice(0); mode.remove('connect'); mode.remove('brawl'); var banned=['shen_guanyu','shen_caocao','caopi','re_daqiao','caorui', 'daqiao','lingcao','liuzan','lusu','luxun','yanwen','zhouyu','ns_wangyue','gw_yenaifa', 'old_caozhen','swd_jiangziya','xuhuang','maliang','guojia','simayi','swd_kangnalishi','hs_siwangzhiyi','hs_nozdormu','old_zhuzhi']; var bannedcards=['zengbin']; var favs=["hs_tuoqi","hs_siwangxianzhi","hs_xukongzhiying","hs_hsjiasha","gjqt_xieyi","gjqt_yunwuyue","gjqt_beiluo", "gjqt_cenying","shen_lvmeng","shen_zhaoyun","shen_zhugeliang","ow_ana","chenlin","ns_guanlu","hs_guldan","swd_guyue", "pal_jiangyunfan","mtg_jiesi","swd_lanyin","pal_liumengli","swd_muyun","pal_nangonghuang","swd_muyue","pal_murongziying", "swd_qiner","pal_shenqishuang","hs_taisi","wangji","pal_xingxuan","xunyou","hs_yelise","pal_yuejinzhao","pal_yueqi", "gjqt_yuewuyi","swd_yuxiaoxue","ow_zhaliya","zhangchunhua","hs_zhihuanhua","swd_zhiyin","old_zhonghui","gjqt_bailitusu", "hs_barnes","ow_dva","swd_hengai","pal_jushifang","hs_kazhakusi","hs_lafamu","ow_liekong","hs_lreno","pal_mingxiu", "swd_murongshi","gw_oudimu","gjqt_ouyangshaogong","hs_pyros","qinmi","gw_sanhanya","hs_selajin","swd_shuwaner", "swd_situqiang","hs_xialikeer","pal_xuejian","swd_yuchiyanhong","swd_yuwentuo","swd_zhaoyun","zhugeliang","gw_aigeleisi", "gw_aimin","gjqt_aruan","hs_aya","swd_cheyun","swd_chenjingchou","gw_diandian","swd_huzhongxian","hs_jinglinglong", "hs_kaituozhe","hs_kalimosi","gw_linjing","ow_luxiao","re_luxun","hs_morgl","swd_sikongyu","hs_sthrall","sunquan", "sunshangxiang","gw_yioufeisisp","gw_yisilinni","hs_yogg","hs_ysera","pal_yuntianhe","zhugejin","zhugeke","gw_zhuoertan", "hs_anduin","swd_anka","ow_banzang","ow_chanyata","diaochan","swd_duguningke","sp_diaochan","hetaihou","ns_huamulan", "swd_huanglei","swd_huanyuanzhi","re_huatuo","gw_huoge","pal_jiangcheng","yj_jushou","swd_kendi","yxs_libai", "mtg_lilianna","xin_liru","liuxie","pal_lixiaoyao","pal_longkui","ns_nanhua","swd_qi","swd_septem","gw_shasixiwusi", "ow_tianshi","swd_weida","gjqt_xiayize","swd_xiyan","hs_xsylvanas","hs_yelinlonghou","ow_yuanshi","zuoci"]; var vintage=['tianjian','shuiyun','zhuyue','zhimeng','poyun','qianfang','xfenxin','danqing','ywuhun','tianwu','xuelu', 'shahun','yuling','duhun','liaoyuan','touxi','wangchen','poyue','kunlunjing','huanhun','yunchou','tuzhen','cyqiaoxie', 'mufeng','duanyi','guozao','yaotong','pozhen','tanlin','susheng','jikong','shouyin','jilve','hxunzhi','huodan','shanxian', 'ziyu','kuoyin','feiren','zihui','jidong','baoxue','aqianghua','maoding','bfengshi','zhongdun','pingzhang','maichong', 'guozai','jingxiang','yuelu','liechao','fengnu','hanshuang','enze','malymowang','xshixin','qingzun']; var favmodes=["versus|three", "versus|four", "versus|two", "chess|combat"]; for(var i=0;i<mode.length;i++){ game.saveConfig(mode[i]+'_banned',banned); game.saveConfig(mode[i]+'_bannedcards',bannedcards); } var characters=lib.config.all.characters.slice(0); characters.remove('standard'); characters.remove('old'); game.saveConfig('vintageSkills', vintage); game.saveConfig('favouriteCharacter',favs); game.saveConfig('favouriteMode',favmodes); game.saveConfig('theme','simple'); game.saveConfig('player_border', 'slim'); game.saveConfig('cards',lib.config.all.cards); game.saveConfig('characters',characters); game.saveConfig('change_skin',false); game.saveConfig('show_splash','off'); game.saveConfig('show_favourite',false); game.saveConfig('animation', false); game.saveConfig('hover_all', false); game.saveConfig('asset_version', 'v1.9'); // game.saveConfig('characters',lib.config.all.characters); // game.saveConfig('cards',lib.config.all.cards); game.saveConfig('plays',['cardpile']); game.saveConfig('skip_shan',false); game.saveConfig('tao_enemy',true); game.saveConfig('layout','long2'); game.saveConfig('hp_style','ol'); game.saveConfig('background_music','music_off'); game.saveConfig('background_audio',false); game.saveConfig('background_speak',false); game.saveConfig('show_volumn',false); game.saveConfig('show_replay',true); game.saveConfig('autostyle',true); game.saveConfig('debug',true); game.saveConfig('dev',true); if(!lib.device){ game.saveConfig('sync_speed',false); } game.reload(); }, o:function(){ ui.arena.classList.remove('observe'); }, pt:function(){ var list=Array.from(arguments); while(list.length){ var card=cheat.gn(list.pop()); if(card) ui.cardPile.insertBefore(card,ui.cardPile.firstChild); } }, q:function(){ // if(lib.config.layout!='mobile') lib.init.layout('mobile'); if(arguments.length==0){ var style=ui.css.card_style; if(lib.config.card_style!='simple'){ lib.config.card_style='simple'; ui.css.card_style=lib.init.css(lib.assetURL+'theme/style/card','simple'); } else{ lib.config.card_style='default'; ui.css.card_style=lib.init.css(lib.assetURL+'theme/style/card','default'); } style.remove(); } else{ for(var i=0;i<arguments.length;i++){ cheat.g(arguments[i]); } } ui.arena.classList.remove('selecting'); ui.arena.classList.remove('tempnoe'); }, p:function(name,i,skin){ var list=['swd','hs','pal','gjqt','ow','gw']; if(!lib.character[name]){ for(var j=0;j<list.length;j++){ if(lib.character[list[j]+'_'+name]){ name=list[j]+'_'+name;break; } } } if(skin){ lib.config.skin[name]=skin } var target; if(typeof i=='number'){ target=game.players[i]; } else{ target=game.me.next; } if(!lib.character[name]){ target.node.avatar.setBackground(name,'character'); target.node.avatar.show(); } else{ target.init(name); } if(i===true){ if(lib.config.layout=='long2'){ lib.init.layout('mobile'); } else{ lib.init.layout('long2'); } } }, e:function(){ var cards=[],target; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ target=arguments[i]; } else{ cards.push(game.createCard(arguments[i])); } } if(!cards.length){ cards.push(game.createCard('qilin')); cards.push(game.createCard('bagua')); cards.push(game.createCard('dilu')); cards.push(game.createCard('chitu')); cards.push(game.createCard('muniu')); } target=target||game.me; for(var i=0;i<cards.length;i++){ var card=target.getEquip(cards[i]); if(card){ card.discard(); target.removeEquipTrigger(card); } target.$equip(cards[i]); } }, c:function(){ (function(){ var a=0,b=0,c=0,d=0,e=0,f=0,g=0; var sa=0,sb=0,sc=0,sd=0,se=0,sf=0,sg=0; for(var i in lib.character){ switch(lib.character[i][1]){ case 'wei':a++;if(lib.config.banned.contains(i)) sa++;break; case 'shu':b++;if(lib.config.banned.contains(i)) sb++;break; case 'wu':c++;if(lib.config.banned.contains(i)) sc++;break; case 'qun':d++;if(lib.config.banned.contains(i)) sd++;break; case 'jin':g++;if(lib.config.banned.contains(i)) sg++;break; case 'western':e++;if(lib.config.banned.contains(i)) se++;break; case 'key':f++;if(lib.config.banned.contains(i)) sf++;break; } } console.log('魏:'+(a-sa)+'/'+a); console.log('蜀:'+(b-sb)+'/'+b); console.log('吴:'+(c-sc)+'/'+c); console.log('群:'+(d-sd)+'/'+d); console.log('晋:'+(g-sg)+'/'+g); console.log('西:'+(e-se)+'/'+e); console.log('键:'+(f-sf)+'/'+f); console.log('已启用:'+((a+b+c+d+e+f)-(sa+sb+sc+sd+se+sf))+'/'+(a+b+c+d+e+f)); }()); (function(){ var a=0,b=0,c=0,d=0; var aa=0,bb=0,cc=0,dd=0; var sa=0,sb=0,sc=0,sd=0; var sha=0,shan=0,tao=0,jiu=0,wuxie=0,heisha=0,hongsha=0; var num={1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0}; for(var i in lib.card){ if(get.objtype(lib.card[i])=='object'&&lib.translate[i+'_info']){ switch(lib.card[i].type){ case 'basic':a++;break; case 'trick':b++;break; case 'equip':c++;break; default:d++;break; } } } for(var i=0;i<lib.card.list.length;i++){ if(typeof lib.card[lib.card.list[i][2]]=='object'){ switch(lib.card[lib.card.list[i][2]].type){ case 'basic':aa++;break; case 'trick':case 'delay':bb++;break; case 'equip':cc++;break; default:dd++;break; } switch(lib.card.list[i][0]){ case 'heart':sa++;break; case 'diamond':sb++;break; case 'club':sc++;break; case 'spade':sd++;break; } if(lib.card.list[i][2]=='sha'){ sha++; if(lib.card.list[i][0]=='club'||lib.card.list[i][0]=='spade'){ heisha++; } else{ hongsha++; } } if(lib.card.list[i][2]=='shan'){ shan++; } if(lib.card.list[i][2]=='tao'){ tao++; } if(lib.card.list[i][2]=='jiu'){ jiu++; } if(lib.card.list[i][2]=='wuxie'){ wuxie++; } num[lib.card.list[i][1]]++; } } var str='基本牌'+aa+'; '+'锦囊牌'+bb+'; '+'装备牌'+cc+'; '+'其它牌'+dd console.log(str); str='红桃牌'+sa+'; '+'方片牌'+sb+'; '+'梅花牌'+sc+'; '+'黑桃牌'+sd console.log(str); str='杀'+sha+'; '+'黑杀'+heisha+'; '+'红杀'+hongsha+'; '+'闪'+shan+'; '+'桃'+tao+'; '+'酒'+jiu+'; '+'无懈'+wuxie console.log(str); if(arguments[1]){ for(var i=1;i<=13;i++){ if(i<10){ console.log(i+' ',num[i]); } else{ console.log(i,num[i]); } } } var arr=[]; for(var i=1;i<=13;i++){ arr.push(num[i]); } console.log((a+b+c+d)+'/'+(aa+bb+cc+dd),...arr) }()); }, id:function(){ game.showIdentity(); }, b:function(){ if(!ui.dialog||!ui.dialog.buttons) return; for(var i=0;i<Math.min(arguments.length,ui.dialog.buttons.length);i++){ ui.dialog.buttons[i].link=arguments[i]; } }, uy:function(me){ if(me){ game.me.useCard({name:'spell_yexinglanghun'},game.me); } else{ var enemy=game.me.getEnemy(); enemy.useCard({name:'spell_yexinglanghun'},enemy); } }, gs:function(name,act){ var card=game.createCard('spell_'+(name||'yexinglanghun')); game.me.node.handcards1.appendChild(card); if(!act){ game.me.actused=-99; } ui.updatehl(); delete _status.event._cardChoice; delete _status.event._targetChoice; delete _status.event._skillChoice; setTimeout(game.check,300); }, gc:function(name,act){ var card=game.createCard('stone_'+(name||'falifulong')+'_stonecharacter'); game.me.node.handcards1.appendChild(card); if(!act){ game.me.actused=-99; } ui.updatehl(); delete _status.event._cardChoice; delete _status.event._targetChoice; delete _status.event._skillChoice; setTimeout(game.check,300); }, a:function(bool){ if(lib.config.test_game){ game.saveConfig('test_game'); } else{ if(bool){ if(typeof bool==='string'){ game.saveConfig('test_game',bool); } else{ game.saveConfig('test_game','_'); } } else{ game.saveConfig('test_game',true); } } game.reload(); }, as:function(){ ui.window.classList.remove('testing'); var bg=ui.window.querySelector('.pausedbg'); if(bg){ bg.remove(); } }, uj:function(){ cheat.e('qilin'); game.me.next.useCard({name:'jiedao'},[game.me,game.me.previous]); }, u:function(){ var card={name:'sha'},source=game.me.next,targets=[]; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ source=arguments[i]; } else if(Array.isArray(arguments[i])){ targets=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]){ card=arguments[i]; } else if(typeof arguments[i]=='string'){ card={name:arguments[i]} } } if(!targets.length) targets.push(game.me); source.useCard(game.createCard(card.name,card.suit,card.number,card.nature),targets); }, r:function(bool){ var list=['s','ap','a','am','bp','b','bm','c','d']; var str=''; for(var i=0;i<list.length;i++){ if(str) str+=' 、 '; str+=list[i]+'-'+lib.rank[list[i]].length; } console.log(str); for(var i in lib.characterPack){ if(!bool&&lib.config.all.sgscharacters.contains(i)) continue; var map={}; var str=''; for(var j in lib.characterPack[i]){ var rank=get.rank(j); if(!map[rank]){ map[rank]=1; } else{ map[rank]++; } } for(var j=0;j<list.length;j++){ if(map[list[j]]){ if(str) str+=' 、 '; str+=list[j]+'-'+map[list[j]]; } } if(str){ console.log(lib.translate[i+'_character_config']+':'+str); } } var list=lib.rank.s.concat(lib.rank.ap).concat(lib.rank.a).concat(lib.rank.am). concat(lib.rank.bp).concat(lib.rank.b).concat(lib.rank.bm).concat(lib.rank.c).concat(lib.rank.d); Object.keys(lib.character).forEach(key=>{ if(!lib.config.forbidai.includes(key)&&!key.startsWith('boss_')&&!key.startsWith('tafang_')&&!list.includes(key)) console.log(get.translation(key),key); }); }, h:function(player){ console.log(get.translation(player.getCards('h'))); }, g:function(){ for(var i=0;i<arguments.length;i++){ if(i>0&&typeof arguments[i]=='number'){ for(var j=0;j<arguments[i]-1;j++){ cheat.gx(arguments[i-1]); } } else{ cheat.gx(arguments[i]); } } }, ga:function(type){ for(var i in lib.card){ if(lib.card[i].type==type||lib.card[i].subtype==type){ cheat.g(i); } } }, gg:function(){ for(var i=0;i<game.players.length;i++){ for(var j=0;j<arguments.length;j++){ cheat.gx(arguments[j],game.players[i]); } } }, gx:function(name,target){ target=target||game.me; var card=cheat.gn(name); if(!card) return; target.node.handcards1.appendChild(card); delete _status.event._cardChoice; delete _status.event._targetChoice; delete _status.event._skillChoice; game.check(); target.update(); ui.updatehl(); }, gn:function(name){ var nature=null; var suit=null; var suits=['club','spade','diamond','heart']; for(var i=0;i<suits.length;i++){ if(name.startsWith(suits[i])){ suit=suits[i]; name=name.slice(suits[i].length); break; } } if(name.startsWith('red')){ name=name.slice(3); suit=['diamond','heart'].randomGet(); } if(name.startsWith('black')){ name=name.slice(5); suit=['spade','club'].randomGet(); } if(name=='huosha'){ name='sha'; nature='fire'; } else if(name=='leisha'){ name='sha'; nature='thunder'; } if(!lib.card[name]){ return null; } return game.createCard(name,suit,null,nature); }, ge:function(target){ if(target){ cheat.gx('zhuge',target); cheat.gx('qinglong',target); cheat.gx('bagua',target); cheat.gx('dilu',target); cheat.gx('chitu',target); cheat.gx('muniu',target); } else{ cheat.g('zhuge'); cheat.g('qinglong'); cheat.g('bagua'); cheat.g('dilu'); cheat.g('chitu'); cheat.g('muniu'); } }, gj:function(){ cheat.g('shandian'); cheat.g('huoshan'); cheat.g('hongshui'); cheat.g('lebu'); cheat.g('bingliang'); cheat.g('guiyoujie'); }, gf:function(){ for(var i in lib.card){ if(lib.card[i].type=='food'){ cheat.g(i); } } }, d:function(num,target){ if(num==undefined) num=1; var cards=get.cards(num); for(var i=0;i<num;i++){ var card=cards[i]; game.me.node.handcards1.appendChild(card); delete _status.event._cardChoice; delete _status.event._targetChoice; delete _status.event._skillChoice; game.check(); game.me.update(); ui.updatehl(); } }, s:function(){ for(var i=0;i<arguments.length;i++){ game.me.addSkill(arguments[i],true); } delete _status.event._cardChoice; delete _status.event._targetChoice; delete _status.event._skillChoice; game.check(); }, t:function(num){ if(game.players.contains(num)){ num=game.players.indexOf(num); } if(num==undefined){ for(var i=0;i<game.players.length;i++) cheat.t(i); return; } var player=game.players[num]; var cards=player.getCards('hej'); for(var i=0;i<cards.length;i++){ cards[i].discard(); } player.removeEquipTrigger(); player.update(); }, to:function(){ for(var i=0;i<game.players.length;i++){ if(game.players[i]!=game.me){ cheat.t(i); } } }, tm:function(){ for(var i=0;i<game.players.length;i++){ if(game.players[i]==game.me){ cheat.t(i); } } }, k:function(i){ if(i==undefined) i=1; game.players[i].hp=1; cheat.t(i); cheat.g('juedou'); }, z:function(name){ switch(name){ case 'cc':name='re_caocao';break; case 'lb':name='re_liubei';break; case 'sq':name='sunquan';break; case 'dz':name='dongzhuo';break; case 'ys':name='re_yuanshao';break; case 'zj':name='sp_zhangjiao';break; case 'ls':name='liushan';break; case 'sc':name='sunce';break; case 'cp':name='caopi';break; case 'cr':name='caorui';break; case 'sx':name='sunxiu';break; case 'lc':name='liuchen';break; case 'sh':name='sunhao';break; } game.zhu.init(name); game.zhu.maxHp++; game.zhu.hp++; game.zhu.update(); }, }, translate:{ flower:'鲜花', egg:'鸡蛋', wine:'酒杯', shoe:'拖鞋', yuxisx:'玉玺', jiasuo:'枷锁', junk:'平凡', common:'普通', rare:'精品', epic:'史诗', legend:'传说', default:"默认", special:'特殊', zhenfa:'阵法', aozhan:"鏖战", mode_derivation_card_config:'衍生', mode_banned_card_config:'禁卡', mode_favourite_character_config:'收藏', mode_banned_character_config:'禁将', heart:"♥︎", diamond:"♦︎", spade:"♠︎", club:"♣︎", none:'◈', ghujia:'护甲', ghujia_bg:'甲', heart2:"红桃", diamond2:"方片", spade2:"黑桃", club2:"梅花", none2:'无色', red:'红色', black:'黑色', ok:"确定", ok2:"确定", cancel:"取消", cancel2:"取消", restart:"重新开始", setting:"设置", start:"开始", random:"随机", _out:'无效', agree:'同意', refuse:'拒绝', fire:"火", thunder:"雷", poison:"毒", kami:'神', ice:'冰', stab:'刺', wei:'魏', shu:'蜀', wu:'吴', qun:'群', shen:'神', western:'西', key:'键', jin:'晋', double:'双', wei2:'魏国', shu2:'蜀国', wu2:'吴国', qun2:'群雄', shen2:'神明', western2:'西方', key2:'KEY', jin2:'晋朝', double2:'双势力', male:'男', female:'女', mad:'混乱', mad_bg:'疯', draw_card:'摸牌', discard_card:'弃牌', take_damage:'受伤害', reset_character:'复原武将牌', recover_hp:'回复体力', lose_hp:'流失体力', get_damage:'受伤害', weiColor:"#b0d0e2", shuColor:"#ffddb9", wuColor:"#b2d9a9", qunColor:"#f6f6f6", shenColor:"#ffe14c", westernColor:"#ffe14c", jinColor:"#ffe14c", keyColor:"#c9b1fd", basic:'基本', equip:'装备', trick:'锦囊', delay:'延时锦囊', character:'角色', revive:'复活', equip1:'武器', equip2:'防具', equip3:'防御马', 'equip3_4':'坐骑', equip4:'攻击马', equip5:'宝物', equip6:'特殊装备', zero:'零', one:'一', two:'二', three:'三', four:'四', five:'五', six:'六', seven:'七', eight:'八', nine:'九', ten:'十', _recasting:'重铸', _lianhuan:'连环', _lianhuan2:'连环', _kamisha:'神杀', _icesha:'冰杀', qianxing:'潜行', mianyi:'免疫', fengyin:'封印', baiban:'白板', _disableJudge:"判定区", xiaowu_emotion:'小无表情', guojia_emotion:'郭嘉表情', zhenji_emotion:'甄姬表情', shibing_emotion:'士兵表情', xiaosha_emotion:'小杀表情', xiaotao_emotion:'小桃表情', xiaojiu_emotion:'小酒表情', xiaokuo_emotion:'小扩表情', pause:'暂停', config:'选项', auto:'托管', unknown:'未知', unknown0:'一号位', unknown1:'二号位', unknown2:'三号位', unknown3:'四号位', unknown4:'五号位', unknown5:'六号位', unknown6:'七号位', unknown7:'八号位', feichu_equip1:"已废除", feichu_equip1_info:"武器栏已废除", feichu_equip2:"已废除", feichu_equip2_info:"防具栏已废除", feichu_equip3:"已废除", feichu_equip3_info:"防御坐骑栏已废除", feichu_equip4:"已废除", feichu_equip4_info:"攻击坐骑栏已废除", feichu_equip5:"已废除", feichu_equip5_info:"宝物栏已废除", feichu_equip1_bg:"废", feichu_equip2_bg:"废", feichu_equip3_bg:"废", feichu_equip4_bg:"废", feichu_equip5_bg:"废", disable_judge:'已废除', disable_judge_info:'判定区已废除', disable_judge_bg:'废', pss:'手势', pss_paper:'布', pss_scissor:'剪刀', pss_stone:'石头', pss_paper_info:'石头剪刀布时的一种手势。克制石头,但被剪刀克制。', pss_scissor_info:'石头剪刀布时的一种手势。克制布,但被石头克制。', pss_stone_info:'石头剪刀布时的一种手势。克制剪刀,但被布克制。', renku:'仁库', group_wei:"魏势力", group_shu:"蜀势力", group_wu:"吴势力", group_qun:"群势力", group_key:"键势力", group_jin:"晋势力", group_wei_bg:"魏", group_shu_bg:"蜀", group_wu_bg:"吴", group_qun_bg:"群", group_key_bg:"键", group_jin_bg:"晋", zhengsu:'整肃', zhengsu_leijin:'擂进', zhengsu_bianzhen:'变阵', zhengsu_mingzhi:'鸣止', zhengsu_leijin_info:'回合内所有于出牌阶段使用的牌点数递增且不少于三张。', zhengsu_bianzhen_info:'回合内所有于出牌阶段使用的牌花色相同且不少于两张。', zhengsu_mingzhi_info:'回合内所有于弃牌阶段弃置的牌花色均不相同且不少于两张。', db_atk:'策略', db_atk1:'全军出击', db_atk2:'分兵围城', db_def:'策略', db_def1:'奇袭粮道', db_def2:'开城诱敌', cooperation_damage:'同仇', cooperation_damage_info:'双方累计造成至少4点伤害', cooperation_draw:'并进', cooperation_draw_info:'双方累计摸至少8张牌', cooperation_discard:'疏财', cooperation_discard_info:'双方累计弃置至少4种花色的牌', cooperation_use:'戮力', cooperation_use_info:'双方累计使用至少4种花色的牌', charge:'蓄力值', expandedSlots:'扩展装备栏', }, element:{ content:{ emptyEvent:function(){ event.trigger(event.name); }, //增加明置手牌 addShownCards:()=>{ var 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=[...new Set(event.slots)].sort(); if(!event.slots.length) event.finish(); 'step 1' var slot=event.slotsx[event.num]; var left=player.countEnabledSlot(slot),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]) player.disabledSlots[slot]=0; player.disabledSlots[slot]+=lose; var cards=player.getEquips(slot).filter(card=>!event.cards.contains(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){ 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=[...new Set(event.slots)].sort(); for(var slot of slotsx){ var expand=get.numOf(event.slots,slot); game.log(player,'获得了'+get.cnNumber(expand)+'个额外的','#g'+get.translation(slot)+'栏'); if(!player.expandedSlots) player.expandedSlots={}; if(!player.expandedSlots[slot]) player.expandedSlots[slot]=0; player.expandedSlots[slot]+=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=[...new Set(event.slots)].sort(); } } else event.goto(4); 'step 1' var slot=event.slotsx[event.num]; var left=player.countEquipableSlot(slot),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.contains(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){ 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.destroyed){ if(player.hasSkill(card.destroyed)){ delete card.destroyed; } else{ event.finish(); return; } } else if(event.owner){ if(event.owner.getCards('hejsx').contains(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,false,'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]; }),'意见为<span class="firetext">红色</span>,展示了',red.map(function(i){ return i[1]; })); } else game.log('#b无人','意见为<span class="firetext">红色</span>'); 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('<div class="text center">'+list[i]+'</div>'); 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'?'<span class="firetext">红色</span>':'#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+='<br>(点击屏幕可以跳过等待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('<div class="text center">'+(beatmap.prompt||'在音符滑条和底部判定区重合时点击屏幕!')+'</div>'); 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='<div class="text center">演奏结束!<br>最大连击数:'+max_combo+' 精准度:'+acc+'%</div>'; game.me.$fullscreenpop('<span style="font-family:xinwei">演奏评级:<span data-nature="'+rank[1]+'">'+rank[0]+'</span></span>',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.contains(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=('<div class="text center">'+i.textPrompt(event.moved[i._link])+'</div>'); } 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('<div class="text center">'+list[i][0]+'</div>'); 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('<div class="text center">点击两张牌以交换位置;点击一张牌并点击其他区域以移动卡牌</div>'); tex.classList.add('choosetomove'); event.dialog.open(); updateButtons(); event.custom.replace.button=function(button){ var node=button.parentNode; if(!buttonss.contains(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.contains(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 next=player.useCard(card,event.targets2||result.targets); 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(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(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(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.contains('equip3')&&list.contains('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.contains(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.contains(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]); } 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.contains(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.contains(lib.config.mode)) continue; if(character[i].mode&&character[i].mode.contains(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].contains('boss')|| character[i][j][k][4].contains('hiddenboss')){ lib.config.forbidai.add(k); } if(lib.config.forbidai_user&&lib.config.forbidai_user.contains(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.contains(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.filter1=function(info){ if(info[1].isDead()&&!lib.skill[info[0]].forceDie) return false; if(info[1].isOut()&&!lib.skill[info[0]].forceOut) return false; return lib.filter.filterTrigger(trigger,info[1],event.triggername,info[0]); } event.filter2=function(info2){ var info=lib.skill[info2[0]]; if(!lib.translate[info2[0]]||info.silent) return false; return true; } event.filter3=function(info,info2){ return event.filter2(info2)&&event.filter1(info2)&&info2[1]==info[1]&&info[2]==info2[2]&&(lib.skill.global.contains(info2[0])||info[1].hasSkill(info2[0],true)); } 'step 1' if(trigger.filterStop&&trigger.filterStop()){ event.finish(); } else if(event.list.length){ var info=event.list.shift(); game.createTrigger(event.triggername,info[0],info[1],trigger); event.redo(); } 'step 2' if(!event.map.length){ if(event.list2.length){ var info=event.list2.shift(); game.createTrigger(event.triggername,info[0],info[1],trigger); event.redo(); } else{ if(trigger._triggering==this){ delete trigger._triggering; } event.finish(); return; } }; event.doing=event.map.shift(); 'step 3' event.num=0; var bool=false; var list=event.doing.list; for(var i=0;i<list.length;i++){ if(event.filter1(list[i])){ event.num=i; bool=true; break; } } if(!bool){event.goto(2);return;} var priority=list[event.num][2]; for(var i=0;i<event.num;i++){ if(event.doing.list[i][2]>priority){ event.doing.list.splice(i--,1); event.num--; } } event.choice=[]; if(event.num<event.doing.list.length-1&&event.filter2(event.doing.list[event.num])){ var current=event.doing.list[event.num]; event.choice.push(current); for(var i=event.num+1;i<event.doing.list.length;i++){ if(event.filter3(current,event.doing.list[i])) event.choice.push(event.doing.list[i]); } } if(event.choice.length<2) event.goto(6); 'step 4' var controls=[]; event.current=event.choice[0][1] for(var i=0;i<event.choice.length;i++){ controls.push(event.choice[i][0]); } event.current.chooseControl(controls) .set('prompt','选择下一个触发的技能').set('forceDie',true).set('arrangeSkill',true).set('includeOut',true) 'step 5' if(result.control){ for(var i=0;i<event.doing.list.length;i++){ if(event.doing.list[i][0]==result.control&&event.doing.list[i][1]==event.current){ event.num=i;break; } } } 'step 6' var info=event.doing.list[event.num]; if(info){ event.doing.list2.push(info); event.doing.list.splice(event.num,1); game.createTrigger(event.triggername,info[0],info[1],trigger); } 'step 7' if(trigger.filterStop&&trigger.filterStop()){ event.finish(); } else event.goto(event.doing.list.length?3:2); }, createTrigger:function(){ "step 0" //console.log('triggering: ' + player.name+ ' \'s skill: ' + event.skill+' in ' + event.triggername) if(lib.filter.filterTrigger(trigger,player,event.triggername,event.skill)){ var fullskills=game.expandSkills(player.getSkills().concat(lib.skill.global)); if(!fullskills.contains(event.skill)){ var info=get.info(event.skill); var hidden=player.hiddenSkills.slice(0); var invisible=player.invisibleSkills.slice(0); game.expandSkills(hidden); game.expandSkills(invisible); if(hidden.contains(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.contains(event.skill)){ event.trigger('triggerInvisible'); } else{ var keep=false; for(var i in player.additionalSkills){ if(i.startsWith('hidden:')&&game.expandSkills(player.additionalSkills[i]).contains(event.skill)){ keep=true;break; } } if(!keep){ event.finish(); } } } } else{ event.finish(); } "step 1" if(event.cancelled){ event.finish(); return; } var info=get.info(event.skill); if(!event.revealed&&!info.forced){ var 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&&player.isUnderControl()){ game.swapPlayerAuto(player); event._result={bool:true}; event._direct=true; } else if(info.direct){ event._result={bool:true}; event._direct=true; } else if(info.direct&&player.isOnline()){ 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'){ var 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=function(){ return !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','<span class="thundertext">'+trigger.skillwarn+'。</span>'+next.prompt2); } else{ next.set('prompt2',trigger.skillwarn); } } } } "step 2" var info=get.info(event.skill); if(result&&result.bool!=false){ 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); event.finish(); return; } 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){ 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); } } else{ player.logSkill(event.skill,false,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; 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){ for(var i=0;i<player._hookTrigger.length;i++){ var info=lib.skill[player._hookTrigger[i]].hookTrigger; if(info){ if(info.after&&info.after(event,player,event.triggername)){ event.trigger('triggerAfter'); break; } } } } }, 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.contains(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(); } }, 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(typeof _status.lastSeatNum!='number'||seatNum<_status.lastSeatNum) isRound=true; _status.lastSeatNum=seatNum; } } 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; 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(player.isIn()&&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').contains(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); }, 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.contains('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); } } _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.contains(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); 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']]; } event.backup(event.buttoned+'_backup'); if(info.prompt){ event.openskilldialog=info.prompt(info.chooseControl?result:result.links,player); } } else{ ui.control.animate('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.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); } } _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.contains(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); } 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']]; } event.backup(event.buttoned+'_backup'); if(info.prompt){ event.openskilldialog=info.prompt(info.chooseControl?result:result.links,player); } } else{ ui.control.animate('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.skill){ if(info.direct&&!info.clearTime){ _status.noclearcountdown=true; } } 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(); } }, 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.contains(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.contains(card)||!player.getCards('hejsx').contains(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.contains(card)||!player.getCards('hejsx').contains(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.contains(card)||!player.getCards('hejsx').contains(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.contains(card)||!player.getCards('hejsx').contains(card); }) } var shown=i[1].slice(0),hidden=[]; if(event.animate=='giveAuto'){ for(var card of i[1]){ if(evt.hs.contains(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.contains(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].contains(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); player.animate('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.animate('target'); event.card2=event.cardlist[event.iwhile]; event.num2=event.getNum(event.card2); game.log(event.target,'的拼点牌为',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.contains(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].contains(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.animate('target'); player.animate('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('<div class="popup pointerdiv" style="width:80%;display:inline-block"><div class="skill">【'+ translation+'】</div><div>'+lib.translate[list[i]+'_info']+'</div></div>'); 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.contains(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.contains(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.contains(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].animate('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.contains(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].animate('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.contains(i)&&hidden.contains(i)){ event.result={ bool:true, control:i, } return; } } } } else if(event.hsskill&&_status.prehidden_skills.contains(event.hsskill)&&event.controls.contains('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='<div style="font-family: xinwei;font-size: 25px;height: 75px;line-height: 25px;top: 8px;left: 10px;width: 30px;">第'+get.cnNumber(i+1,true)+'张</div>'; 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('<div class="popup text pointerdiv" style="width:calc(100% - 10px);display:inline-block">'+event.controls[i]+'</div>'); 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('<div class="popup text" style="width:calc(100% - 10px);display:inline-block">'+ (event.displayIndex!==false?('选项'+get.cnNumber(i+1,true)+':'):'')+event.choiceList[i]+'</div>'); } } 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.contains(event.frequentSkill)){ ui.click.ok(); return; } else if(event.hsskill&&_status.prehidden_skills.contains(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; 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('<div class="text center" style="margin: 0px;">手牌区</div>'); 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('<div class="text center" style="margin: 0px;">装备区</div>'); 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('<div class="text center" style="margin: 0px;">判定区</div>'); title.style.margin='0px'; title.style.padding='0px'; event.dialog.add(js); directh=false; } } } if(event.dialog.buttons.length==0){ event.finish(); return; } var cs=target.getCards(event.position); var select=get.select(event.selectButton); if(event.forced&&select[0]>=cs.length){ event.result={ bool:true, buttons:event.dialog.buttons, links:cs } } else if(event.forced&&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.contains(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('<div class="text center" style="margin: 0px;">手牌区</div>'); 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('<div class="text center" style="margin: 0px;">装备区</div>'); 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('<div class="text center" style="margin: 0px;">判定区</div>'); title.style.margin='0px'; title.style.padding='0px'; event.dialog.add(js); directh=false; } } } if(event.dialog.buttons.length==0){ event.finish(); return; } var cs=target.getCards(event.position); var select=get.select(event.selectButton); if(event.forced&&select[0]>=cs.length){ event.result={ bool:true, buttons:event.dialog.buttons, links:cs } } else if(event.forced&&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('<div class="text center" style="margin: 0px;">手牌区</div>'); 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('<div class="text center" style="margin: 0px;">装备区</div>'); 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('<div class="text center" style="margin: 0px;">判定区</div>'); 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); if(event.forced&&select[0]>=cs.length){ event.result={ bool:true, buttons:event.dialog.buttons, links:cs } } else if(event.forced&&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.contains(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.contains(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.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" 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.finish(); return; } var next=player.chooseTarget(2,function(card,player,target){ if(ui.selected.targets.length){ var from=ui.selected.targets[0]; var js=from.getCards('j'); 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'); for(var i=0;i<es.length;i++){ if(target.canEquip(es[i])) return true; } return false; } else{ var range='ej'; if(_status.event.nojudge) range='e'; return target.countCards(range)>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); if(ui.selected.targets.length==0){ if(att>0){ if(!_status.event.nojudge&&target.countCards('j',function(card){ return game.hasPlayer(function(current){ return current!=target&¤t.canAddJudge(card)&&get.attitude(player,current)<0; }) })) return 14; if(target.countCards('e',function(card){ return get.value(card,target)<0&&game.hasPlayer(function(current){ return current!=target&&get.attitude(player,current)<0&¤t.canEquip(card)&&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'); for(var i=0;i<es.length;i++){ if(get.value(es[i],target)>0&¤t.canEquip(es[i])&&get.effect(current,es[i],player,player)>0) return true; } } })){ return -att; } } return 0; } var es=ui.selected.targets[0].getCards('e'); 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])){ return Math.abs(att); } } if(i==es.length&&(_status.event.nojudge||!ui.selected.targets[0].countCards('j',function(card){ 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||'移动场上的一张牌'); if(event.prompt2) next.set('prompt2',event.prompt2); if(event.forced) next.set('forced',true); 'step 1' event.result=result; if(result.bool){ 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.position(button.link)=='j'){ if(_status.event.nojudge) return false; return targets1.canAddJudge(button.link); } else{ return targets1.canEquip(button.link); } }); } 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.contains(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)=>{ 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].animate('target'); } } else if(animate){ for(var i=0;i<targets.length;i++){ targets[i].animate('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.contains(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.contains(next.target)) next.directHit=true; if(next.target&&!info.multitarget){ if(num==0&&targets.length>1){ // var ttt=next.target; // setTimeout(function(){ttt.animate('target');},0.5*lib.config.duration); } else{ next.target.animate('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+='对<span class="bluetext">'+(targets[0]==player?'自己':get.translation(targets[0])); for(var i=1;i<targets.length;i++){ str+='、'+(targets[i]==player?'自己':get.translation(targets[i])); } str+='</span>' } 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.contains(info.sourceSkill)){ logInfo.type='global'; } else if(players.contains(info.sourceSkill)){ logInfo.type='player'; } else if(equips.contains(info.sourceSkill)){ logInfo.type='equip'; } } else{ if(global.contains(name)){ logInfo.sourceSkill=name; logInfo.type='global'; } else if(players.contains(name)){ logInfo.sourceSkill=name; logInfo.type='player'; } else if(equips.contains(name)){ logInfo.sourceSkill=name; logInfo.type='equip'; } else{ var bool=false; for(var i of players){ var expand=[i]; game.expandSkills(expand); if(expand.contains(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.contains(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].animate('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.animate('target');},0.5*lib.config.duration); } else{ next.target.animate('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)+'张牌'); } } var 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)); } if(event.animate!=false){ if(event.visible){ var next=player.gain(cards,'gain2'); if(event.bottom) game.log(player,'从牌堆底摸了'+get.cnNumber(num)+'张牌(',cards,')'); else game.log(player,'摸了'+get.cnNumber(num)+'张牌(',cards,')'); } else{ var next=player.gain(cards,'draw'); } } else{ var 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)=>{ 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.contains(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].destroyed){ if(player.hasSkill(cards[i].destroyed)){ delete cards[i].destroyed; } else{ cards.splice(i--,1); } } else if(event.losing_map){ for(var id in event.losing_map){ if(event.losing_map[id][0].contains(cards[i])){ var source=(_status.connectMode?lib.playerOL:game.playerMap)[id]; var hs=source.getCards('hejsx'); if(hs.contains(cards[i])){ cards.splice(i--,1); } } } } } 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.contains(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; cards[num].fix(); cards[num].style.transform=''; cards[num].addGaintag(event.gaintag); 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].destroyed){ if(player.hasSkill(cards[i].destroyed)){ delete cards[i].destroyed; } else{ cards.splice(i--,1); } } else if(event.losing_map){ for(var id in event.losing_map){ if(event.losing_map[id][0].contains(cards[i])){ var source=(_status.connectMode?lib.playerOL:game.playerMap)[id]; var hs=source.getCards('hejsx'); if(hs.contains(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.contains(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.contains(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(info.destroy||cards[i]._destroy){ cards[i].delete(); cards[i].destroyed=info.destroy||cards[i]._destroy; } else 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.contains(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; "step 2" if(num<cards.length){ if(event.es.contains(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.destroyed; })); 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) 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(['fire','thunder','ice'].contains(event.nature)){ if(player.hujia>0&&!player.hasSkillTag('nohujia')&&event.nature!='ice'){ game.broadcastAll(function(num){ if(lib.config.background_audio) game.playAudio('effect','hujia_damage_'+event.nature+(num>1?'2':'')); },num); } else{ game.broadcastAll(function(num){ if(lib.config.background_audio) game.playAudio('effect','damage_'+event.nature+(num>1?'2':'')); },num); } } else{ if(player.hujia>0&&!player.hasSkillTag('nohujia')){ game.broadcastAll(function(num){ if(lib.config.background_audio) game.playAudio('effect','hujia_damage'+(num>1?'2':'')); },num); } else{ game.broadcastAll(function(num){ if(lib.config.background_audio) game.playAudio('effect','damage'+(num>1?'2':'')); },num); } } var str=event.unreal?'视为受到了':'受到了'; if(source) str+='来自<span class="bluetext">'+(source==player?'自己':get.translation(source))+'</span>的'; 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=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; 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.contains(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(){ player.hujia+=num; if(num>0){ game.log(player,'获得了'+get.cnNumber(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].contains(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].contains('die_audio')){ game.playAudio('die',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].destroyed){ if(player.hasSkill(cards[0].destroyed)){ delete cards[0].destroyed; } else{ event.finish(); return; } } else if(event.relatedLose){ var owner=event.relatedLose.player; if(owner.getCards('hejsx').contains(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,'被贴上了<span class="yellowtext">'+get.translation(cards[0].viewAs)+'</span>(',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).animate('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()); }, 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]); } player.popup(get.cnNumber(top.length)+'上'+get.cnNumber(bottom.length)+'下'); game.log(player,'将'+get.cnNumber(top.length)+'张牌置于牌堆顶'); game.updateRoundNumber(); game.delayx(); }, }, player:{ //新函数 /** * version 1.4 * * 链式创建一次性技能的api。 * * 使用者只需要关注技能的效果,而不是技能的本身。 */ when:function(){ if(!_status.postReconnect.player_when) _status.postReconnect.player_when=[ function(map){ "use strict"; for(let i in map){ lib.skill[i]={ charlotte:true, forced:true, popup:false, } if(typeof map[i]=='string') lib.translate[i]=map[i]; } },{} ]; let triggerNames=Array.from(arguments); let trigger; if(triggerNames.length==0) throw 'player.when的参数数量应大于0'; //add other triggerNames //arguments.length = 1 if(triggerNames.length==1){ //以下两种情况: //triggerNames = [ ['xxAfter', ...args] ] //triggerNames = [ 'xxAfter' ] if(Array.isArray(triggerNames[0])||typeof triggerNames[0]=='string') trigger={player:triggerNames[0]}; //triggerNames = [ {player:'xxx'} ] else if(get.is.object(triggerNames[0])) trigger=triggerNames[0]; } //arguments.length > 1 else{ //triggerNames = [ 'xxAfter', 'yyBegin' ] if(triggerNames.every(t=>typeof t=='string')) trigger={player:triggerNames}; //triggerNames = [ {player: 'xxAfter'}, {global: 'yyBegin'} ] //此处不做特殊的合并处理,由使用者自行把握 else if(triggerNames.every(t=>get.is.object(t))) trigger=triggerNames.reduce((pre,cur)=>Object.assign(pre,cur)); } if(!trigger) throw 'player.when传参数类型错误:'+triggerNames; let skillName; do{ skillName='player_when_'+Math.random().toString(36).slice(-8); }while(lib.skill[skillName]!=null); let after=`${skillName}After`; if(!trigger.player) trigger.player=after; else if(Array.isArray(trigger.player)) trigger.player.add(after); else if(typeof trigger.player=='string') trigger.player=[trigger.player,after]; let skill={ trigger, forced:true, charlotte:true, popup:false, //必要条件 filterFuns:[], //充分条件 filter2Funs:[], contentFuns:[], get filter(){ return (event,player,name)=>{ if(name==`${skillName}After`){ skill.popup=false; return true; } return skill.filterFuns.every(fun=>Boolean(fun(event,player,name)))&& skill.filter2(event,player,name); } }, get filter2(){ return (event,player,name)=>{ return skill.filter2Funs.length==0|| skill.filter2Funs.some(fun=>Boolean(fun(event,player,name))); }; } }; Object.defineProperty(lib.skill,skillName,{ configurable:true, //这类技能不需要被遍历到 enumerable:false, writable:true, value:skill }); game.broadcast(function(skillName){ Object.defineProperty(lib.skill,skillName,{ configurable:true, enumerable:false, writable:true, value:{ forced:true, charlotte:true, popup:false, } }); },skillName); this.addSkill(skillName); _status.postReconnect.player_when[1][skillName]=true; return{ filter(fun){ if(lib.skill[skillName]!=skill) throw `This skill has been destroyed`; skill.filterFuns.push(fun); return this; }, removeFilter(fun){ if(lib.skill[skillName]!=skill) throw `This skill has been destroyed`; skill.filterFuns.remove(fun); return this; }, filter2(fun){ if(lib.skill[skillName]!=skill) throw `This skill has been destroyed`; skill.filter2Funs.push(fun); return this; }, removeFilter2(fun){ if(lib.skill[skillName]!=skill) throw `This skill has been destroyed`; skill.filter2Funs.remove(fun); return this; }, then(fun){ if(lib.skill[skillName]!=skill) throw `This skill has been destroyed`; skill.contentFuns.push(fun); let str=` function content(){ if(event.triggername=='${skillName}After'){ player.removeSkill('${skillName}'); delete lib.skill['${skillName}']; delete lib.translate['${skillName}']; return event.finish(); } `; for(let i=0;i<skill.contentFuns.length;i++){ let fun2=skill.contentFuns[i]; let a=fun2.toString(); let str2=a.slice(a.indexOf("{")+1,a.lastIndexOf("}")!=-1?a.lastIndexOf("}"):undefined).trim(); str+=`'step ${i}'\n\t${str2}\n\t`; } let result=eval(str+`\n};content;`); skill.content=result; return this; }, popup(str){ if(lib.skill[skillName]!=skill) throw `This skill has been destroyed`; if(typeof str=='string') skill.popup=str; return this; }, translation(translation){ if(lib.skill[skillName]!=skill) throw `This skill has been destroyed`; if(typeof translation=='string'){ _status.postReconnect.player_when[1][skillName]=translation; game.broadcastAll((skillName,translation)=>lib.translate[skillName]=translation,skillName,translation) } return this; }, assign(obj) { if(lib.skill[skillName]!=skill) throw `This skill has been destroyed`; if(typeof obj=='object'&&obj!==null) Object.assign(skill,obj); return this; } }; }, //让一名角色明置一些手牌 addShownCards:function(){ const cards=[],tags=[]; for(const argument of arguments){ const type=get.itemtype(argument); if(type=='cards') cards.addArray(argument); else if(type=='card') cards.add(argument); else if(typeof argument=='string'&&argument.startsWith('visible_')) tags.add(argument); } if(!cards.length||!tags.length) return; const next=game.createEvent('addShownCards',false); next.player=this; next._cards=cards; next.gaintag=tags; next.setContent('addShownCards'); return next; }, hideShownCards:function(){ const cards=[],tags=[]; for(const argument of arguments){ const type=get.itemtype(argument); if(type=='cards') cards.addArray(argument); else if(type=='card') cards.add(argument); else if(typeof argument=='string'&&argument.startsWith('visible_')) tags.add(argument); } if(!cards.length) return; const next=game.createEvent('hideShownCards',false); next.player=this; next._cards=cards; next.gaintag=tags; next.setContent('hideShownCards'); return next; }, //获取角色所有的明置手牌 getShownCards:function(){ return this.getCards('h',function(card){ return get.is.shownCard(card); }); }, //Execute the delay card effect //执行延时锦囊牌效果 executeDelayCardEffect:function(card,target,judge,judge2){ const executeDelayCardEffect=game.createEvent('executeDelayCardEffect'); executeDelayCardEffect.player=this; executeDelayCardEffect.target=target||this; if(typeof card=='string'){ const virtualCard=executeDelayCardEffect.card=ui.create.card(); virtualCard._destroy=true; virtualCard.expired=true; const info=lib.card[card]; virtualCard.init(['','',card,info&&info.cardnature]); } else if(get.itemtype(card)=='card') executeDelayCardEffect.card=card; else _status.event.next.remove(executeDelayCardEffect); executeDelayCardEffect.judge=judge; executeDelayCardEffect.judge2=judge2; executeDelayCardEffect.setContent('executeDelayCardEffect'); executeDelayCardEffect._args=Array.from(arguments); return executeDelayCardEffect; }, //Check if the card does not count toward hand limit //检测此牌是否不计入手牌上限 canIgnoreHandcard:function(card){ return lib.filter.ignoredHandcard(card,this); }, //Gift //赠予 gift:function(cards,target){ const gift=game.createEvent('gift'); gift.player=this; gift.target=target; const isArray=Array.isArray(cards); if(cards&&!isArray) gift.cards=[cards]; else if(isArray&&cards.length) gift.cards=cards; else _status.event.next.remove(gift); gift.deniedGifts=[]; gift.setContent('gift'); gift._args=Array.from(arguments); return gift; }, //Check if the player can gift the card //检测角色是否能赠予此牌 canGift:function(card,target,strict){ return lib.filter.cardGiftable(card,this,target,strict); }, //Check if the player refuses gifts //检测角色是否拒绝赠予 refuseGifts:function(card,player){ return this.hasSkillTag('refuseGifts',null,{ player:player, card:card }); }, //Gift AI related //赠予AI相关 getGiftAIResultTarget:function(card,target){ if(!card||target.refuseGifts(card,this)) return 0; if(get.type(card,false)=='equip') return get.effect(target,card,target,target); if(card.name=='du') return this.hp>target.hp?-1:0; if(target.hasSkillTag('nogain')) return 0; return Math.max(1,get.value(card,this)-get.value(card,target)); }, getGiftEffect:function(card,target){ return this.getGiftAIResultTarget(card,target)*get.attitude(this,target); }, //Recast //重铸 recast:function(cards,recastingLose,recastingGain){ const recast=game.createEvent('recast'); recast.player=this; const isArray=Array.isArray(cards); if(cards&&!isArray) recast.cards=[cards]; else if(isArray&&cards.length) recast.cards=cards; else _status.event.next.remove(recast); if(typeof recastingLose!='function') recastingLose=(player,cards)=>player.loseToDiscardpile(cards).log=false; recast.recastingLose=recastingLose; recast.recastingLosingEvents=[]; if(typeof recastingGain!='function') recastingGain=(player,cards)=>player.draw(cards.length).log=false; recast.recastingGain=recastingGain; recast.recastingGainingEvents=[]; recast.setContent('recast'); recast._args=Array.from(arguments); return recast; }, //Check if the player can recast the card //检测角色是否能重铸此牌 canRecast:function(card,source,strict){ return lib.filter.cardRecastable(card,this,source,strict); }, //装备栏相关 //判断一名角色的某个区域是否被废除 //type为要判断的区域 若为空 则判断玩家是否有任意一个被废除的区域 hasDisabledSlot:function(type){ var player=this; if(type=='horse') return player.hasDisabledSlot(3)&&player.hasDisabledSlot(4); return player.countDisabledSlot(type)>0; }, //判断一名角色的某个区域被废除的数量 //用法同上 countDisabledSlot:function(type){ var player=this; var map=(player.disabledSlots||{}); if(type==undefined){ num=0; for(var i=1;i<=5;i++){ num+=player.countDisabledSlot(i); } return num; } else{ if(typeof type=='number') type=('equip'+type); var num=map[type]; if(typeof num=='number'&&num>0) return num; return 0; } }, //判断一名角色是否有某个装备栏空着 hasEmptySlot:function(type){ var player=this; if(type=='horse') return player.hasEmptySlot(3)&&player.hasEmptySlot(4); return player.countEmptySlot(type)>0; }, //判断一名角色的某个装备栏空位的数量 countEmptySlot:function(type){ if(!type) return 0; var player=this; if(typeof type=='number') type=('equip'+type); return Math.max(0,player.countEnabledSlot(type)-player.getEquips(type).reduce(function(num,card){ var types=get.subtypes(card,false); return num+get.numOf(types,type); },0)) }, //判断一名角色是否有可以用于装备新装备牌的区域(排除金箍棒和六龙等“不可被替换装备”) //用法同下 hasEquipableSlot:function(type){ return this.countEquipableSlot(type)>0; }, //统计一名角色有多少个可以用于装备新的装备牌的区域 //用法同下 countEquipableSlot:function(type){ if(!type) return 0; var player=this; if(typeof type=='number') type=('equip'+type); return Math.max(0,player.countEnabledSlot(type)-player.getEquips(type).reduce(function(num,card){ var types=get.subtypes(card,false); if(!lib.filter.canBeReplaced(card,player)) num+=get.numOf(types,type); return num; },0)) }, //判断一名角色是否拥有未被废除的某个区域 //type为要判断的区域 若为空 则判断玩家是否有任意一个未被废除的区域 hasEnabledSlot:function(type){ var player=this; if(type=='horse') return player.hasEnabledSlot(3)&&player.hasEnabledSlot(4); return player.countEnabledSlot(type)>0; }, //判断一名角色的某个区域未被废除的数量 //用法同上 countEnabledSlot:function(type){ var player=this; var map=(player.expandedSlots||{}); if(!type){ num=0; for(var i=1;i<=5;i++){ num+=player.countEnabledSlot(i); } return num; } else{ if(typeof type=='number') type=('equip'+type); var slots=1; var num=map[type]; if(typeof num=='number'&&num>0) slots+=num; slots-=player.countDisabledSlot(type); return slots; } }, //获取一名角色装备区内某种类型的装备牌 //参数可以为数字/区域字符串/实体牌/虚拟牌/牌名 getEquips:function(subtype){ var type=(typeof subtype); switch(type){ case 'string': if(subtype.startsWith('equip')&&parseInt(subtype.slice(5))>0){ break; } else if(lib.card[subtype]){ return this.getCards('e',card=>card.name==subtype); } else return []; case 'number': subtype='equip'+subtype; break; case 'object': subtype=get.subtype(subtype,false); break; default: return []; } if(!subtype) return []; return this.getCards('e',function(card){ return get.subtypes(card,false).contains(subtype); }) }, //新的废除装备区/恢复装备区/扩展装备区 //参数:废除来源角色(不写默认当前事件角色),废除区域(数字/区域字符串/数组,可以写多个,重复废除) disableEquip:function(){ var next=game.createEvent('disableEquip'); next.player=this; next.slots=[]; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(Array.isArray(arguments[i])){ for(var arg of arguments[i]){ if(typeof arg=='string'){ if(arg.startsWith('equip')&&parseInt(arg.slice(5))>0) next.slots.push(arg); } else if(typeof arg=='number'){ next.slots.push('equip'+arg); } } } else if(typeof arguments[i]=='string'){ if(arguments[i].startsWith('equip')&&parseInt(arguments[i].slice(5))>0) next.slots.push(arguments[i]); } else if(typeof arguments[i]=='number'){ next.slots.push('equip'+arguments[i]); } } if(!next.source) next.source=_status.event.player; if(!next.slots.length){ _status.event.next.remove(next); } next.setContent('disableEquip'); return next; }, enableEquip:function(){ var next=game.createEvent('enableEquip'); next.player=this; next.slots=[]; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(Array.isArray(arguments[i])){ for(var arg of arguments[i]){ if(typeof arg=='string'){ if(arg.startsWith('equip')&&parseInt(arg.slice(5))>0) next.slots.push(arg); } else if(typeof arg=='number'){ next.slots.push('equip'+arg); } } } else if(typeof arguments[i]=='string'){ if(arguments[i].startsWith('equip')&&parseInt(arguments[i].slice(5))>0) next.slots.push(arguments[i]); } else if(typeof arguments[i]=='number'){ next.slots.push('equip'+arguments[i]); } } if(!next.source) next.source=_status.event.player; if(!next.slots.length){ _status.event.next.remove(next); } next.setContent('enableEquip'); return next; }, expandEquip:function(){ var next=game.createEvent('expandEquip'); next.player=this; next.slots=[]; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(Array.isArray(arguments[i])){ for(var arg of arguments[i]){ if(typeof arg=='string'){ if(arg.startsWith('equip')&&parseInt(arg.slice(5))>0) next.slots.push(arg); } else if(typeof arg=='number'){ next.slots.push('equip'+arg); } } } else if(typeof arguments[i]=='string'){ if(arguments[i].startsWith('equip')&&parseInt(arguments[i].slice(5))>0) next.slots.push(arguments[i]); } else if(typeof arguments[i]=='number'){ next.slots.push('equip'+arguments[i]); } } if(!next.source) next.source=_status.event.player; if(!next.slots.length){ _status.event.next.remove(next); } next.setContent('expandEquip'); return next; }, //判断判定区是否被废除 isDisabledJudge:function(){ return Boolean(this.storage._disableJudge); }, //同步显示扩展装备区状态 $syncExpand:function(map){ var player=this; if(!map){ map=(player.expandedSlots||{}); } game.addVideo('$syncExpand',player,get.copy(map)) game.broadcast(function(player,map){ player.expandedSlots=map; player.$syncExpand(map); },player,map); player.markSkill('expandedSlots'); }, //同步装备区废除牌显示状态 $syncDisable:function(map){ var player=this; var suits={equip3:'+1马栏',equip4:'-1马栏',equip6:'特殊栏'}; if(!map){ map=(player.disabledSlots||{}); } game.addVideo('$syncDisable',player,get.copy(map)) game.broadcast(function(player,map){ player.disabledSlots=map; player.$syncDisable(map); },player,map) var map2=get.copy(map); var cards=Array.from(player.node.equips.childNodes); for(var card of cards){ if(card.name.startsWith('feichu_')){ var index=card.name.slice(7); if(!map2[index]) map2[index]=0; map2[index]--; } } for(var index in map2){ if(!index.startsWith('equip')||!(parseInt(index.slice(5))>0)) continue; var num=map2[index]; if(num>0){ for(var i=0;i<num;i++){ var card=game.createCard('feichu_'+index,(suits[index]||(get.translation(index)+'栏')),''); card.fix(); card.style.transform=''; card.classList.remove('drawinghidden'); card.classList.add('feichu'); delete card._transform; var equipNum=get.equipNum(card); var equipped=false; for(var j=0;j<player.node.equips.childNodes.length;j++){ if(get.equipNum(player.node.equips.childNodes[j])>=equipNum){ player.node.equips.insertBefore(card,player.node.equips.childNodes[j]); equipped=true; break; } } if(!equipped){ player.node.equips.appendChild(card); if(_status.discarded){ _status.discarded.remove(card); } } } } else if(num<0){ for(var i=0;i>num;i--){ var card=cards.find(card=>card.name=='feichu_'+index); if(card){ player.node.equips.removeChild(card); cards.remove(card); } } } } }, //以下函数涉及到本次更新内容而进行修改 canEquip:function(name,replace){ var ranges=get.subtypes(name),rangex=[...new Set(ranges)],player=this; for(var range of rangex){ var num=this.countEquipableSlot(range); var num2=get.numOf(rangex,range); if(!replace) num-=this.getEquips(range).filter(card=>lib.filter.canBeReplaced(card,player)).length; if(num<num2) return false; } return true; }, //以下函数将不再进行后续维护 countDisabled:function(){ return this.countDisabledSlot.apply(this,arguments) }, isDisabled:function(arg){ return this.hasDisabledSlot(arg)&&!this.hasEnabledSlot(arg); }, isEmpty:function(num){ return this.countEnabledSlot(num)>this.getEquips(num).length; }, //以下函数将被废弃 $disableEquip:function(){}, $enableEquip:function(){}, //装备区End chooseToDebate:function(){ var next=game.createEvent('chooseToDebate'); next.player=this; next._args=[]; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='players'){ next.list=arguments[i].slice(0); } else{ next._args.push(arguments[i]); } } next.setContent('chooseToDebate'); return next; }, cooperationWith:function(target,type,reason){ var player=this; if(!player.storage.cooperation) player.storage.cooperation=[]; var info={ target:target, type:type, reason:reason, }; player.storage.cooperation.add(info); player.addTempSkill('cooperation',{player:'dieAfter'}); player.addSkill('cooperation_'+type,{player:'dieAfter'}); game.log(player,'向',target,'发起了“协力”,合作类型是','#g'+get.translation('cooperation_'+type)); }, chooseCooperationFor:function(){ var next=game.createEvent('chooseCooperationFor'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.target=arguments[i]; } else if(Array.isArray(arguments[i])){ next.cardlist=arguments[i]; } else if(typeof arguments[i]=='string'){ next.reason=arguments[i]; } } if(!next.cardlist) next.cardlist=['cooperation_damage','cooperation_draw','cooperation_discard','cooperation_use']; next.setContent('chooseCooperationFor'); return next; }, checkCooperationStatus:function(target,reason){ var storage=this.getStorage('cooperation'); for(var info of storage){ if(info.target==target&&info.reason==reason){ var skill=lib.skill['cooperation_'+info.type]; if(skill&&skill.checkx&&skill.checkx(info)) return true; } } return false; }, removeCooperation:function(info){ var player=this; var storage=player.getStorage('cooperation'); if(!storage.contains(info)) return; storage.remove(info); var unmark=true,reason=info.type; if(!storage.length){ player.removeSkill('cooperation'); } else{ for(var i of storage){ if(i.type==reason){ unmark=false; break; } } } if(unmark) player.removeSkill('cooperation_'+reason); else player.markSkill('cooperation_'+reason); }, hasClan:function(clan,unseen){ if(unseen||!this.isUnseen(0)){ var info=lib.character[this.name1]; if(info&&info[4]){ for(var i of info[4]){ if(typeof i=='string'&&i.startsWith('clan:')&&i.slice(5)==clan) return true; } } } if(this.name2&&(unseen||!this.isUnseen(1))){ var info=lib.character[this.name2]; if(info&&info[4]){ for(var i of info[4]){ if(typeof i=='string'&&i.startsWith('clan:')&&i.slice(5)==clan) return true; } } } return false; }, changeZhuanhuanji:function(skill){ var player=this,info=get.info(skill),zhuanhuan=info.zhuanhuanji; if(typeof zhuanhuan=='function') zhuanhuan(player,skill); else if(zhuanhuan=='number') player.addMark(skill,1,false); else player.storage[skill]=!player.storage[skill]; game.broadcastAll(function(player,skill){ player.$changeZhuanhuanji(skill); },player,skill); }, $changeZhuanhuanji:function(skill){ var mark=this.marks[skill]; if(mark){ if(mark.firstChild.reversed){ mark.firstChild.reversed=false; mark.firstChild.style.transform='none'; } else{ mark.firstChild.reversed=true; mark.firstChild.style.transform='rotate(180deg)'; } } }, setSeatNum:function(num){ _status.seatNumSettled=true; game.broadcastAll(function(player,num){ player.seatNum=num; },this,num); }, getSeatNum:function(){ if(typeof this.seatNum=='number') return this.seatNum; return 0; }, hasSex:function(sex){ if(this.sex=='unknown') return false; if(this.sex=='double') return true; return this.sex==sex; }, sameSexAs:function(target){ var sex1=this.sex,sex2=target.sex; if(sex1=='unknown'||sex2=='unknown') return false; if(sex1=='double'||sex2=='double') return true; return sex1==sex2; }, differentSexFrom:function(target){ var sex1=this.sex,sex2=target.sex; if(sex1=='unknown'||sex2=='unknown') return false; if(sex1=='double'||sex2=='double') return true; return sex1!=sex2; }, addSkillBlocker:function(skill){ if(!this.storage.skill_blocker) this.storage.skill_blocker=[]; this.storage.skill_blocker.push(skill); }, removeSkillBlocker:function(skill){ if(this.storage.skill_blocker){ this.storage.skill_blocker.remove(skill); if(!this.storage.skill_blocker.length) delete this.storage.skill_blocker; } }, loseToSpecial:function(cards,tag,target){ var next=game.loseAsync({ player:this, cards:cards, tag:tag, toStorage:true, target:target||this, }); next.setContent(function(){ "step 0" player.lose(cards,ui.special).set('getlx',false); "step 1" var cards=event.cards.slice(0); cards.removeArray(player.getCards('hejsx')); if(cards.length) target.directgains(cards,null,event.tag) }); return next; }, addGaintag:function(cards,tag){ if(get.itemtype(cards)=='card') cards=[cards]; game.addVideo('addGaintag',this,[get.cardsInfo(cards),tag]); game.broadcastAll(function(player,cards,tag){ var hs=player.getCards('hejsx'); for(var i of cards){ if(hs.contains(i)) i.addGaintag(tag); } },this,cards,tag); }, removeGaintag:function(tag,cards){ cards=cards||this.getCards('h'); game.addVideo('removeGaintag',this,[tag,get.cardsInfo(cards)]); game.broadcastAll(function(player,tag,cards){ for(var i of cards) i.removeGaintag(tag); },this,tag,cards); }, canSave:function(target){ var player=this; if(player.hasSkillTag('save',true,target,true)) return true; var name={},hs=player.getCards('hs'); for(var i of hs) name[get.name(i)]=true; for(var i in lib.card){ if(lib.card[i].savable&&(lib.inpile.contains(i)||name[i])){ if(lib.filter.cardSavable({name:i},player,target)&&(_status.connectMode||player.hasUsableCard(i))) return true; } } return false; }, canSaveCard:function(card,target){ var player=this; var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); if(mod2!='unchanged') return mod2; var mod=game.checkMod(card,player,target,'unchanged','cardSavable',player); if(mod!='unchanged') return mod; var savable=get.info(card).savable; if(typeof savable=='function') savable=savable(card,player,target); return savable; }, showCharacter:function(num,log){ var toShow=[]; if((num==0||num==2)&&this.isUnseen(0)) toShow.add(this.name1); if((num==1||num==2)&&this.isUnseen(1)) toShow.add(this.name2); if(!toShow.length) return; lib.element.player.$showCharacter.apply(this,arguments); var next=game.createEvent('showCharacter',false); next.player=this; next.num=num; next.toShow=toShow; next._args=Array.from(arguments); next.setContent('showCharacter'); var evt=_status.event; evt.next.remove(next); if(evt.logSkill) evt=evt.getParent(); evt.after.push(next); return next; }, $showCharacter:function(num,log){ if(num==0&&!this.isUnseen(0)){ return; } if(num==1&&(!this.name2||!this.isUnseen(1))){ return; } if(!this.isUnseen(2)){ return; } game.addVideo('showCharacter',this,num); var skills; switch(num){ case 0: if(log!==false) game.log(this,'展示了主将','#b'+this.name1); this.name=this.name1; skills=lib.character[this.name][3]||[]; this.sex=lib.character[this.name][0]; if(this.group=='unknown') this.group=lib.character[this.name][1]; this.classList.remove('unseen'); break; case 1: if(log!==false) game.log(this,'展示了副将','#b'+this.name2); skills=lib.character[this.name2][3]||[]; if(this.sex=='unknown') this.sex=lib.character[this.name2][0]; if(this.name.startsWith('unknown')) this.name=this.name2; this.classList.remove('unseen2'); break; case 2: if(log!==false){ if(this.name2) game.log(this,'展示了主将','#b'+this.name1,'、副将','#b'+this.name2); else game.log(this,'展示了主将','#b'+this.name1); } this.name=this.name1; var skills=(lib.character[this.name][3]||[]); if(this.name2) skills=skills.concat(lib.character[this.name2][3]||[]); this.sex=lib.character[this.name][0]; if(this.group=='unknown') this.group=lib.character[this.name][1]; this.classList.remove('unseen'); this.classList.remove('unseen2'); break; } if(!this.isUnseen(2)){ delete this.storage.nohp; this.hp=this.storage.rawHp+this.maxHp-1; this.maxHp=this.storage.rawMaxHp+this.maxHp-1; this.node.hp.show(); this.update(); } game.broadcast(function(player,name,sex,num,group){ player.group=group; player.name=name; player.sex=sex; switch(num){ case 0:player.classList.remove('unseen');break; case 1:player.classList.remove('unseen2');break; case 2:player.classList.remove('unseen');player.classList.remove('unseen2');break; } if(!player.isUnseen(2)){ delete player.storage.nohp; player.node.hp.show(); player.update(); } },this,this.name,this.sex,num,this.group); skills=skills.filter(skill=>{ var info=get.info(skill); if(info&&info.zhuSkill&&!this.isZhu2()) return false; return true; }); for(var i=0;i<skills.length;i++){ if(this.hiddenSkills.contains(skills[i])){ this.hiddenSkills.remove(skills[i]); this.addSkill(skills[i]); } } this.checkConflict(); }, chooseToPlayBeatmap:function(beatmap){ var next=game.createEvent('chooseToPlayBeatmap'); next.player=this; next.beatmap=beatmap; next._args=Array.from(arguments); next.setContent('chooseToPlayBeatmap'); return next; }, chooseToMove:function(){ var next=game.createEvent('chooseToMove'); next.player=this; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(typeof arguments[i]=='string'){ next.prompt=arguments[i]; } } next.setContent('chooseToMove'); next.filterOk=function(){return true}; next.filterMove=function(){return true}; return next; }, chooseToGuanxing:function(num){ var next=game.createEvent('chooseToGuanxing'); next.num=num||1; next.player=this; next.setContent('chooseToGuanxing'); return next; }, $throwEmotion:function(target,name){ game.addVideo('throwEmotion',this,[target.dataset.position,name]); var getLeft=function(player){ if(player==game.me&&!ui.fakeme&&!ui.chess) return player.getLeft()+player.node.avatar.offsetWidth/2; return player.getLeft()+player.offsetWidth/2; } var player=this; var emotion=ui.create.div('','<div style="text-align:center"> <img src="'+lib.assetURL+'image/emotion/throw_emotion/'+name+'1.png"> </div>',game.chess?ui.chess:ui.window); emotion.style.width='60px'; emotion.style.height='60px'; var width=emotion.offsetWidth/2; var height=emotion.offsetHeight/2; if(game.chess) width+=60; var left=getLeft(player)-width; var top=player.getTop()+player.offsetHeight/3-height; emotion.style.left=left+'px'; emotion.style.top=top+'px'; var left2=getLeft(target)-width; var top2=target.getTop()+target.offsetHeight/3-height; emotion.style['z-index']=10; emotion.style.transform='translateY('+(top2-top)+'px) translateX('+(left2-left)+'px)'; if(lib.config.background_audio) game.playAudio('effect','throw_'+name+get.rand(1,2)); setTimeout(function(){ emotion.innerHTML=('<div style="text-align:center"> <img src="'+lib.assetURL+'image/emotion/throw_emotion/'+name+'2.png"> </div>'); setTimeout(function(){ emotion.delete(); },1200); },600); }, tryJudgeAnimate:function(bool){ var player=this; game.broadcast(function(player,bool){ player.trySkillAnimate(bool); },player,bool); if(bool) this.popup('判定生效','wood',false); else this.popup('判定失效','fire',false); }, trySkillAnimate:function(name,popname,checkShow){ if(!game.online&&lib.config.skill_animation_type!='off'&&lib.skill[name]&&lib.skill[name].skillAnimation){ if(lib.config.skill_animation_type=='default'){ checkShow=checkShow||'main'; } else{ checkShow=false; } if(lib.skill[name].textAnimation){ checkShow=false; } this.$skill(lib.skill[name].animationStr||lib.translate[name],lib.skill[name].skillAnimation,lib.skill[name].animationColor,checkShow); return; } var player=this; game.broadcast(function(player,name,popname){ player.trySkillAnimate(name,popname); },player,name,popname); if(lib.animate.skill[name]) lib.animate.skill[name].apply(this,arguments); else{ if(popname!=name) this.popup(popname,'water',false); else this.popup(get.skillTranslation(name,this),'water',false); } }, tryCardAnimate:function(card,name,nature,popname){ var player=this; game.broadcast(function(player,card,name,nature,popname){ player.tryCardAnimate(card,name,nature,popname); },player,card,name,nature,popname); if(lib.animate.card[card.name]) lib.animate.card[card.name].apply(this,arguments); else { if(!lib.config.show_card_prompt) return; if(get.type(card)=='equip'&&lib.config.hide_card_prompt_equip) return; if(get.type(card)=='basic'&&lib.config.hide_card_prompt_basic) return; if(popname) player.popup({name:card.name,nature:card.nature},nature,false); else player.popup(name,nature,false); } }, hasUsableCard:function(name){ var player=this; if(player.countCards('hs',name)) return true; var skills=player.getSkills('invisible').concat(lib.skill.global); game.expandSkills(skills); for(var i=0;i<skills.length;i++){ var ifo=get.info(skills[i]); if(ifo.viewAs&&typeof ifo.viewAs!='function'&&ifo.viewAs.name==name){ if(!ifo.viewAsFilter||ifo.viewAsFilter(player)!==false){ return true; } } else{ var hiddenCard=get.info(skills[i]).hiddenCard; if(typeof hiddenCard=='function'&&hiddenCard(player,name)){ return true; } } } }, inRange:function(to){ var from=this; if(from==to||from.hasSkill('undist')||to.hasSkill('undist')) return false; if(!game.players.contains(from)&&!game.dead.contains(from)) return false; if(!game.players.contains(to)&&!game.dead.contains(to)) return false; var mod1=game.checkMod(from,to,'unchanged','inRange',from); if(mod1!='unchanged') return mod1; var mod2=game.checkMod(from,to,'unchanged','inRangeOf',to); if(mod2!='unchanged') return mod2; var range=from.getAttackRange(); if(range<1) return false; var player=from,m,n=1,i; var fxy,txy; if(game.chess){ fxy=from.getXY(); txy=to.getXY(); n=Math.abs(fxy[0]-txy[0])+Math.abs(fxy[1]-txy[1]); } else if(to.isMin(true)||from.isMin(true)){} else{ var length=game.players.length; var totalPopulation=game.players.length+game.dead.length+1; for(var 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(i=0;i<game.players.length;i++){ if(game.players[i].isOut()||game.players[i].hasSkill('undist')||game.players[i].isMin(true)) length--; } if(from.isDead()) length++; if(to.isDead()) length++; var left=from.hasSkillTag('left_hand'); var right=from.hasSkillTag('right_hand'); if(left===right) n=Math.min(n,length-n); else if(left==true) n=length-n; } n=game.checkMod(from,to,n,'globalFrom',from); n=game.checkMod(from,to,n,'globalTo',to); m=n; m=game.checkMod(from,to,m,'attackFrom',from); m=game.checkMod(from,to,m,'attackTo',to); var equips1=from.getCards('e',function(card){ return !ui.selected.cards||!ui.selected.cards.contains(card); }),equips2=to.getCards('e',function(card){ return !ui.selected.cards||!ui.selected.cards.contains(card); }); for(i=0;i<equips1.length;i++){ var info=get.info(equips1[i]).distance; if(!info) continue; if(info.globalFrom){ m+=info.globalFrom; n+=info.globalFrom; } } for(i=0;i<equips2.length;i++){ var info=get.info(equips2[i]).distance; if(!info) continue; if(info.globalTo){ m+=info.globalTo; n+=info.globalTo; } if(info.attaclTo){ m+=info.attaclTo; } } return m<=range; }, inRangeOf:function(source){ return source.inRange(this); }, //Get the player's HP not less than 0. Set “raw” to true to get the player's raw HP instead. //获取角色的体力值。设置“raw”为true以获取角色的体力。 getHp:function(raw){ return raw?this.hp:Math.max(0,this.hp); }, //Set “raw” to true to get the player's raw damaged HP instead. //设置“raw”为true以获取角色已损失的体力。 getDamagedHp:function(raw){ return this.maxHp-this.getHp(raw); }, changeGroup:function(group,log,broadcast){ var next=game.createEvent('changeGroup'); next.player=this; next.log=true; for(var i=0;i<arguments.length;i++){ var arg=arguments[i]; if(lib.group.contains(arg)){ next.group=arg; } else if(typeof arg==='boolean'){ next.log=arg; } else if(arg==='nobroadcast'){ next.broadcast=false; } } next.setContent('changeGroup'); return next; }, chooseToDuiben:function(target){ var next=game.createEvent('chooseToDuiben'); next.player=this; next.target=target; next.setContent('chooseToDuiben'); return next; }, chooseToPSS:function(target){ var next=game.createEvent('chooseToPSS'); next.player=this; next.target=target; next.setContent('chooseToPSS'); return next; }, chooseToEnable:function(){ var next=game.createEvent('chooseToEnable'); next.player=this; next.setContent('chooseToEnable'); return next; }, chooseToDisable:function(horse){ var next=game.createEvent('chooseToDisable'); next.player=this; if(horse) next.horse=true; next.setContent('chooseToDisable'); return next; }, isPhaseUsing:function(notmeisok){ if(!notmeisok&&_status.currentPhase!=this) return false; return _status.event.name=='phaseUse'||_status.event.getParent('phaseUse').name=='phaseUse'; }, swapEquip:function(target){ var next=game.createEvent('swapEquip'); next.player=this; next.target=target; next.setContent('swapEquip'); return next; }, canCompare:function(target){ if(this==target) return false; if(!this.countCards('h')||!target.countCards('h')) return false; if(this.hasSkillTag('noCompareSource')||target.hasSkillTag('noCompareTarget')) return false; return true; }, $disableJudge:function(){ var player=this; game.addVideo('$disableJudge',player); player.storage._disableJudge=true; var card=game.createCard('disable_judge','',''); card.fix(); card.classList.add('feichu'); card.style.transform=''; card.classList.add('drawinghidden'); player.node.judges.insertBefore(card,player.node.judges.firstChild); ui.updatej(player); }, $enableJudge:function(){ var player=this; game.addVideo('$enableJudge',player); player.storage._disableJudge=false; for(var i=0;i<player.node.judges.childNodes.length;i++){ if(player.node.judges.childNodes[i].name=='disable_judge'){ player.node.judges.removeChild(player.node.judges.childNodes[i]); break; } } }, disableJudge:function(){ var next=game.createEvent('disableJudge'); next.player=this; next.source=_status.event.player; next.setContent('disableJudge'); return next; }, enableJudge:function(){ var next=game.createEvent('enableJudge'); next.player=this; next.source=_status.event.player; next.setContent('enableJudge'); return next; }, //原有函数 init:function(character,character2,skill,update){ if(typeof character=='string'&&!lib.character[character]){ lib.character[character]=get.character(character); } if(typeof character2=='string'&&!lib.character[character2]){ lib.character[character2]=get.character(character2); } if(!lib.character[character]) return; if(get.is.jun(character2)){ var tmp=character; character=character2; character2=tmp; } if(character2==false){ skill=false; character2=null; } var info=lib.character[character]; if(!info){ info=['','',1,[],[]]; } if(!info[4]){ info[4]=[]; } var skills=info[3].slice(0); this.clearSkills(true); this.classList.add('fullskin'); if(!game.minskin&&get.is.newLayout()&&!info[4].contains('minskin')){ this.classList.remove('minskin'); this.node.avatar.setBackground(character,'character'); } else{ this.node.avatar.setBackground(character,'character'); if(info[4].contains('minskin')){ this.classList.add('minskin'); } else if(game.minskin){ this.classList.add('minskin'); } else{ this.classList.remove('minskin'); } } var hp1=get.infoHp(info[2]); var maxHp1=get.infoMaxHp(info[2]); var hujia1=get.infoHujia(info[2]); this.node.avatar.show(); this.node.count.show(); this.node.equips.show(); this.name=character; this.name1=character; this.sex=info[0]; this.group=info[1]; this.hp=hp1; this.maxHp=maxHp1; this.hujia=hujia1; this.node.intro.innerHTML=lib.config.intro; this.node.name.dataset.nature=get.groupnature(this.group); lib.setIntro(this); this.node.name.innerHTML=get.slimName(character); if(this.classList.contains('minskin')&&this.node.name.querySelectorAll('br').length>=4){ this.node.name.classList.add('long'); } if(info[4].contains('hiddenSkill')&&!this.noclick){ if(!this.hiddenSkills) this.hiddenSkills=[]; this.hiddenSkills.addArray(skills); skills=[]; this.classList.add(_status.video?'unseen_v':'unseen'); this.name='unknown'; if(!this.node.name_seat&&!_status.video){ this.node.name_seat=ui.create.div('.name.name_seat',get.verticalStr(get.translation(this.name)),this); this.node.name_seat.dataset.nature=get.groupnature(this.group); } this.sex='male'; //this.group='unknown'; this.storage.nohp=true; skills.add('g_hidden_ai'); } if(character2&&lib.character[character2]){ var info2=lib.character[character2]; if(!info2){ info2=['','',1,[],[]]; } if(!info2[4]){ info2[4]=[]; } this.classList.add('fullskin2'); this.node.avatar2.setBackground(character2,'character'); this.node.avatar2.show(); this.name2=character2; var hp2=get.infoHp(info2[2]); var maxHp2=get.infoMaxHp(info2[2]); var hujia2=get.infoHujia(info2[2]); this.hujia+=hujia2; var double_hp; if(_status.connectMode||get.mode()=='single'){ double_hp='pingjun'; } else{ double_hp=get.config('double_hp'); } switch(double_hp){ case 'pingjun':{ this.maxHp=Math.floor((maxHp1+maxHp2)/2); this.hp=Math.floor((hp1+hp2)/2); this.singleHp=((maxHp1+maxHp2)%2===1); break; } case 'zuidazhi':{ this.maxHp=Math.max(maxHp1,maxHp2); this.hp=Math.max(hp1,hp2); break; } case 'zuixiaozhi':{ this.maxHp=Math.min(maxHp1,maxHp2); this.hp=Math.min(hp1,hp2); break; } case 'zonghe':{ this.maxHp=maxHp1+maxHp2; this.hp=hp1+hp2; break; } default:{ this.maxHp=maxHp1+maxHp2-3; this.hp=hp1+hp2-3; }; } this.node.count.classList.add('p2'); if(info2[4].contains('hiddenSkill')&&!this.noclick){ if(!this.hiddenSkills) this.hiddenSkills=[]; this.hiddenSkills.addArray(info2[3]); this.classList.add(_status.video?'unseen2_v':'unseen2'); this.storage.nohp=true; skills.add('g_hidden_ai'); } else skills=skills.concat(info2[3]); this.node.name2.innerHTML=get.slimName(character2); } if(this.storage.nohp){ this.storage.rawHp=this.hp; this.storage.rawMaxHp=this.maxHp; this.hp=1; this.maxHp=1; this.node.hp.hide(); } if(skill!=false){ skills=skills.filter(skill=>{ var info=get.info(skill); if(info&&info.zhuSkill&&!this.isZhu2()) return false; return true; }); for(var i=0;i<skills.length;i++){ this.addSkill(skills[i],null,true); } this.checkConflict(); } lib.group.add(this.group); if(this.inits){ for(var i=0;i<lib.element.player.inits.length;i++){ lib.element.player.inits[i](this); } } if(this._inits){ for(var i=0;i<this._inits.length;i++){ this._inits[i](this); } } if(update!==false) this.$update(); return this; }, initOL:function(name,character){ this.node.avatar.setBackground(character,'character'); this.node.avatar.show(); this.node.name.innerHTML=get.verticalStr(name); this.nickname=name; this.avatar=character; this.node.nameol.innerHTML=''; if(lib.character[character]) this.sex=lib.character[character][0]; }, uninitOL:function(){ this.node.avatar.hide(); this.node.name.innerHTML=''; this.node.identity.firstChild.innerHTML=''; delete this.nickname; delete this.avatar; delete this.sex; }, initRoom:function(info,info2){ var str=''; this.serving=false; if(!info||info=='server'){ this.roomempty=true; str='空房间'; this.roomfull=false; this.roomgaming=false; this.version=null; if(info=='server'){ this.serving=true; } } else{ var config=info[2]; this.key=info[4]; this.roomempty=false; str+=get.modetrans(config); str+=' 模式 '; for(var i=str.length;i<11;i++) str+=' '; this.version=config.version; if(config.gameStarted){ str+='<span class="firetext">游戏中</span> '; if(config.observe&&config.observeReady&&this.version==lib.versionOL){ this.classList.remove('exclude'); } else{ this.classList.add('exclude'); } } else{ str+='<span class="greentext">等待中</span> '; if(this.version!=lib.versionOL){ this.classList.add('exclude'); } else{ this.classList.remove('exclude'); } } this.maxHp=parseInt(config.number); this.hp=Math.min(this.maxHp,info[3]); if(this.hp<this.maxHp||config.gameStarted) str+=('人数:'+this.hp+'/'+this.maxHp); else str+=('人数:<span class="firetext">'+this.hp+'/'+this.maxHp+'</span>'); str+=(' ('+info[0].slice(0,12)+' 的房间)'); if(config.mode!='guozhan'&&(config.mode!='doudizhu'||config.doudizhu_mode!='online')){ str+='【'; for(var i=0;i<config.cardPack.length;i++){ str+=(get.translation(config.cardPack[i]+'_card_config').slice(0,2)); if(i<config.cardPack.length-1) str+='+'; } str+='】'; } this.config=config; if(this.hp==this.maxHp&&!config.gameStarted){ this.roomfull=true; } else{ this.roomfull=false; } if(config.gameStarted&&(!config.observe||!config.observeReady)){ this.roomgaming=true; } else{ this.roomgaming=false; } } this.firstChild.innerHTML=str; return this; }, reinit:function(from,to,maxHp,online){ var info1=lib.character[from]; var info2=lib.character[to]; var smooth=true; if(maxHp=='nosmooth'){ smooth=false; maxHp=null; } if(this.name2==from){ this.name2=to; if(this.isUnseen(0)&&!this.isUnseen(1)){ this.sex=info2[0]; this.name=to; } if(smooth) this.smoothAvatar(true); this.node.avatar2.setBackground(to,'character'); this.node.name2.innerHTML=get.slimName(to); } else if(this.name==from||this.name1==from){ if(this.name1==from){ this.name1=to; } if(!this.classList.contains('unseen2')){ this.name=to; this.sex=info2[0]; } if(smooth) this.smoothAvatar(false); this.node.avatar.setBackground(to,'character'); this.node.name.innerHTML=get.slimName(to); if(this==game.me&&ui.fakeme){ ui.fakeme.style.backgroundImage=this.node.avatar.style.backgroundImage; } } else{ return this; } if(online){ return; } for(var i=0;i<info1[3].length;i++){ this.removeSkill(info1[3][i]); } for(var i=0;i<info2[3].length;i++){ var info=get.info(info2[3][i]); if(info&&info.zhuSkill&&!this.isZhu2()) continue; this.addSkill(info2[3][i]); } if(Array.isArray(maxHp)){ this.maxHp=maxHp[1]; this.hp=maxHp[0]; } else{ var num; if(maxHp===false){ num=0; } else{ if(typeof maxHp!='number'){ maxHp=get.infoMaxHp(info2[2]); } num=maxHp-get.infoMaxHp(info1[2]); } if(typeof this.singleHp=='boolean'){ if(num%2!=0){ if(this.singleHp){ this.maxHp+=(num+1)/2; this.singleHp=false; } else{ this.maxHp+=(num-1)/2; this.singleHp=true; if(!game.online){ this.doubleDraw(); } } } else{ this.maxHp+=num/2; } } else{ this.maxHp+=num; } } game.broadcast(function(player,from,to,skills){ player.reinit(from,to,null,true); player.applySkills(skills); },this,from,to,get.skillState(this)); game.addVideo('reinit3',this,{ from:from, to:to, hp:this.maxHp, avatar2:this.name2==to }); this.update(); }, uninit:function(){ this.expandedSlots={}; this.disabledSlots={}; this.$syncDisable(); if(this.isDisabledJudge()){ game.broadcastAll(function(player){ player.storage._disableJudge=false; for(var i=0;i<player.node.judges.childNodes.length;i++){ if(player.node.judges.childNodes[i].name=='disable_judge'){ player.node.judges.removeChild(player.node.judges.childNodes[i]); break; } } },this); } this.node.avatar.hide(); this.node.count.hide(); if(this.node.wuxing){ this.node.wuxing.hide(); } if(this.node.name_seat){ this.node.name_seat.remove(); delete this.node.name_seat; } if(this.storage.nohp) this.node.hp.show(); this.classList.remove('unseen'); this.classList.remove('unseen2'); delete this.name; delete this.name1; delete this.sex; delete this.group; delete this.hp; delete this.maxHp; delete this.hujia; this.clearSkills(true); this.node.identity.style.backgroundColor=''; this.node.intro.innerHTML=''; this.node.name.innerHTML=''; this.node.hp.innerHTML=''; this.node.count.innerHTML='0'; if(this.name2){ delete this.singleHp; this.node.avatar2.hide(); this.node.name2.innerHTML=''; this.classList.remove('fullskin2') delete this.name2; this.node.count.classList.remove('p2'); } for(var mark in this.marks){ this.marks[mark].remove(); } ui.updatem(this); this.skipList=[]; this.skills=this.skills.contains('cangji_yozuru')?['cangji_yozuru']:[]; this.initedSkills=[]; this.additionalSkills={}; this.disabledSkills={}; this.hiddenSkills=[]; this.awakenedSkills=[]; this.forbiddenSkills={}; this.phaseNumber=0; this.stat=[{card:{},skill:{}}]; this.tempSkills={}; this.storage={}; this.marks={}; this.ai={friend:[],enemy:[],neutral:[]}; return this; }, getLeft:function(){ return this.offsetLeft; }, getTop:function(){ return this.offsetTop; }, smoothAvatar:function(vice,video){ var div=ui.create.div('.fullsize'); if(vice){ div.style.background=getComputedStyle(this.node.avatar2).background; this.node.avatar2.appendChild(div); } else{ div.style.background=getComputedStyle(this.node.avatar).background; this.node.avatar.appendChild(div); } ui.refresh(div); div.style.transition='all 1s'; setTimeout(function(){ div.classList.add('removing'); setTimeout(function(){ div.remove(); },2000); },100); if(video!=false){ game.addVideo('smoothAvatar',this,vice); } }, changeSeat:function(position,video){ var player=this; if(video!==false) game.addVideo('changeSeat',player,position); var rect1=player.getBoundingClientRect(); player.style.transition='all 0s'; ui.refresh(player); player.dataset.position=position; var rect2=player.getBoundingClientRect(); var dx=rect1.left-rect2.left; var dy=rect1.top-rect2.top; if((game.chess||(player.dataset.position!=0&&position!=0))&&player.classList.contains('linked')){ player.style.transform='rotate(-90deg) translate('+(-dy)+'px,'+(dx)+'px)'; } else{ player.style.transform='translate('+(dx)+'px,'+(dy)+'px)'; } setTimeout(function(){ player.style.transition=''; ui.refresh(player); player.style.transform=''; },100); }, send:function(){ if(!this.ws||this.ws.closed) return this; this.ws.send.apply(this.ws,arguments); return this; }, getId:function(){ if(_status.video||_status.connectMode) return this; if(this.playerid){ delete game.playerMap[this.playerid]; } this.playerid=get.id(); game.playerMap[this.playerid]=this; return this; }, throwEmotion:function(target,emotion){ game.broadcastAll(function(player,target,emotion){ player.$throwEmotion(target,emotion); },this,target,emotion); }, emotion:function(pack,id){ var str='<img src="##assetURL##image/emotion/'+pack+'/'+id+'.gif" width="50" height="50">'; lib.element.player.say.call(this,str); game.broadcast(function(id,str){ if(lib.playerOL[id]){ lib.playerOL[id].say(str); } else if(game.connectPlayers){ for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].playerid==id){ lib.element.player.say.call(game.connectPlayers[i],str); return; } } } },this.playerid,str); }, chat:function(str){ if(get.is.banWords(str)) return; lib.element.player.say.call(this,str); game.broadcast(function(id,str){ if(lib.playerOL[id]){ lib.playerOL[id].say(str); } else if(game.connectPlayers){ for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].playerid==id){ lib.element.player.say.call(game.connectPlayers[i],str); return; } } } },this.playerid,str); }, say:function(str){ str=str.replace(/##assetURL##/g,lib.assetURL); var dialog=ui.create.dialog('hidden'); dialog.classList.add('static'); dialog.add('<div class="text" style="word-break:break-all;display:inline">'+str+'</div>'); dialog.classList.add('popped'); ui.window.appendChild(dialog); var width=dialog.content.firstChild.firstChild.offsetWidth; if(width<190){ dialog._mod_height=-16; } else{ dialog.content.firstChild.style.textAlign='left'; } dialog.style.width=(width+16)+'px'; var refnode; if(this.node&&this.node.avatar&&this.parentNode==ui.arena){ refnode=this.node.avatar; } if(refnode){ lib.placePoppedDialog(dialog,{ clientX:(ui.arena.offsetLeft+this.getLeft()+refnode.offsetLeft+refnode.offsetWidth/2)*game.documentZoom, clientY:(ui.arena.offsetTop+this.getTop()+refnode.offsetTop+refnode.offsetHeight/4)*game.documentZoom }); } else{ lib.placePoppedDialog(dialog,{ clientX:(this.getLeft()+this.offsetWidth/2)*game.documentZoom, clientY:(this.getTop()+this.offsetHeight/4)*game.documentZoom }); } if(dialog._mod_height){ dialog.content.firstChild.style.padding=0; } setTimeout(function(){ dialog.delete(); },lib.quickVoice.includes(str)?3800:2000); var name=get.translation(this.name); var info=[name?(name+'['+this.nickname+']'):this.nickname,str]; lib.chatHistory.push(info); if(_status.addChatEntry){ if(_status.addChatEntry._origin.parentNode){ _status.addChatEntry(info,false); } else{ delete _status.addChatEntry; } } if(lib.config.background_speak&&lib.quickVoice.includes(str)){ game.playAudio('voice',(this.sex=='female'?'female':'male'),lib.quickVoice.indexOf(str)); } }, showGiveup:function(){ this._giveUp=true; if(this==game.me){ ui.create.giveup(); } else if(this.isOnline2()){ this.send(ui.create.giveup); } }, applySkills:function(skills){ for(var i in skills){ if(i=='global'){ lib.skill.global=skills[i]; } //else if(i=='skillinfo'){ // for(var j in skills[i]){ // if(!lib.skill[j]){ // lib.skill[j]={}; // } // lib.skill[j].chooseButton=skills[i][j]; // } //} else if(i=='stat'){ this.stat=[skills.stat]; } else if(lib.playerOL[i]){ for(var j in skills[i]){ lib.playerOL[i][j]=skills[i][j]; } } } }, getState:function(){ var state={ hp:this.hp, maxHp:this.maxHp, nickname:this.nickname, sex:this.sex, group:this.group, name:this.name, name1:this.name1, name2:this.name2, handcards:this.getCards('hs'), gaintag:[], equips:this.getCards('e'), judges:this.getCards('j'), specials:this.getCards('s'), expansions:this.getCards('x'), expansion_gaintag:[], disableJudge:this.isDisabledJudge(), disabledSlots:this.disabledSlots, expandedSlots:this.expandedSlots, views:[], position:parseInt(this.dataset.position), hujia:this.hujia, side:this.side, identityShown:this.identityShown, identityNode:[this.node.identity.innerHTML,this.node.identity.dataset.color], identity:this.identity, dead:this.isDead(), linked:this.isLinked(), turnedover:this.isTurnedOver(), out:this.isOut(), phaseNumber:this.phaseNumber, unseen:this.isUnseen(0), unseen2:this.isUnseen(1), seatNum:this.seatNum, } for(var i=0;i<state.judges.length;i++){ state.views[i]=state.judges[i].viewAs; } for(var i=0;i<state.handcards.length;i++){ state.gaintag[i]=state.handcards[i].gaintag; } for(var i=0;i<state.expansions.length;i++){ state.expansion_gaintag[i]=state.expansions[i].gaintag; } if(this.getModeState){ state.mode=this.getModeState(); } return state; }, setNickname:function(str){ this.node.nameol.innerHTML=(str||this.nickname||'').slice(0,12); return this; }, setAvatar:function(name,name2,video,fakeme){ var node; if(this.name2==name){ node=this.node.avatar2; this.smoothAvatar(true,video); } else if(this.name==name){ node=this.node.avatar; this.smoothAvatar(false,video); } if(node){ node.setBackground(name2,'character'); if(this==game.me&&ui.fakeme&&fakeme!==false){ ui.fakeme.style.backgroundImage=node.style.backgroundImage; } if(video!=false){ game.addVideo('setAvatar',this,[name,name2]); } } game.broadcast(function(player,name,name2){ player.setAvatar(name,name2,false); },this,name,name2); }, setAvatarQueue:function(name, list){ var node; var player=this; if(player.name2==name){ node=player.node.avatar2; } else{ node=player.node.avatar; } if(node._avatarqueue){ for(var i=0;i<list.length;i++){ node._avatarqueue.push(list[i]); } } else{ var func=function(){ if(node._avatarqueue.length){ player.setAvatar(name,node._avatarqueue.shift(),false,false); } else{ clearInterval(node._avatarqueueinterval); delete node._avatarqueue; delete node._avatarqueueinterval; player.setAvatar(name,name,false,false); } }; node._avatarqueue=list.slice(0); node._avatarqueueinterval=setInterval(func,1000); func(); } game.addVideo('setAvatarQueue',this,[name,list]); }, flashAvatar:function(skill,name){ if(lib.skill[name]&&!lib.character[name]){ var stop=false; var list=lib.config.all.characters.slice(0); for(var i in lib.characterPack){ list.add(i); } for(var i=0;i<list.length;i++){ for(var j in lib.characterPack[list[i]]){ if(lib.characterPack[list[i]][j][3].contains(name)){ name=j; stop=true; break; } } if(stop){ break; } } } if(lib.character[this.name2]&&lib.character[this.name2][3].contains(skill)){ this.setAvatarQueue(this.name2,[name]); } else{ this.setAvatarQueue(this.name,[name]); } }, update:function(){ if(_status.video&&arguments.length==0) return; if(this.hp>=this.maxHp) this.hp=this.maxHp; game.broadcast(function(player,hp,maxHp,hujia){ player.hp=hp; player.maxHp=maxHp; player.hujia=hujia; player.$update(); },this,this.hp,this.maxHp,this.hujia); this.$update(); }, $update:function(){ if(this.hp>=this.maxHp) this.hp=this.maxHp; var hp=this.node.hp; hp.style.transition='none'; if(!_status.video){ if(this.hujia){ this.markSkill('ghujia'); } else{ this.unmarkSkill('ghujia'); } } if(!this.storage.nohp){ if(this.maxHp==Infinity){ hp.innerHTML='∞'; } else if(game.layout=='default'&&this.maxHp>14){ hp.innerHTML=this.hp+'/'+this.maxHp; hp.classList.add('text'); } else if(get.is.newLayout()&& ( this.maxHp>9|| (this.maxHp>5&&this.classList.contains('minskin'))|| ((game.layout=='mobile'||game.layout=='long')&&this.dataset.position==0&&this.maxHp>7) )){ hp.innerHTML=this.hp+'<br>/<br>'+this.maxHp+'<div></div>'; if(this.hp==0){ hp.lastChild.classList.add('lost'); } hp.classList.add('textstyle'); // hp.classList.remove('long'); } else{ hp.innerHTML=''; hp.classList.remove('text'); hp.classList.remove('textstyle'); while(this.maxHp>hp.childNodes.length){ ui.create.div(hp); } while(Math.max(0,this.maxHp)<hp.childNodes.length){ hp.removeChild(hp.lastChild); } for(var i=0;i<this.maxHp;i++){ var index=i; if(get.is.newLayout()){ index=this.maxHp-i-1; } if(i<this.hp){ hp.childNodes[index].classList.remove('lost'); } else{ hp.childNodes[index].classList.add('lost'); } } // if(this.maxHp==9){ // hp.classList.add('long'); // } // else{ // hp.classList.remove('long'); // } } if(hp.classList.contains('room')){ hp.dataset.condition='high'; } else if(this.hp==0){ hp.dataset.condition=''; } else if(this.hp>Math.round(this.maxHp/2)||this.hp===this.maxHp){ hp.dataset.condition='high'; } else if(this.hp>Math.floor(this.maxHp/3)){ hp.dataset.condition='mid'; } else{ hp.dataset.condition='low'; } setTimeout(function(){ hp.style.transition=''; }); } var numh=this.countCards('h'); if(_status.video){ numh=arguments[0]; } if(numh>=10){ numh=numh.toString(); this.node.count.dataset.condition='low'; this.node.count.innerHTML=numh[0]+'<br>'+numh[1]; } else{ if(numh>5){ this.node.count.dataset.condition='higher'; } else if(numh>2){ this.node.count.dataset.condition='high'; } else if(numh>0){ this.node.count.dataset.condition='mid'; } else{ this.node.count.dataset.condition='none'; } this.node.count.innerHTML=numh; } if(this.updates){ for(var i=0;i<lib.element.player.updates.length;i++){ lib.element.player.updates[i](this); } } if(!_status.video){ game.addVideo('update',this,[this.countCards('h'),this.hp,this.maxHp,this.hujia]); } this.updateMarks(); return this; }, clearMark:function(i,log){ let num=this.countMark(i); if(num>0) this.removeMark(i,num,log) }, removeMark:function(i,num,log){ if(typeof num!='number'||!num) num=1; if(typeof this.storage[i]!='number'||!this.storage[i]) return; if(num>this.storage[i]) num=this.storage[i]; this.storage[i]-=num; if(log!==false){ var str=false; var info=get.info(i); if(info&&info.intro&&(info.intro.name||info.intro.name2)) str=info.intro.name2||info.intro.name; else str=lib.translate[i]; if(str) game.log(this,'移去了',get.cnNumber(num),'个','#g【'+str+'】'); } this.syncStorage(i); this[(this.storage[i]||(lib.skill[i]&&lib.skill[i].mark))?'markSkill':'unmarkSkill'](i); }, addMark:function(i,num,log){ if(typeof num!='number'||!num) num=1; if(typeof this.storage[i]!='number') this.storage[i]=0; this.storage[i]+=num; if(log!==false){ var str=false; var info=get.info(i); if(info&&info.intro&&(info.intro.name||info.intro.name2)) str=info.intro.name2||info.intro.name; else str=lib.translate[i]; if(str) game.log(this,'获得了',get.cnNumber(num),'个','#g【'+str+'】'); } this.syncStorage(i); this.markSkill(i); }, setMark:function(name,num,log){ const count=this.countMark(name); if(count>num)this.removeMark(name,count-num,log); else if(count<num)this.addMark(name,num-count,log); }, countMark:function(i){ if(this.storage[i]==undefined) return 0; if(typeof this.storage[i]=='number') return this.storage[i]; if(Array.isArray(this.storage[i])) return this.storage[i].length; return 0; }, hasMark:function(i){ return this.countMark(i)>0; }, updateMark:function(i,storage){ if(!this.marks[i]){ if(lib.skill[i]&&lib.skill[i].intro&&(this.storage[i]||lib.skill[i].intro.markcount)){ this.markSkill(i); if(!this.marks[i]) return this; } else{ return this; } } if(storage&&this.storage[i]){ this.syncStorage(i); } if(i=='ghujia'||((!this.marks[i].querySelector('.image')||this.storage[i+'_markcount'])&& lib.skill[i]&&lib.skill[i].intro&&!lib.skill[i].intro.nocount&& (this.storage[i]||this.storage[i+'_markcount']||lib.skill[i].intro.markcount))){ this.marks[i].classList.add('overflowmark') var num=0; if(typeof lib.skill[i].intro.markcount=='function'){ num=lib.skill[i].intro.markcount(this.storage[i],this); } else if(lib.skill[i].intro.markcount=='expansion'){ num=this.countCards('x',(card)=>card.hasGaintag(i)); } else if(typeof this.storage[i+'_markcount']=='number'){ num=this.storage[i+'_markcount']; } else if(i=='ghujia'){ num=this.hujia; } else if(typeof this.storage[i]=='number'){ num=this.storage[i]; } else if(Array.isArray(this.storage[i])){ num=this.storage[i].length; } if(num){ if(!this.marks[i].markcount){ this.marks[i].markcount=ui.create.div('.markcount.menubutton',this.marks[i]); } this.marks[i].markcount.innerHTML=num; } else if(this.marks[i].markcount){ this.marks[i].markcount.delete(); delete this.marks[i].markcount; } } else{ if(this.marks[i].markcount){ this.marks[i].markcount.delete(); delete this.marks[i].markcount; } if(lib.skill[i].mark=='auto'){ this.unmarkSkill(i); } } return this; }, updateMarks:function(connect){ if(typeof connect=='string'&&_status.connectMode&&!game.online){ game.broadcast(function(player,storage,skill){ player.storage[skill]=storage; player.updateMarks(); },this,this.storage[connect],connect); } for(var i in this.marks){ this.updateMark(i); } }, num:function(arg1,arg2,arg3){ if(get.itemtype(arg1)=='position'){ return this.get(arg1,arg2,arg3).length; } else if(arg1=='s'){ if(typeof arg2=='boolean'){ return game.expandSkills(this.getSkills(arg2).concat(lib.skill.global)).contains(arg3); } else{ return game.expandSkills(this.getSkills().concat(lib.skill.global)).contains(arg2); } } }, line:function(target,config){ if(get.itemtype(target)=='players'){ for(var i=0;i<target.length;i++){ this.line(target[i],config); } } else if(get.itemtype(target)=='player'){ if(target==this) return; game.broadcast(function(player,target,config){ player.line(target,config); },this,target,config); game.addVideo('line',this,[target.dataset.position,config]); game.linexy([ this.getLeft()+this.offsetWidth/2, this.getTop()+this.offsetHeight/2, target.getLeft()+target.offsetWidth/2, target.getTop()+target.offsetHeight/2 ],config,true); } }, line2:function(targets,config){ this.line(targets[0],config); targets=targets.slice(0); for(var i=1;i<targets.length;i++){ (function(j){ setTimeout(function(){ targets[j-1].line(targets[j],config); },lib.config.duration*i); }(i)); } }, getNext:function(){ if(this.hasSkill('undist')) return null; var target=this; for(var i=0;i<game.players.length-1;i++){ target=target.next; if(!target.hasSkill('undist')){ return target; } } return null; }, getPrevious:function(){ if(this.hasSkill('undist')) return null; var target=this; for(var i=0;i<game.players.length-1;i++){ target=target.previous; if(!target.hasSkill('undist')){ return target; } } return null; }, countUsed:function(card,type){ if(type===true){ var num=0; var history=this.getHistory('useCard'); for(var i=0;i<history.length;i++){ if(!card) num++; else if(typeof card=='string'&&history[i].card&&card==history[i].card.name) num++; else if(typeof card=='object'&&history[i].card&&card.name==history[i].card.name) num++; } return num; } var num; var stat=this.getStat('card'); if(!card){ num=0; for(var i in stat){ if(typeof stat[i]=='number') num+=stat[i]; } return num; } if(typeof card=='object'){ card=card.name; } num=stat[card]; if(typeof num!='number') return 0; return num; }, countSkill:function(skill){ var num=this.getStat('skill')[skill]; if(num==undefined) return 0; return num; }, getStockSkills:function(unowned,unique,hidden){ var list=[]; if(lib.character[this.name]&&(hidden||!this.isUnseen(0))){ list.addArray(lib.character[this.name][3]); } if(lib.character[this.name1]&&(hidden||!this.isUnseen(0))){ list.addArray(lib.character[this.name1][3]); } if(lib.character[this.name2]&&(hidden||!this.isUnseen(1))){ list.addArray(lib.character[this.name2][3]); } if(!unowned){ for(var i=0;i<list.length;i++){ if(!this.hasSkill(list[i])){ list.splice(i--,1); } } } if(!unique){ for(var i=0;i<list.length;i++){ var info=lib.skill[list[i]]; if(!info||info.unique||info.temp||info.sub||info.charlotte){ list.splice(i--,1); } } } return list; }, getCards:function(arg1,arg2){ if(typeof arg1!='string'){ arg1='h'; } var cards=[],cards1=[]; var i,j; for(i=0;i<arg1.length;i++){ if(arg1[i]=='h'){ for(j=0;j<this.node.handcards1.childElementCount;j++){ if(!this.node.handcards1.childNodes[j].classList.contains('removing')&&!this.node.handcards1.childNodes[j].classList.contains('glows')){ cards.push(this.node.handcards1.childNodes[j]); } } for(j=0;j<this.node.handcards2.childElementCount;j++){ if(!this.node.handcards2.childNodes[j].classList.contains('removing')&&!this.node.handcards2.childNodes[j].classList.contains('glows')){ cards.push(this.node.handcards2.childNodes[j]); } } } else if(arg1[i]=='s'){ for(j=0;j<this.node.handcards1.childElementCount;j++){ if(!this.node.handcards1.childNodes[j].classList.contains('removing')&&this.node.handcards1.childNodes[j].classList.contains('glows')){ cards.push(this.node.handcards1.childNodes[j]); } } for(j=0;j<this.node.handcards2.childElementCount;j++){ if(!this.node.handcards2.childNodes[j].classList.contains('removing')&&this.node.handcards2.childNodes[j].classList.contains('glows')){ cards.push(this.node.handcards2.childNodes[j]); } } } else if(arg1[i]=='e'){ for(j=0;j<this.node.equips.childElementCount;j++){ if(!this.node.equips.childNodes[j].classList.contains('removing')&&!this.node.equips.childNodes[j].classList.contains('feichu')){ cards.push(this.node.equips.childNodes[j]); } } } else if(arg1[i]=='j'){ for(j=0;j<this.node.judges.childElementCount;j++){ if(!this.node.judges.childNodes[j].classList.contains('removing')&&!this.node.judges.childNodes[j].classList.contains('feichu')){ cards.push(this.node.judges.childNodes[j]); if(this.node.judges.childNodes[j].viewAs&&arguments.length>1){ this.node.judges.childNodes[j].tempJudge=this.node.judges.childNodes[j].name; this.node.judges.childNodes[j].name=this.node.judges.childNodes[j].viewAs; cards1.push(this.node.judges.childNodes[j]); } } } } else if(arg1[i]=='x'){ for(j=0;j<this.node.expansions.childElementCount;j++){ if(!this.node.expansions.childNodes[j].classList.contains('removing')){ cards.push(this.node.expansions.childNodes[j]); } } } } if(arguments.length==1){ return cards; } if(arg2){ if(typeof arg2=='string'){ for(i=0;i<cards.length;i++){ if(get.name(cards[i])!=arg2){ cards.splice(i,1);i--; } } } else if(typeof arg2=='object'){ for(i=0;i<cards.length;i++){ for(j in arg2){ var value; if(j=='type'||j=='subtype'||j=='color'||j=='suit'||j=='number'){ value=get[j](cards[i]); } else{ value=cards[i][j]; } if((typeof arg2[j]=='string'&&value!=arg2[j])|| (Array.isArray(arg2[j])&&!arg2[j].contains(value))){ cards.splice(i--,1);break; } } } } else if(typeof arg2=='function'){ for(i=0;i<cards.length;i++){ if(!arg2(cards[i])){ cards.splice(i--,1); } } } } for(i=0;i<cards1.length;i++){ if(cards1[i].tempJudge){ cards1[i].name=cards1[i].tempJudge; delete cards1[i].tempJudge; } } return cards; }, getDiscardableCards:function(player,arg1,arg2){ var cards=this.getCards(arg1,arg2); for(var i=0;i<cards.length;i++){ if(!lib.filter.canBeDiscarded(cards[i],player,this)){ cards.splice(i--,1); } } return cards; }, getGainableCards:function(player,arg1,arg2){ var cards=this.getCards(arg1,arg2); for(var i=0;i<cards.length;i++){ if(!lib.filter.canBeGained(cards[i],player,this)){ cards.splice(i--,1); } } return cards; }, getGainableSkills:function(func){ var list=[]; var names=[this.name,this.name1,this.name2]; for(var i=0;i<names.length;i++){ list.addArray(get.gainableSkillsName(names[i],func)); } return list; }, countCards:function(arg1,arg2){ return this.getCards(arg1,arg2).length; }, countDiscardableCards:function(player,arg1,arg2){ return this.getDiscardableCards(player,arg1,arg2).length; }, countGainableCards:function(player,arg1,arg2){ return this.getGainableCards(player,arg1,arg2).length; }, getOriginalSkills:function(){ var skills=[]; if(lib.character[this.name]&&!this.isUnseen(0)){ skills.addArray(lib.character[this.name][3]); } if(this.name2&&lib.character[this.name2]&&!this.isUnseen(1)){ skills.addArray(lib.character[this.name2][3]); } return skills; }, getModableSkills:function(useCache){ var func = function(player){ var skills=player.getSkills().concat(lib.skill.global); game.expandSkills(skills); skills = skills.filter(function(skill){ var info = get.info(skill); return info && info.mod; }); skills.sort((a,b)=>get.priority(a)-get.priority(b)); return skills; }; if(!useCache)return func(this); return game.callFuncUseStepCache("player.getModableSkills",func,[this]); }, getSkills:function(arg2,arg3,arg4){ var skills=this.skills.slice(0); var es=[]; var i,j; if(arg3!==false){ for(i=0;i<this.node.equips.childElementCount;i++){ if(!this.node.equips.childNodes[i].classList.contains('removing')){ var equipskills=get.info(this.node.equips.childNodes[i],false).skills; if(equipskills){ es.addArray(equipskills); } } } if(arg2=='e'){ return es; } } for(var i in this.additionalSkills){ if(Array.isArray(this.additionalSkills[i])&&(arg2||i.indexOf('hidden:')!==0)){ for(j=0;j<this.additionalSkills[i].length;j++){ if(this.additionalSkills[i][j]){ skills.add(this.additionalSkills[i][j]); } } } else if(this.additionalSkills[i]&&typeof this.additionalSkills[i]=='string'){ skills.add(this.additionalSkills[i]); } } for(var i in this.tempSkills){ skills.add(i); } if(arg2) skills.addArray(this.hiddenSkills); if(arg2===false||arg2=='invisible') skills.addArray(this.invisibleSkills); if(arg3!==false) skills.addArray(es); for(var i in this.forbiddenSkills){ skills.remove(i); } if(arg4!==false){ skills=game.filterSkills(skills,this,es); } return skills; }, get:function(arg1,arg2,arg3,arg4){ var i,j; if(arg1=='s'){ var skills=this.skills.slice(0); var es=[]; if(arg3!==false){ for(i=0;i<this.node.equips.childElementCount;i++){ if(!this.node.equips.childNodes[i].classList.contains('removing')&&!this.node.equips.childNodes[i].classList.contains('feichu')){ var equipskills=get.info(this.node.equips.childNodes[i]).skills; if(equipskills){ es.addArray(equipskills); } } } if(arg2=='e'){ return es; } } for(var i in this.additionalSkills){ if(Array.isArray(this.additionalSkills[i])){ for(j=0;j<this.additionalSkills[i].length;j++){ if(this.additionalSkills[i][j]){ skills.add(this.additionalSkills[i][j]); } } } else if(this.additionalSkills[i]&&typeof this.additionalSkills[i]=='string'){ skills.add(this.additionalSkills[i]); } } for(var i in this.tempSkills){ skills.add(i); } if(arg2) skills.addArray(this.hiddenSkills); if(arg3!==false) skills.addArray(es); for(var i in this.forbiddenSkills){ skills.remove(i); } if(arg4!==false){ skills=game.filterSkills(skills,this,es); } return skills; } else if(get.is.pos(arg1)){ var cards=[],cards1=[]; for(i=0;i<arg1.length;i++){ if(arg1[i]=='h'){ for(j=0;j<this.node.handcards1.childElementCount;j++){ if(!this.node.handcards1.childNodes[j].classList.contains('removing')&&!this.node.handcards1.childNodes[j].classList.contains('feichu')&&!this.node.handcards1.childNodes[j].classList.contains('glows')){ cards.push(this.node.handcards1.childNodes[j]); } } for(j=0;j<this.node.handcards2.childElementCount;j++){ if(!this.node.handcards2.childNodes[j].classList.contains('removing')&&!this.node.handcards2.childNodes[j].classList.contains('feichu')&&!this.node.handcards2.childNodes[j].classList.contains('glows')){ cards.push(this.node.handcards2.childNodes[j]); } } } else if(arg1[i]=='e'){ for(j=0;j<this.node.equips.childElementCount;j++){ if(!this.node.equips.childNodes[j].classList.contains('removing')&&!this.node.equips.childNodes[j].classList.contains('feichu')){ cards.push(this.node.equips.childNodes[j]); } } if(arguments.length==2&&typeof arg2=='string'&&/1|2|3|4|5/.test(arg2)){ for(j=0;j<cards.length;j++){ if(get.subtype(cards[j])=='equip'+arg2) return cards[j]; } return; } } else if(arg1[i]=='j'){ for(j=0;j<this.node.judges.childElementCount;j++){ if(!this.node.judges.childNodes[j].classList.contains('removing')&&!this.node.judges.childNodes[j].classList.contains('feichu')){ cards.push(this.node.judges.childNodes[j]); if(this.node.judges.childNodes[j].viewAs&&arguments.length>1){ this.node.judges.childNodes[j].tempJudge=this.node.judges.childNodes[j].name; this.node.judges.childNodes[j].name=this.node.judges.childNodes[j].viewAs; cards1.push(this.node.judges.childNodes[j]); } } } } } if(arguments.length==1){ return cards; } if(arg2!=undefined){ if(typeof arg3=='function'){ var cards2=cards.slice(0); cards.sort(function(a,b){ return arg3(b,cards2)-arg3(a,cards2); }); } if(typeof arg2=='string'){ for(i=0;i<cards.length;i++){ if(cards[i].name!=arg2){ cards.splice(i,1);i--; } } } else if(typeof arg2=='object'){ for(i=0;i<cards.length;i++){ for(j in arg2){ if(j=='type'){ if(typeof arg2[j]=='object'){ if(arg2[j].contains(get.type(cards[i]))==false){ cards.splice(i,1);i--;break; } } else if(typeof arg2[j]=='string'){ if(get.type(cards[i])!=arg2[j]){ cards.splice(i,1);i--;break; } } } else if(j=='subtype'){ if(typeof arg2[j]=='object'){ if(arg2[j].contains(get.subtype(cards[i]))==false){ cards.splice(i,1);i--;break; } } else if(typeof arg2[j]=='string'){ if(get.subtype(cards[i])!=arg2[j]){ cards.splice(i,1);i--;break; } } } else if(j=='color'){ if(typeof arg2[j]=='object'){ if(arg2[j].contains(get.color(cards[i]))==false){ cards.splice(i,1);i--;break; } } else if(typeof arg2[j]=='string'){ if(get.color(cards[i])!=arg2[j]){ cards.splice(i,1);i--;break; } } } else if(j=='suit'){ if(typeof arg2[j]=='object'){ if(arg2[j].contains(get.suit(cards[i]))==false){ cards.splice(i,1);i--;break; } } else if(typeof arg2[j]=='string'){ if(get.suit(cards[i])!=arg2[j]){ cards.splice(i,1);i--;break; } } } else if(j=='number'){ if(typeof arg2[j]=='object'){ if(arg2[j].contains(get.number(cards[i]))==false){ cards.splice(i,1);i--;break; } } else if(typeof arg2[j]=='string'){ if(get.number(cards[i])!=arg2[j]){ cards.splice(i,1);i--;break; } } } else if(typeof arg2[j]=='object'){ if(arg2[j].contains(cards[i][j])==false){ cards.splice(i,1);i--;break; } } else if(typeof arg2[j]=='string'){ if(cards[i][j]!=arg2[j]){ cards.splice(i,1);i--;break; } } } } } else if(typeof arg2=='number'&&arg2>0){ cards.splice(arg2); } else if(typeof arg2=='function'){ for(i=0;i<cards.length;i++){ if(!arg2(cards[i])){ cards.splice(i,1);i--; } } } } for(i=0;i<cards1.length;i++){ if(cards1[i].tempJudge){ cards1[i].name=cards1[i].tempJudge; delete cards1[i].tempJudge; } } if(arg2===0) return cards[0]; if(typeof arg3=='number'){ if(arg3==0) return cards[0]; cards.splice(arg3); } if(typeof arg4=='number'){ if(arg4==0) return cards[0]; cards.splice(arg4); } return cards; } }, syncStorage:function(skill){ switch(get.itemtype(this.storage[skill])){ case 'cards':game.addVideo('storage',this,[skill,get.cardsInfo(this.storage[skill]),'cards']);break; case 'card':game.addVideo('storage',this,[skill,get.cardInfo(this.storage[skill]),'card']);break; default: try{ game.addVideo('storage',this,[skill,JSON.parse(JSON.stringify(this.storage[skill]))]); } catch(e){ console.log(this.storage[skill]); } } }, syncSkills:function(){ game.broadcast(function(player,skills){ player.applySkills(skills); },this,get.skillState(this)); }, playerfocus:function(time){ time=time||1000; this.classList.add('playerfocus'); ui.arena.classList.add('playerfocus'); var that=this; setTimeout(function(){ that.classList.remove('playerfocus'); ui.arena.classList.remove('playerfocus'); },time); game.addVideo('playerfocus',this,time); game.broadcast(function(player,time){ player.playerfocus(time); },this,time); return this; }, setIdentity:function(identity,nature){ if(!identity) identity=this.identity; if(get.is.jun(this)){ this.node.identity.firstChild.innerHTML='君'; } else{ this.node.identity.firstChild.innerHTML=get.translation(identity); } this.node.identity.dataset.color=nature||identity; return this; }, insertPhase:function(skill,insert){ var evt=_status.event.getParent('phase'); var next; if(evt&&evt.parent&&evt.parent.next){ evt=evt.parent; next=game.createEvent('phase',false,evt); } else if(_status.event.parent&&_status.event.parent.next){ evt=_status.event.parent; next=game.createEvent('phase',false,evt); } else{ evt=null; next=game.createEvent('phase',false); } if(evt&&insert&&evt.next.contains(next)){ evt.next.remove(next); evt.next.unshift(next); } next.player=this; next.forceDie=true; next.includeOut=true; next.skill=skill||_status.event.name; next.setContent('phase'); return next; }, insertEvent:function(name,content,arg){ var evt=_status.event.getParent('phase'); var next; if(evt&&evt.parent&&evt.parent.next){ next=game.createEvent(name,null,evt.parent); } else{ next=game.createEvent(name); } for(var i in arg){ next[i]=arg[i]; } next.player=this; next.setContent(content); return next; }, phase:function(skill){ var next=game.createEvent('phase',false); next.player=this; next.setContent('phase'); if(!_status.roundStart){ _status.roundStart=this; } if(skill){ next.skill=skill; } next.forceDie=true; next.includeOut=true; return next; }, phaseZhunbei:function(){ var next=game.createEvent('phaseZhunbei'); next.player=this; next.setContent('phaseZhunbei'); return next; }, phaseJudge:function(){ var next=game.createEvent('phaseJudge'); next.player=this; next.setContent('phaseJudge'); return next; }, phaseDraw:function(){ var next=game.createEvent('phaseDraw'); next.player=this; next.num=2; if((get.config('first_less')||_status.connectMode||_status.first_less_forced)&&game.phaseNumber==1&&_status.first_less){ next.num--; } next.setContent('phaseDraw'); return next; }, phaseUse:function(){ var next=game.createEvent('phaseUse'); next.player=this; next.setContent('phaseUse'); return next; }, phaseDiscard:function(){ var next=game.createEvent('phaseDiscard'); next.player=this; next.setContent('phaseDiscard'); return next; }, phaseJieshu:function(){ var next=game.createEvent('phaseJieshu'); next.player=this; next.setContent('phaseJieshu'); return next; }, chooseToUse:function(use){ var next=game.createEvent('chooseToUse'); next.player=this; if(arguments.length==1&&get.objtype(arguments[0])=='object'){ for(var i in use){ next[i]=use[i]; } } else{ for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'||get.itemtype(arguments[i])=='select'){ next.selectTarget=arguments[i]; } else if((typeof arguments[i]=='object'&&arguments[i])||typeof arguments[i]=='function'){ if(get.itemtype(arguments[i])=='player'||next.filterCard){ next.filterTarget=arguments[i]; } else next.filterCard=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(typeof arguments[i]=='string'){ next.prompt=arguments[i]; } } } if(typeof next.filterCard=='object'){ next.filterCard=get.filter(next.filterCard); } if(typeof next.filterTarget=='object'){ next.filterTarget=get.filter(next.filterTarget,2); } if(next.filterCard==undefined){ next.filterCard=lib.filter.filterCard; } if(next.selectCard==undefined){ next.selectCard=[1,1]; } if(next.filterTarget==undefined){ next.filterTarget=lib.filter.filterTarget; } if(next.selectTarget==undefined){ next.selectTarget=lib.filter.selectTarget; } if(next.position==undefined){ next.position='hs'; } if(next.ai1==undefined) next.ai1=get.order; if(next.ai2==undefined) next.ai2=get.effect_use; next.setContent('chooseToUse'); next._args=Array.from(arguments); return next; }, chooseToRespond:function(){ var next=game.createEvent('chooseToRespond'); next.player=this; var filter; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ next.selectCard=[arguments[i],arguments[i]]; } else if(get.itemtype(arguments[i])=='select'){ next.selectCard=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(get.itemtype(arguments[i])=='position'){ next.position=arguments[i]; } else if(typeof arguments[i]=='function'){ if(next.filterCard) next.ai=arguments[i]; else next.filterCard=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]){ next.filterCard=get.filter(arguments[i]); filter=arguments[i]; } else if(arguments[i]=='nosource'){ next.nosource=true; } else if(typeof arguments[i]=='string'){ next.prompt=arguments[i]; } } if(next.filterCard==undefined) next.filterCard=lib.filter.all; if(next.selectCard==undefined) next.selectCard=[1,1]; if(next.source==undefined&&!next.nosource) next.source=_status.event.player; if(next.ai==undefined) next.ai=get.unuseful2; if(next.prompt!=false){ if(typeof next.prompt=='string'){ //next.dialog=next.prompt; } else{ var str='请打出'+get.cnNumber(next.selectCard[0])+'张' if(filter){ if(filter.name){ str+=get.translation(filter.name); } else{ str+='牌'; } } else{ str+='牌'; } if(_status.event.getParent().name=='useCard'){ var cardname=_status.event.name; if(lib.card[cardname]&&lib.translate[cardname]){ str+='响应'+lib.translate[cardname]; } } next.prompt=str; } } next.position='hs'; if(next.ai2==undefined) next.ai2=(()=>1); next.setContent('chooseToRespond'); next._args=Array.from(arguments); return next; }, chooseToDiscard:function(){ var next=game.createEvent('chooseToDiscard'); next.player=this; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ next.selectCard=[arguments[i],arguments[i]]; } else if(get.itemtype(arguments[i])=='select'){ next.selectCard=arguments[i]; } else if(get.itemtype(arguments[i])=='dialog'){ next.dialog=arguments[i]; next.prompt=false; } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(get.itemtype(arguments[i])=='position'){ next.position=arguments[i]; } else if(typeof arguments[i]=='function'){ if(next.filterCard) next.ai=arguments[i]; else next.filterCard=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]){ next.filterCard=get.filter(arguments[i]); } else if(typeof arguments[i]=='string'){ get.evtprompt(next,arguments[i]); } if(arguments[i]===null){ for(var i=0;i<arguments.length;i++){ console.log(arguments[i]); } } } if(next.isMine()==false&&next.dialog) next.dialog.style.display='none'; if(next.filterCard==undefined) next.filterCard=lib.filter.all; if(next.selectCard==undefined) next.selectCard=[1,1]; if(next.ai==undefined) next.ai=get.unuseful; next.autochoose=function(){ if(!this.forced) return false; if(typeof this.selectCard=='function') return false; var cards=this.player.getCards(this.position); var num=cards.length; for(var i=0;i<cards.length;i++){ if(!lib.filter.cardDiscardable(cards[i],this.player,this)) num--; } return get.select(this.selectCard)[0]>=num; } next.setContent('chooseToDiscard'); next._args=Array.from(arguments); return next; }, chooseToCompare:function(target,check){ var next=game.createEvent('chooseToCompare'); next.player=this; if(Array.isArray(target)){ next.targets=target; if(check) next.ai=check; else next.ai=function(card){ if(typeof card=='string'&&lib.skill[card]){ var ais=lib.skill[card].check||function(){return 0}; return ais(); } var addi=(get.value(card)>=8&&get.type(card)!='equip')?-3:0; if(card.name=='du') addi-=3; var source=_status.event.source; var player=_status.event.player; var event=_status.event.getParent(); var getn=function(card){ if(player.hasSkill('tianbian')&&get.suit(card)=='heart') return 13*(Boolean(event.small)?-1:1); return get.number(card)*(Boolean(event.small)?-1:1); } if(source&&source!=player){ if(get.attitude(player,source)>1){ if(Boolean(event.small)) return getn(card)-get.value(card)/2+addi; return -getn(card)-get.value(card)/2+addi; } if(Boolean(event.small)) return -getn(card)-get.value(card)/2+addi; return getn(card)-get.value(card)/2+addi; } else{ if(Boolean(event.small)) return -getn(card)-get.value(card)/2+addi; return getn(card)-get.value(card)/2+addi; } } next.setContent('chooseToCompareMultiple'); } else{ next.target=target; if(check) next.ai=check; else next.ai=function(card){ if(typeof card=='string'&&lib.skill[card]){ var ais=lib.skill[card].check||function(){return 0}; return ais(); } var player=get.owner(card); var getn=function(card){ if(player.hasSkill('tianbian')&&get.suit(card)=='heart') return 13; return get.number(card); } var event=_status.event.getParent(); var to=(player==event.player?event.target:event.player); var addi=(get.value(card)>=8&&get.type(card)!='equip')?-6:0; if(card.name=='du') addi-=5; if(player==event.player){ if(Boolean(event.small)){ return -getn(card)-get.value(card)/2+addi; } return getn(card)-get.value(card)/2+addi; } else{ if((get.attitude(player,to)<=0)==Boolean(event.small)){ return -getn(card)-get.value(card)/2+addi; } return getn(card)-get.value(card)/2+addi; } } next.setContent('chooseToCompare'); } next.forceDie=true; next._args=Array.from(arguments); return next; }, chooseSkill:function(target){ var next=game.createEvent('chooseSkill'); next.player=this; next.setContent('chooseSkill'); next.target=target; for(var i=1;i<arguments.length;i++){ if(typeof arguments[i]=='string'){ next.prompt=arguments[i]; } else if(typeof arguments[i]=='function'){ next.func=arguments[i]; } } }, discoverCard:function(list){ var next=game.createEvent('discoverCard'); next.player=this; next.setContent('discoverCard'); next.list=list||lib.inpile.slice(0); next.forced=true; for(var i=1;i<arguments.length;i++){ if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(typeof arguments[i]=='string'){ switch(arguments[i]){ case 'use': next.use=true; break; case 'nogain': next.nogain=true; break; default: next.prompt=arguments[i]; } } else if(typeof arguments[i]=='number'){ next.num=arguments[i]; } else if(typeof arguments[i]==='function'){ next.ai=arguments[i]; } } return next; }, chooseCardButton:function(){ var cards,prompt,forced,select; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='cards') cards=arguments[i]; else if(typeof arguments[i]=='boolean') forced=arguments[i]; else if(typeof arguments[i]=='string') prompt=arguments[i]; else if(get.itemtype(arguments[i])=='select'||typeof arguments[i]=='number') select=arguments[i]; } if(prompt==undefined) prompt='请选择卡牌'; return this.chooseButton(forced,select,'hidden',[prompt,cards,'hidden']); }, chooseVCardButton:function(){ var list,prompt,forced,select,notype=false; for(var i=0;i<arguments.length;i++){ if(Array.isArray(arguments[i])){ list=arguments[i]; } else if(arguments[i]=='notype'){ notype=true; } else if(typeof arguments[i]=='boolean') forced=arguments[i]; else if(typeof arguments[i]=='string') prompt=arguments[i]; else if(get.itemtype(arguments[i])=='select'||typeof arguments[i]=='number') select=arguments[i]; } for(var i=0;i<list.length;i++){ list[i]=[notype?'':(get.subtype(list[i])||get.type(list[i])),'',list[i]]; } if(prompt==undefined) prompt='请选择卡牌'; return this.chooseButton(forced,select,'hidden',[prompt,[list,'vcard'],'hidden']); }, chooseButton:function(){ var next=game.createEvent('chooseButton'); for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(get.itemtype(arguments[i])=='dialog'){ next.dialog=arguments[i]; next.closeDialog=true; } else if(get.itemtype(arguments[i])=='select'){ next.selectButton=arguments[i]; } else if(typeof arguments[i]=='number'){ next.selectButton=[arguments[i],arguments[i]]; } else if(typeof arguments[i]=='function'){ if(next.ai) next.filterButton=arguments[i]; else next.ai=arguments[i]; } else if(Array.isArray(arguments[i])){ next.createDialog=arguments[i]; } } next.player=this; if(typeof next.forced!='boolean') next.forced=false; if(next.isMine()==false&&next.dialog) next.dialog.style.display='none'; if(next.filterButton==undefined) next.filterButton=lib.filter.filterButton; if(next.selectButton==undefined) next.selectButton=[1,1]; if(next.ai==undefined) next.ai=function(){return 1}; next.setContent('chooseButton'); next._args=Array.from(arguments); next.forceDie=true; return next; }, chooseButtonOL:function(list,callback,ai){ var next=game.createEvent('chooseButtonOL'); next.list=list; next.setContent('chooseButtonOL'); next.ai=ai; next.callback=callback; next._args=Array.from(arguments); return next; }, chooseCardOL:function(){ var next=game.createEvent('chooseCardOL'); next._args=[]; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='players'){ next.list=arguments[i].slice(0); } else{ next._args.push(arguments[i]); } } next.setContent('chooseCardOL'); next._args.add('glow_result'); return next; }, chooseCard:function(choose){ var next=game.createEvent('chooseCard'); next.player=this; if(arguments.length==1&&get.is.object(choose)){ for(var i in choose){ next[i]=choose[i]; } } else{ for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ next.selectCard=[arguments[i],arguments[i]]; } else if(get.itemtype(arguments[i])=='select'){ next.selectCard=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(get.itemtype(arguments[i])=='position'){ next.position=arguments[i]; } else if(typeof arguments[i]=='function'){ if(next.filterCard) next.ai=arguments[i]; else next.filterCard=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]){ next.filterCard=get.filter(arguments[i]); } else if(arguments[i]=='glow_result'){ next.glow_result=true; } else if(typeof arguments[i]=='string'){ get.evtprompt(next,arguments[i]); } } } if(next.filterCard==undefined) next.filterCard=lib.filter.all; if(next.selectCard==undefined) next.selectCard=[1,1]; if(next.ai==undefined) next.ai=get.unuseful3; next.setContent('chooseCard'); next._args=Array.from(arguments); return next; }, chooseUseTarget:function(){ var next=game.createEvent('chooseUseTarget'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.card=arguments[i]; } else if(get.itemtype(arguments[i])=='players'){ next.targets=arguments[i]; } else if(get.itemtype(arguments[i])=='player'){ next.targets=[arguments[i]]; } else if(get.itemtype(arguments[i])=='select'){ next.selectTarget=arguments[i]; } else if(typeof arguments[i]=='number'){ next.selectTarget=[arguments[i],arguments[i]]; } else if(get.is.object(arguments[i])&&arguments[i].name){ next.card=arguments[i]; } else if(typeof arguments[i]=='string'){ if(arguments[i]=='nopopup'){ next.nopopup=true; } else if(arguments[i]=='noanimate'){ next.animate=false; } else if(arguments[i]=='nothrow'){ next.throw=false; } else if(arguments[i]=='nodistance'){ next.nodistance=true; } else if(arguments[i]=='noTargetDelay'){ next.noTargetDelay=true; } else if(arguments[i]=='nodelayx'){ next.nodelayx=true; } else if(lib.card[arguments[i]]&&!next.card){ next.card={name:arguments[i],isCard:true}; } else get.evtprompt(next,arguments[i]); } else if(arguments[i]===true){ next.forced=true; } else if(arguments[i]===false){ next.addCount=false; } } if(!next.targets) next.targets=game.players.slice(0); if(next.cards==undefined){ if(get.itemtype(next.card)=='card'){ next.cards=[next.card]; } else next.cards=[]; } else if(next.card==undefined){ if(next.cards){ next.card=next.cards[0]; } } next.setContent('chooseUseTarget'); next._args=Array.from(arguments); return next; // Fully Online-Ready! Enjoy It! }, chooseTarget:function(){ var next=game.createEvent('chooseTarget'); next.player=this; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ next.selectTarget=[arguments[i],arguments[i]]; } else if(get.itemtype(arguments[i])=='select'){ next.selectTarget=arguments[i]; } else if(get.itemtype(arguments[i])=='dialog'){ next.dialog=arguments[i]; next.prompt=false; } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(typeof arguments[i]=='function'){ if(next.filterTarget) next.ai=arguments[i]; else next.filterTarget=arguments[i]; } else if(typeof arguments[i]=='string'){ get.evtprompt(next,arguments[i]); } } if(next.filterTarget==undefined) next.filterTarget=lib.filter.all; if(next.selectTarget==undefined) next.selectTarget=[1,1]; if(next.ai==undefined) next.ai=get.attitude2; next.setContent('chooseTarget'); next._args=Array.from(arguments); next.forceDie=true; return next; }, chooseCardTarget:function(choose){ var next=game.createEvent('chooseCardTarget'); next.player=this; if(arguments.length==1){ for(var i in choose){ next[i]=choose[i]; } } if(typeof next.filterCard=='object'){ next.filterCard=get.filter(next.filterCard); } if(typeof next.filterTarget=='object'){ next.filterTarget=get.filter(next.filterTarget,2); } if(next.filterCard==undefined||next.filterCard===true){ next.filterCard=lib.filter.all; } if(next.selectCard==undefined){ next.selectCard=1; } if(next.filterTarget==undefined||next.filterTarget===true){ next.filterTarget=lib.filter.all; } if(next.selectTarget==undefined){ next.selectTarget=1; } if(next.ai1==undefined) next.ai1=get.unuseful2; if(next.ai2==undefined) next.ai2=get.attitude2; next.setContent('chooseCardTarget'); next._args=Array.from(arguments); return next; }, chooseControlList:function(){ var list=[]; var prompt=null; var forced='cancel2'; var func=null; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='string'){ if(!prompt){ prompt=arguments[i]; } else{ list.push(arguments[i]); } } else if(Array.isArray(arguments[i])){ list=arguments[i]; } else if(arguments[i]===true){ forced=null; } else if(typeof arguments[i]=='function'){ func=arguments[i]; } } return this.chooseControl(forced,func).set('choiceList',list).set('prompt',prompt); }, chooseControl:function(){ var next=game.createEvent('chooseControl'); next.controls=[]; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='string'){ if(arguments[i]=='dialogcontrol'){ next.dialogcontrol=true; } else if(arguments[i]=='seperate'){ next.seperate=true; } else{ next.controls.push(arguments[i]); } } else if(Array.isArray(arguments[i])){ next.controls=next.controls.concat(arguments[i]); } else if(typeof arguments[i]=='function'){ next.ai=arguments[i]; } else if(typeof arguments[i]=='number'){ next.choice=arguments[i]; } else if(get.itemtype(arguments[i])=='dialog'){ next.dialog=arguments[i]; } } next.player=this; if(next.choice==undefined) next.choice=0; next.setContent('chooseControl'); next._args=Array.from(arguments); next.forceDie=true; return next; }, chooseBool:function(){ var next=game.createEvent('chooseBool'); for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='boolean'){ next.choice=arguments[i]; } else if(typeof arguments[i]=='function'){ next.ai=arguments[i]; } else if(typeof arguments[i]=='string'){ get.evtprompt(next,arguments[i]); } else if(get.itemtype(arguments[i])=='dialog'){ next.dialog=arguments[i]; } if(next.choice==undefined) next.choice=true; } next.player=this; next.setContent('chooseBool'); next._args=Array.from(arguments); next.forceDie=true; return next; }, chooseDrawRecover:function(){ var next=game.createEvent('chooseDrawRecover',false); next.player=this; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ if(typeof next.num1=='number'){ next.num2=arguments[i]; } else{ next.num1=arguments[i]; } } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(typeof arguments[i]=='string'){ next.prompt=arguments[i]; } else if(typeof arguments[i]=='function'){ next.ai=arguments[i]; } } if(typeof next.num1!='number'){ next.num1=1; } if(typeof next.num2!='number'){ next.num2=1; } next.setContent('chooseDrawRecover'); return next; }, choosePlayerCard:function(){ var next=game.createEvent('choosePlayerCard'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.target=arguments[i]; } else if(typeof arguments[i]=='number'){ next.selectButton=[arguments[i],arguments[i]]; } else if(get.itemtype(arguments[i])=='select'){ next.selectButton=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(get.itemtype(arguments[i])=='position'){ next.position=arguments[i]; } else if(arguments[i]=='visible'){ next.visible=true; } else if(typeof arguments[i]=='function'){ if(next.ai) next.filterButton=arguments[i]; else next.ai=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]){ next.filterButton=get.filter(arguments[i]); } else if(typeof arguments[i]=='string'){ next.prompt=arguments[i]; } } if(next.filterButton==undefined) next.filterButton=lib.filter.all; if(next.position==undefined) next.position='he'; if(next.selectButton==undefined) next.selectButton=[1,1]; if(next.ai==undefined) next.ai=function(button){ var val=get.buttonValue(button); if(get.attitude(_status.event.player,get.owner(button.link))>0) return -val; return val; }; next.setContent('choosePlayerCard'); next._args=Array.from(arguments); return next; }, discardPlayerCard:function(){ var next=game.createEvent('discardPlayerCard'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.target=arguments[i]; } else if(typeof arguments[i]=='number'){ next.selectButton=[arguments[i],arguments[i]]; } else if(get.itemtype(arguments[i])=='select'){ next.selectButton=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(get.itemtype(arguments[i])=='position'){ next.position=arguments[i]; } else if(arguments[i]=='visible'){ next.visible=true; } else if(typeof arguments[i]=='function'){ if(next.ai) next.filterButton=arguments[i]; else next.ai=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]){ next.filterButton=get.filter(arguments[i]); } else if(typeof arguments[i]=='string'){ next.prompt=arguments[i]; } } if(next.filterButton==undefined) next.filterButton=lib.filter.all; if(next.position==undefined) next.position='he'; if(next.selectButton==undefined) next.selectButton=[1,1]; if(next.ai==undefined) next.ai=function(button){ var val=get.buttonValue(button); if(get.attitude(_status.event.player,get.owner(button.link))>0) return -val; return val; }; next.setContent('discardPlayerCard'); next._args=Array.from(arguments); return next; }, gainPlayerCard:function(){ var next=game.createEvent('gainPlayerCard'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.target=arguments[i]; } else if(typeof arguments[i]=='number'){ next.selectButton=[arguments[i],arguments[i]]; } else if(get.itemtype(arguments[i])=='select'){ next.selectButton=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(get.itemtype(arguments[i])=='position'){ next.position=arguments[i]; } else if(arguments[i]=='visible'){ next.visible=true; } else if(arguments[i]=='visibleMove'){ next.visibleMove=true; } else if(typeof arguments[i]=='function'){ if(next.ai) next.filterButton=arguments[i]; else next.ai=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]){ next.filterButton=get.filter(arguments[i]); } else if(typeof arguments[i]=='string'){ next.prompt=arguments[i]; } } if(next.filterButton==undefined) next.filterButton=lib.filter.all; if(next.position==undefined) next.position='he'; if(next.selectButton==undefined) next.selectButton=[1,1]; if(next.ai==undefined) next.ai=function(button){ var val=get.buttonValue(button); if(get.attitude(_status.event.player,get.owner(button.link))>0) return -val; return val; }; next.setContent('gainPlayerCard'); next._args=Array.from(arguments); return next; }, showHandcards:function(str){ var next=game.createEvent('showHandcards'); next.player=this; if(typeof str=='string'){ next.prompt=str; } next.setContent('showHandcards'); next._args=Array.from(arguments); return next; }, showCards:function(cards,str){ var next=game.createEvent('showCards'); next.player=this; next.str=str; if(typeof cards=='string'){ str=cards; cards=next.str; next.str=str; } if(get.itemtype(cards)=='card') next.cards=[cards]; else if(get.itemtype(cards)=='cards') next.cards=cards.slice(0); else _status.event.next.remove(next); next.setContent('showCards'); next._args=Array.from(arguments); return next; }, viewCards:function(str,cards){ var next=game.createEvent('viewCards'); next.player=this; next.str=str; next.cards=cards.slice(0); next.setContent('viewCards'); next._args=Array.from(arguments); return next; }, viewHandcards:function(target){ var cards=target.getCards('h'); if(cards.length){ return this.viewCards(get.translation(target)+'的手牌',cards); } else{ return false; } }, canMoveCard:function(withatt,nojudge){ var player=this; return game.hasPlayer(function(current){ var att=get.sgn(get.attitude(player,current)); if(!withatt||att!=0){ var es=current.getCards('e'); for(var i=0;i<es.length;i++){ if(game.hasPlayer(function(current2){ if(withatt){ if(get.sgn(get.value(es[i],current))!=-att) return false; var att2=get.sgn(get.attitude(player,current2)); if(att==att2||att2!=get.sgn(get.effect(current2,es[i],player,current2))) return false; } return current!=current2&&!current2.isMin()&¤t2.canEquip(es[i]); })){ return true; } } } if(!nojudge&&(!withatt||att>0)){ var js=current.getCards('j'); for(var i=0;i<js.length;i++){ if(game.hasPlayer(function(current2){ if(withatt){ var att2=get.attitude(player,current2); if(att2>=0) return false; } return current!=current2&¤t2.canAddJudge(js[i]); })){ return true; } } } }); }, moveCard:function(){ var next=game.createEvent('moveCard'); next.player=this; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='boolean'){ next.forced=arguments[i]; } else if(typeof arguments[i]=='string'){ get.evtprompt(next,arguments[i]); } else if(Array.isArray(arguments[i])){ for(var j=0;j<arguments[i].length;j++){ if(typeof arguments[i][j]!='string') break; } if(j==arguments[i].length){ next.targetprompt=arguments[i]; } } } next.setContent('moveCard'); next._args=Array.from(arguments); return next; }, useResult:function(result,event){ event=event||_status.event; if(result._sendskill){ lib.skill[result._sendskill[0]]=result._sendskill[1]; } if(event.onresult){ event.onresult(result); } if(result.skill){ var info=get.info(result.skill); if(info.onuse){ info.onuse(result,this); } if(info.direct&&!info.clearTime){ _status.noclearcountdown=true; } } if(event.logSkill){ if(typeof event.logSkill=='string'){ this.logSkill(event.logSkill); } else if(Array.isArray(event.logSkill)){ this.logSkill.apply(this,event.logSkill); } } if(result.card||!result.skill){ result.used=result.card||result.cards[0]; var next=this.useCard(result.used,result.cards,result.targets,result.skill); next.oncard=event.oncard; next.respondTo=event.respondTo; if(event.addCount===false){ next.addCount=false; } if(result._apply_args){ for(var i in result._apply_args){ next[i]=result._apply_args[i]; } } return next; } else if(result.skill){ result.used=result.skill; return this.useSkill(result.skill,result.cards,result.targets); } }, useCard:function(){ var next=game.createEvent('useCard'); next.player=this; next.num=0; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='players'){ next.targets=arguments[i]; } else if(get.itemtype(arguments[i])=='player'){ next.targets=[arguments[i]]; } else if(get.itemtype(arguments[i])=='card'){ next.card=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]&&arguments[i].name){ next.card=arguments[i]; } else if(typeof arguments[i]=='string'){ if(arguments[i]=='noai'){ next.noai=true; } else if(arguments[i]=='nowuxie'){ next.nowuxie=true; } else{ next.skill=arguments[i]; } } else if(typeof arguments[i]=='boolean'){ next.addCount=arguments[i]; } } if(next.cards==undefined){ if(get.itemtype(next.card)=='card'){ next.cards=[next.card]; } else next.cards=[]; } else if(next.card==undefined){ if(next.cards){ next.card=next.cards[0]; } } if(!next.targets){ next.targets=[]; } if(next.card){ next.card=get.autoViewAs(next.card,next.cards); var info=get.info(next.card); if(info.changeTarget){ info.changeTarget(next.player,next.targets); } if(info.singleCard){ next._targets=next.targets.slice(0); next.target=next.targets[0]; next.addedTargets=next.targets.splice(1); if(next.addedTargets.length){ next.addedTarget=next.addedTargets[0]; } } } for(var i=0;i<next.targets.length;i++){ if(get.attitude(this,next.targets[i])>=-1&&get.attitude(this,next.targets[i])<0){ if(!this.ai.tempIgnore) this.ai.tempIgnore=[]; this.ai.tempIgnore.add(next.targets[i]); } } if(typeof this.logAi=='function'&&!next.noai&&!get.info(next.card).noai){ var postAi=get.info(next.card).postAi; if(postAi&&postAi(next.targets)){ next.postAi=true; } else{ this.logAi(next.targets,next.card); } } next.stocktargets=next.targets.slice(0); next.setContent('useCard'); return next; }, useSkill:function(){ var next=game.createEvent('useSkill'); next.player=this; next.num=0; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='players'){ next.targets=arguments[i]; } else if(get.itemtype(arguments[i])=='card'){ next.card=arguments[i]; } else if(typeof arguments[i]=='string'){ next.skill=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.addCount=arguments[i]; } } if(next.cards==undefined){ next.cards=[]; } if(next.skill&&get.info(next.skill)&&get.info(next.skill).changeTarget){ get.info(next.skill).changeTarget(next.player,next.targets); } if(next.targets){ for(var i=0;i<next.targets.length;i++){ if(get.attitude(this,next.targets[i])>=-1&&get.attitude(this,next.targets[i])<0){ if(!this.ai.tempIgnore) this.ai.tempIgnore=[]; this.ai.tempIgnore.add(next.targets[i]); } } if(typeof this.logAi=='function'){ this.logAi(next.targets,next.skill); } } else{ next.targets=[]; } next.setContent('useSkill'); return next; }, drawTo:function(num,args){ var num2=num-this.countCards('h'); if(!num2) return; var next=this.draw(num2); if(Array.isArray(args)){ for(var i=0;i<args.length;i++){ if(get.itemtype(args[i])=='player'){ next.source=args[i]; } else if(typeof args[i]=='boolean'){ next.animate=args[i]; } else if(args[i]=='nodelay'){ next.animate=false; next.$draw=true; } else if(args[i]=='visible'){ next.visible=true; } else if(args[i]=='bottom'){ next.bottom=true; } else if(typeof args[i]=='object'&&args[i]&&args[i].drawDeck!=undefined){ next.drawDeck=args[i].drawDeck; } } } return next; }, draw:function(){ var next=game.createEvent('draw'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(typeof arguments[i]=='number'){ next.num=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.animate=arguments[i]; } else if(arguments[i]=='nodelay'){ next.animate=false; next.$draw=true; } else if(arguments[i]=='visible'){ next.visible=true; } else if(arguments[i]=='bottom'){ next.bottom=true; } else if(typeof arguments[i]=='object'&&arguments[i]&&arguments[i].drawDeck!=undefined){ next.drawDeck=arguments[i].drawDeck; } } if(next.num==undefined) next.num=1; if(next.num<=0) _status.event.next.remove(next); next.setContent('draw'); if(lib.config.mode=='stone'&&_status.mode=='deck'&& next.drawDeck==undefined&&!next.player.isMin()&&next.num>1){ next.drawDeck=1; } next.result=[]; return next; }, randomDiscard:function(){ var position='he',num=1,delay=null; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ num=arguments[i]; } else if(get.itemtype(arguments[i])=='position'){ position=arguments[i]; } else if(typeof arguments[i]=='boolean'){ delay=arguments[i]; } } var cards=this.getCards(position).randomGets(num); if(cards.length){ var next=this.discard(cards,'notBySelf'); if(typeof delay=='boolean'){ next.delay=delay; } } return cards; }, randomGain:function(){ var position='he',num=1,target=null,line=false; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ num=arguments[i]; } else if(get.itemtype(arguments[i])=='position'){ position=arguments[i]; } else if(get.itemtype(arguments[i])=='player'){ target=arguments[i]; } else if(typeof arguments[i]=='boolean'){ line=arguments[i]; } } if(target){ var cards=target.getCards(position).randomGets(num); if(cards.length){ if(line){ this.line(target,'green'); } this.gain(cards,target,'log','bySelf'); target.$giveAuto(cards,this); } return cards; } return []; }, discard:function(){ var next=game.createEvent('discard'); next.player=this; next.num=0; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.cards=[arguments[i]]; } else if(typeof arguments[i]=='boolean'){ next.animate=arguments[i]; } else if(get.objtype(arguments[i])=='div'){ next.position=arguments[i]; } else if(arguments[i]=='notBySelf'){ next.notBySelf=true; } } if(next.cards==undefined) _status.event.next.remove(next); next.setContent('discard'); return next; }, loseToDiscardpile:function(){ var next=game.createEvent('loseToDiscardpile'); next.player=this; next.num=0; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.cards=[arguments[i]]; } else if(typeof arguments[i]=='boolean'){ next.animate=arguments[i]; } else if(get.objtype(arguments[i])=='div'){ next.position=arguments[i]; } else if(arguments[i]=='notBySelf'){ next.notBySelf=true; } else if(arguments[i]=='insert'){ next.insert_card=true; } else if(arguments[i]=='blank'){ next.blank=true; } } if(next.cards==undefined) _status.event.next.remove(next); next.setContent('loseToDiscardpile'); return next; }, respond:function(){ var next=game.createEvent('respond'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.card=arguments[i]; } else if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]&&arguments[i].name){ next.card=arguments[i]; } else if(typeof arguments[i]=='boolean') next.animate=arguments[i]; else if(arguments[i]=='highlight') next.highlight=true; else if(arguments[i]=='noOrdering') next.noOrdering=true; else if(typeof arguments[i]=='string') next.skill=arguments[i]; } if(next.cards==undefined){ if(get.itemtype(next.card)=='card'){ next.cards=[next.card]; } else{ next.cards=[]; } } else if(next.card==undefined){ if(next.cards){ next.card=next.cards[0]; if(!next.skill){ next.card=get.autoViewAs(next.card,next.cards); } } } next.setContent('respond'); return next; }, swapHandcards:function(target,cards1,cards2){ var next=game.createEvent('swapHandcards',false); next.player=this; next.target=target; if(cards1) next.cards1=cards1; if(cards2) next.cards2=cards2; next.setContent('swapHandcards'); return next; }, directequip:function(cards){ for(var i=0;i<cards.length;i++){ this.$equip(cards[i]); } if(!_status.video){ game.addVideo('directequip',this,get.cardsInfo(cards)); } }, $addToExpansion:function(cards,broadcast,gaintag){ var hs=this.getCards('x'); for(var i=0;i<cards.length;i++){ if(hs.contains(cards[i])){ cards.splice(i--,1); } } for(var i=0;i<cards.length;i++){ cards[i].fix(); if(gaintag) cards[i].addGaintag(gaintag); var sort=lib.config.sort_card(cards[i]); this.node.expansions.insertBefore(cards[i],this.node.expansions.firstChild); } if(broadcast!==false) game.broadcast(function(player,cards,gaintag){ player.$addToExpansion(cards,null,gaintag); },this,cards,gaintag); return this; }, directgain:function(cards,broadcast,gaintag){ var hs=this.getCards('hs'); for(var i=0;i<cards.length;i++){ if(hs.contains(cards[i])){ cards.splice(i--,1); } } for(var i=0;i<cards.length;i++){ cards[i].fix(); if(gaintag) cards[i].addGaintag(gaintag); var sort=lib.config.sort_card(cards[i]); if(this==game.me){ cards[i].classList.add('drawinghidden'); } if(get.is.singleHandcard()||sort>0){ this.node.handcards1.insertBefore(cards[i],this.node.handcards1.firstChild); } else{ this.node.handcards2.insertBefore(cards[i],this.node.handcards2.firstChild); } } if(this==game.me||_status.video) ui.updatehl(); if(!_status.video){ game.addVideo('directgain',this,get.cardsInfo(cards)); this.update(); } if(broadcast!==false) game.broadcast(function(player,cards){ player.directgain(cards); },this,cards); return this; }, directgains:function(cards,broadcast,gaintag){ var hs=this.getCards('hs'); for(var i=0;i<cards.length;i++){ if(hs.contains(cards[i])){ cards.splice(i--,1); } } var addLast=function(card,node){ if(gaintag){ for(var i=0;i<node.childNodes.length;i++){ var add=node.childNodes[node.childNodes.length-i-1]; if(!add.classList.contains('glows')) break; if(add.hasGaintag(gaintag)){ node.insertBefore(card,add.nextSibling); return; } } } node.appendChild(card); } for(var i=0;i<cards.length;i++){ cards[i].fix(); cards[i].remove(); if(gaintag) cards[i].addGaintag(gaintag); cards[i].classList.add('glows'); if(this==game.me){ cards[i].classList.add('drawinghidden'); } if(get.is.singleHandcard()){ addLast(cards[i],this.node.handcards1); } else{ addLast(cards[i],this.node.handcards2); } } if(this==game.me||_status.video) ui.updatehl(); if(!_status.video){ game.addVideo('directgains',this,get.cardsInfo(cards)); this.update(); } if(broadcast!==false) game.broadcast(function(player,cards,gaintag){ player.directgains(cards,null,gaintag); },this,cards,gaintag); return this; }, gainMultiple:function(targets,position){ var next=game.createEvent('gainMultiple',false); next.setContent('gainMultiple'); next.player=this; next.targets=targets; next.position=position||'h'; return next; }, gain:function(){ var next=game.createEvent('gain'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.cards=[arguments[i]]; } else if(arguments[i]==='log'){ next.log=true; } else if(arguments[i]=='fromStorage'){ next.fromStorage=true; } else if(arguments[i]=='fromRenku'){ next.fromStorage=true; next.fromRenku=true; } else if(arguments[i]=='bySelf'){ next.bySelf=true; } else if(typeof arguments[i]=='string'){ next.animate=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.delay=arguments[i]; } } if(next.animate=='gain2'||next.animate=='draw2'){ if(!next.hasOwnProperty('log')){ next.log=true; } } next.setContent('gain'); next.getd=function(player,key,position){ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); }); return cards; }; next.getl=function(player){ const that=this; const map={ player:player, hs:[], es:[], js:[], ss:[], xs:[], cards:[], cards2:[], gaintag_map:{}, }; player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); map.js.addArray(evt.js); map.ss.addArray(evt.ss); map.xs.addArray(evt.xs); map.cards.addArray(evt.cards); map.cards2.addArray(evt.cards2); for(let key in evt.gaintag_map){ if(!map.gaintag_map[key]) map.gaintag_map[key]=[]; map.gaintag_map[key].addArray(evt.gaintag_map[key]); } } }); return map; }; next.getg=function(player){ if(this.getlx===false||player!=this.player||!this.cards) return []; return this.cards.slice(0); } next.gaintag=[]; return next; }, addToExpansion:function(){ var next=game.createEvent('addToExpansion'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.cards=[arguments[i]]; } else if(arguments[i]==='log'){ next.log=true; } else if(arguments[i]=='fromStorage'){ next.fromStorage=true; } else if(arguments[i]=='fromRenku'){ next.fromStorage=true; next.fromRenku=true; } else if(arguments[i]=='bySelf'){ next.bySelf=true; } else if(typeof arguments[i]=='string'){ next.animate=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.delay=arguments[i]; } } if(next.animate=='gain2'||next.animate=='draw2'||next.animate=='give'){ if(!next.hasOwnProperty('log')){ next.log=true; } } next.setContent('addToExpansion'); next.getd=function(player,key,position){ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); }); return cards; }; next.getl=function(player){ const that=this; const map={ player:player, hs:[], es:[], js:[], ss:[], xs:[], cards:[], cards2:[], gaintag_map:{}, }; player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); map.js.addArray(evt.js); map.ss.addArray(evt.ss); map.xs.addArray(evt.xs); map.cards.addArray(evt.cards); map.cards2.addArray(evt.cards2); for(let key in evt.gaintag_map){ if(!map.gaintag_map[key]) map.gaintag_map[key]=[]; map.gaintag_map[key].addArray(evt.gaintag_map[key]); } } }); return map; }; next.gaintag=[]; return next; }, give:function(cards,target,visible){ var next=target.gain(cards,this); next.animate=visible?'give':'giveAuto'; next.giver=this; return next; }, lose:function(){ var next=game.createEvent('lose'); next.player=this; next.forceDie=true; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.cards=[arguments[i]]; } else if(get.objtype(arguments[i])=='div'){ next.position=arguments[i]; } else if(arguments[i]=='toStorage'){ next.toStorage=true; } else if(arguments[i]=='toRenku'){ next.toStorage=true; next.toRenku=true; } else if(arguments[i]=='visible'){ next.visible=true; } else if(arguments[i]=='insert'){ next.insert_card=true; } } if(next.cards){ var hej=this.getCards('hejsx'); for(var i=0;i<next.cards.length;i++){ if(!hej.contains(next.cards[i])){ next.cards.splice(i--,1); } } } if(!next.cards||!next.cards.length){ _status.event.next.remove(next); } else{ if(next.position==undefined) next.position=ui.discardPile; next.cards=next.cards.slice(0); } next.setContent('lose'); next.getd=function(player,key,position){ if(!position) position=ui.discardPile; if(!key) key='cards'; if(this.getlx===false||this.position!=position||(player&&this.player!=player)||!Array.isArray(this[key])) return []; return this[key].slice(0); }; next.getl=function(player){ if(this.getlx!==false&&this.player==player) return this; return { player:player, hs:[], es:[], js:[], ss:[], xs:[], cards:[], cards2:[], gaintag_map:{}, }; }; return next; }, damage:function(){ var next=game.createEvent('damage'); //next.forceDie=true; next.player=this; var nocard,nosource; var event=_status.event; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.card=arguments[i]; } else if(typeof arguments[i]=='number'){ next.num=arguments[i]; } else if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]&&arguments[i].name){ next.card=arguments[i]; } else if(arguments[i]=='nocard'){ nocard=true; } else if(arguments[i]=='nosource'){ nosource=true; } else if(arguments[i]=='notrigger'){ next._triggered=null; next.notrigger=true; } else if(arguments[i]=='unreal'){ next.unreal=true } else if(get.itemtype(arguments[i])=='nature'&&arguments[i]!='stab'){ next.nature=arguments[i]; } else if(get.itemtype(arguments[i])=='natures'){ var natures=arguments[i].split(lib.natureSeparator); natures.remove('stab'); if(natures.length) next.nature=natures.join(lib.natureSeparator); } } if(next.card==undefined&&!nocard) next.card=event.card; if(next.cards==undefined&&!nocard) next.cards=event.cards; if(next.source==undefined&&!nosource) next.source=event.customSource||event.player; if(next.source&&next.source.isDead()) delete next.source; if(next.unreal==undefined) next.unreal=false; if(next.num==undefined) next.num=(event.baseDamage||1)+(event.extraDamage||0); next.original_num=next.num; next.change_history=[]; next.hasNature=function(nature){ if(!nature) return Boolean(this.nature&&this.nature.length>0); let natures=get.natureList(nature),naturesx=get.natureList(this.nature); if(nature=='linked') return naturesx.some(n=>lib.linked.includes(n)); return get.is.sameNature(natures,naturesx); }; if(next.hasNature('poison')) delete next._triggered; next.setContent('damage'); next.filterStop=function(){ if(this.source&&this.source.isDead()) delete this.source; var num=this.original_num; for(var i of this.change_history) num+=i; if(num!=this.num) this.change_history.push(this.num-num); if(this.num<=0){ delete this.filterStop; this.trigger('damageZero'); this.finish(); this._triggered=null; return true; } }; return next; }, recover:function(){ var next=game.createEvent('recover'); next.player=this; var nocard,nosource; var event=_status.event; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='cards'){ next.cards=arguments[i].slice(0); } else if(get.itemtype(arguments[i])=='card'){ next.card=arguments[i]; } else if(get.itemtype(arguments[i])=='player'){ next.source=arguments[i]; } else if(typeof arguments[i]=='object'&&arguments[i]&&arguments[i].name){ next.card=arguments[i]; } else if(typeof arguments[i]=='number'){ next.num=arguments[i]; } else if(arguments[i]=='nocard'){ nocard=true; } else if(arguments[i]=='nosource'){ nosource=true; } } if(next.card==undefined&&!nocard) next.card=event.card; if(next.cards==undefined&&!nocard) next.cards=event.cards; if(next.source==undefined&&!nosource) next.source=event.customSource||event.player; if(next.num==undefined) next.num=(event.baseDamage||1)+(event.extraDamage||0); if(next.num<=0) _status.event.next.remove(next); next.setContent('recover'); return next; }, doubleDraw:function(){ if(get.is.changban()) return; var next=game.createEvent('doubleDraw'); next.player=this; next.setContent('doubleDraw'); return next; }, loseHp:function(num){ var next=game.createEvent('loseHp'); next.num=num; next.player=this; if(next.num==undefined) next.num=1; next.setContent('loseHp'); return next; }, loseMaxHp:function(){ var next=game.createEvent('loseMaxHp'); next.player=this; next.num=1; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]==='number'){ next.num=arguments[i]; } else if(typeof arguments[i]==='boolean'){ next.forced=arguments[i]; } } next.setContent('loseMaxHp'); return next; }, gainMaxHp:function(){ var next=game.createEvent('gainMaxHp'); next.player=this; next.num=1; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]==='number'){ next.num=arguments[i]; } else if(typeof arguments[i]==='boolean'){ next.forced=arguments[i]; } } next.setContent('gainMaxHp'); return next; }, changeHp:function(num,popup){ var next=game.createEvent('changeHp'); next.num=num; if(popup!=undefined) next.popup=popup; next.player=this; next.setContent('changeHp'); return next; }, changeHujia:function(num,type,limit){ var next=game.createEvent('changeHujia'); if(typeof num!='number'){ num=1; } next.num=num; next.player=this; if(type) next.type=type; next.setContent('changeHujia'); if(limit===true) limit=5; if(typeof limit=='number'&&this.hujia+num>parseInt(limit)){ var numx=parseInt(limit)-this.hujia; if(numx>0) next.num=numx; else _status.event.next.remove(next); } return next; }, getBuff:function(){ var list=[1,2,3,4,5,6]; var nodelay=false; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ list.remove(arguments[i]); } else if(arguments[i]===false){ nodelay=true; } } if(this.isHealthy()){ list.remove(2); } if(!this.countCards('j')){ list.remove(5); } if(!this.isLinked()&&!this.isTurnedOver()){ list.remove(6); } if(this.hasSkill('qianxing')){ list.remove(4); } switch(list.randomGet()){ case 1:this.draw(nodelay?'nodelay':1);break; case 2:this.recover();break; case 3:this.changeHujia();break; case 4:this.tempHide(); case 5:this.discard(this.getCards('j')).delay=(!nodelay);break; case 6:{ if(this.isLinked()) this.link(); if(this.isTurnedOver()) this.turnOver(); break; } } return this; }, getDebuff:function(){ var list=[1,2,3,4,5,6]; var nodelay=false; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ list.remove(arguments[i]); } else if(arguments[i]===false){ nodelay=true; } } if(this.countCards('he')==0){ list.remove(1); } if(this.isLinked()){ list.remove(4); } if(this.hasSkill('fengyin')){ list.remove(5); } if(this.hp==1){ list.remove(3); if(list.length>1) list.remove(2); } if(!list.length) return this; var num=list.randomGet(); switch(list.randomGet()){ case 1:this.randomDiscard(nodelay?false:'he');break; case 2:this.loseHp();break; case 3:this.damage();break; case 4:if(!this.isLinked()) this.link();break; case 5:this.addTempSkill('fengyin',{player:'phaseAfter'});break; case 6:{ var list=[]; for(var i=0;i<lib.inpile.length;i++){ var info=lib.card[lib.inpile[i]]; if(info.type=='delay'&&!info.cancel&&!this.hasJudge(lib.inpile[i])){ list.push(lib.inpile[i]); } } if(list.length){ var card=game.createCard(list.randomGet()); this.addJudge(card); this.$draw(card); if(!nodelay) game.delay(); } else{ this.getDebuff(6); } break; } } return this; }, dying:function(reason){ if(this.nodying||this.hp>0||this.isDying()) return; var next=game.createEvent('dying'); next.player=this; next.reason=reason; if(reason&&reason.source) next.source=reason.source; next.setContent('dying'); next.filterStop=function(){ if(this.player.hp>0||this.nodying){ delete this.filterStop; return true; } }; return next; }, die:function(reason){ var next=game.createEvent('die'); next.player=this; next.reason=reason; if(reason) next.source=reason.source; next.setContent('die'); return next; }, revive:function(hp,log){ if(log!==false) game.log(this,'复活'); if(this.maxHp<1) this.maxHp=1; if(hp) this.hp=hp; else{ this.hp=1; } game.addVideo('revive',this); this.classList.remove('dead'); this.removeAttribute('style'); this.node.avatar.style.transform=''; this.node.avatar2.style.transform=''; this.node.hp.show(); this.node.equips.show(); this.node.count.show(); this.update(); var player; player=this.previousSeat; while(player.isDead()) player=player.previousSeat; player.next=this; this.previous=player; player=this.nextSeat; while(player.isDead()) player=player.nextSeat; player.previous=this; this.next=player; game.players.add(this); game.dead.remove(this); if(this==game.me){ if(ui.auto) ui.auto.show(); if(ui.wuxie) ui.wuxie.show(); if(ui.revive){ ui.revive.close(); delete ui.revive; } if(ui.exit){ ui.exit.close(); delete ui.exit; } if(ui.swap){ ui.swap.close(); delete ui.swap; } if(ui.restart){ ui.restart.close(); delete ui.restart; } if(ui.continue_game){ ui.continue_game.close(); delete ui.continue_game; } } }, isMad:function(){ return this.hasSkill('mad'); }, goMad:function(end){ if(end){ this.addTempSkill('mad',end); } else{ this.addSkill('mad'); } game.log(this,'进入混乱状态'); }, unMad:function(){ this.removeSkill('mad'); }, tempHide:function(){ this.addTempSkill('qianxing',{player:'phaseBegin'}); }, addExpose:function(num){ if(typeof this.ai.shown=='number'&&!this.identityShown&&this.ai.shown<1){ this.ai.shown+=num; if(this.ai.shown>0.95){ this.ai.shown=0.95; } } return this; }, equip:function(card,draw){ var next=game.createEvent('equip'); next.card=card; next.player=this; if(draw){ next.draw=true; } next.setContent(lib.element.content.equip); if(get.is.object(next.card)&&next.card.cards) next.card=next.card.cards[0]; next.cards=[next.card]; next.getd=function(player,key,position){ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); }); return cards; }; next.getl=function(player){ const that=this; const map={ player:player, hs:[], es:[], js:[], ss:[], xs:[], cards:[], cards2:[], gaintag_map:{}, }; player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); map.js.addArray(evt.js); map.ss.addArray(evt.ss); map.xs.addArray(evt.xs); map.cards.addArray(evt.cards); map.cards2.addArray(evt.cards2); for(let key in evt.gaintag_map){ if(!map.gaintag_map[key]) map.gaintag_map[key]=[]; map.gaintag_map[key].addArray(evt.gaintag_map[key]); } } }); return map; }; return next; }, addJudge:function(card,cards){ var next=game.createEvent('addJudge'); if(get.itemtype(card)=='card'){ next.card=card; next.cards=[card]; } else{ next.cards=cards; if(get.itemtype(next.cards)=='card') next.cards=[next.cards]; if(typeof card=='string'){ card={name:card}; } next.card=get.autoViewAs(card,next.cards) } next.player=this; next.setContent('addJudge'); next.getd=function(player,key,position){ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); }); return cards; }; next.getl=function(player){ const that=this; const map={ player:player, hs:[], es:[], js:[], ss:[], xs:[], cards:[], cards2:[], gaintag_map:{}, }; player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); map.js.addArray(evt.js); map.ss.addArray(evt.ss); map.xs.addArray(evt.xs); map.cards.addArray(evt.cards); map.cards2.addArray(evt.cards2); for(let key in evt.gaintag_map){ if(!map.gaintag_map[key]) map.gaintag_map[key]=[]; map.gaintag_map[key].addArray(evt.gaintag_map[key]); } } }); return map; }; return next; }, canAddJudge:function(card){ if(this.isDisabledJudge()) return false; var name; if(typeof card=='string'){ name=card; } else{ name=card.viewAs||card.name; } if(!name) return false; if(this.hasJudge(name)) return false; if(this.isOut()) return false; var mod=game.checkMod(card,this,this,'unchanged','targetEnabled',this); if(mod!='unchanged') return mod; return true; }, addJudgeNext:function(card,unlimited){ if(!card.expired){ let target=this.next; const name=card.viewAs||card.name; const cards=(get.itemtype(card)=='card')?[card]:card.cards; if(get.itemtype(cards)!='cards') return; let bool=false; if(!unlimited&&cards.some(card=>{ const position=get.position(card,true); return position!='j'&&position!='o'; })){ game.log(card,'已被移出处理区,无法置入判定区'); return; } for(let iwhile=0;iwhile<20;iwhile++){ if(target.canAddJudge(card)){ bool=true;break; } target=target.next; } if(bool){ if(card.cards&&card.cards.length){ target.addJudge(name,card.cards[0]); } else if(card.name!=name){ target.addJudge(name,card); } else{ target.addJudge(card); } } } else{ card.expired=false; } }, judge:function(){ var next=game.createEvent('judge'); next.player=this; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='card'){ next.card=arguments[i]; } else if(typeof arguments[i]=='string'){ next.skill=arguments[i]; } else if(typeof arguments[i]=='function'){ next.judge=arguments[i]; } else if(typeof arguments[i]=='boolean'){ next.clearArena=arguments[i]; } else if(get.objtype(arguments[i])=='div'){ next.position=arguments[i]; } } if(next.card&&next.judge==undefined){ next.judge=get.judge(next.card); next.judge2=get.judge2(next.card); } if(next.judge==undefined) next.judge=function(){return 0}; if(next.position==undefined) next.position=ui.discardPile; if(next.card) next.cardname=next.card.viewAs||next.card.name; var str=''; if(next.card) str=get.translation(next.card.viewAs||next.card.name); else if(next.skill) str=get.translation(next.skill); else str=get.translation(_status.event.name); next.judgestr=str; next.setContent('judge'); return next; }, turnOver:function(bool){ if(typeof bool=='boolean'){ if(bool){ if(this.isTurnedOver()) return; } else{ if(!this.isTurnedOver()) return; } } var next=game.createEvent('turnOver'); next.player=this; next.includeOut=true; next.setContent('turnOver'); return next; }, out:function(skill){ if(typeof skill=='number'){ this.outCount+=skill; } else if(typeof skill=='string'){ if(!this.outSkills){ this.outSkills=[]; } this.outSkills.add(skill); } else{ this.outCount++; } if(!this.classList.contains('out')){ this.classList.add('out'); game.log(this,'离开游戏'); } if(!game.countPlayer()){ game.over(); } }, in:function(skill){ if(this.isOut()){ if(typeof skill=='string'){ if(this.outSkills){ this.outSkills.remove(skill); if(!this.outSkills.length){ delete this.outSkills; } } } else if(typeof skill=='number'){ this.outCount-=skill; } else{ if(skill===true){ delete this.outSkills; } this.outCount=0; } if(this.outCount<=0&&!this.outSkills){ this.outCount=0; this.classList.remove('out'); game.log(this,'进入游戏'); } } }, link:function(bool){ if(typeof bool=='boolean'){ if(bool){ if(this.isLinked()) return; } else{ if(!this.isLinked()) return; } } var next=game.createEvent('link'); next.player=this; next.setContent('link'); return next; }, skip:function(name){ this.skipList.add(name); }, wait:function(callback){ if(lib.node){ if(typeof callback=='function'){ callback._noname_waiting=true; lib.node.torespond[this.playerid]=callback; } else{ lib.node.torespond[this.playerid]='_noname_waiting'; } clearTimeout(lib.node.torespondtimeout[this.playerid]); if(this.ws&&!this.ws.closed){ var player=this; var time=parseInt(lib.configOL.choose_timeout)*1000; if(_status.event._global_timer||_status.event.getParent().skillHidden){ for(var i=0;i<game.players.length;i++){ game.players[i].showTimer(time); } player._hide_all_timer=true; } else if(!_status.event._global_waiting){ player.showTimer(time); } lib.node.torespondtimeout[this.playerid]=setTimeout(function(){ player.unwait('ai'); player.ws.ws.close(); },time+5000); } } }, unwait:function(result){ if(this._hide_all_timer){ delete this._hide_all_timer; for(var i=0;i<game.players.length;i++){ game.players[i].hideTimer(); } } else if(!_status.event._global_waiting){ this.hideTimer(); } clearTimeout(lib.node.torespondtimeout[this.playerid]); delete lib.node.torespondtimeout[this.playerid]; if(!lib.node.torespond.hasOwnProperty(this.playerid)){ return; } var noresume=false; var proceed=null; if(typeof lib.node.torespond[this.playerid]=='function'&&lib.node.torespond[this.playerid]._noname_waiting){ proceed=lib.node.torespond[this.playerid](result,this); if(proceed===false){ noresume=true; } } lib.node.torespond[this.playerid]=result; for(var i in lib.node.torespond){ if(lib.node.torespond[i]=='_noname_waiting'){ return; } else if(lib.node.torespond[i]&&lib.node.torespond[i]._noname_waiting){ return; } } _status.event.result=result; _status.event.resultOL=lib.node.torespond; lib.node.torespond={}; if(typeof proceed=='function') proceed(); else if(_status.paused&&!noresume) game.resume(); }, tempUnwait:function(result){ if(!lib.node.torespond.hasOwnProperty(this.playerid)){ return; } var proceed; if(typeof lib.node.torespond[this.playerid]=='function'&&lib.node.torespond[this.playerid]._noname_waiting){ proceed=lib.node.torespond[this.playerid](result,this); } if(typeof proceed=='function') proceed(); }, logSkill:function(name,targets,nature,logv){ if(get.itemtype(targets)=='player') targets=[targets]; var nopop=false; var popname=name; if(Array.isArray(name)){ popname=name[1]; name=name[0]; } var checkShow=this.checkShow(name); if(lib.translate[name]){ this.trySkillAnimate(name,popname,checkShow); if(Array.isArray(targets)&&targets.length){ var str; if(targets[0]==this){ str='#b自己'; if(targets.length>1){ str+='、'; str+=get.translation(targets.slice(1)); } } else str=targets; game.log(this,'对',str,'发动了','【'+get.skillTranslation(name,this)+'】'); } else{ game.log(this,'发动了','【'+get.skillTranslation(name,this)+'】'); } } if(nature!=false){ if(nature===undefined){ nature='green'; } this.line(targets,nature); } var info=lib.skill[name]; if(info&&info.ai&&info.ai.expose!=undefined&& this.logAi&&(!targets||targets.length!=1||targets[0]!=this)){ this.logAi(lib.skill[name].ai.expose); } if(info&&info.round){ var roundname=name+'_roundcount'; this.storage[roundname]=game.roundNumber; this.syncStorage(roundname); this.markSkill(roundname); } game.trySkillAudio(name,this,true); if(game.chess){ this.chessFocus(); } if(logv===true){ game.logv(this,name,targets,null,true); } else if(info&&info.logv!==false){ game.logv(this,name,targets); } if(info){ var player=this; 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.contains(info.sourceSkill)){ logInfo.type='global'; } else if(players.contains(info.sourceSkill)){ logInfo.type='player'; } else if(equips.contains(info.sourceSkill)){ logInfo.type='equip'; } } else{ if(global.contains(name)){ logInfo.sourceSkill=name; logInfo.type='global'; } else if(players.contains(name)){ logInfo.sourceSkill=name; logInfo.type='player'; } else if(equips.contains(name)){ logInfo.sourceSkill=name; logInfo.type='equip'; } else{ var bool=false; for(var i of players){ var expand=[i]; game.expandSkills(expand); if(expand.contains(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.contains(name)){ logInfo.sourceSkill=i; logInfo.type='equip'; break; } } } } } var next=game.createEvent('logSkill',false),evt=_status.event; next.player=player; next.forceDie=true; next.includeOut=true; evt.next.remove(next); if(evt.logSkill) evt=evt.getParent(); for(var i in logInfo){ if(i=='event') next.log_event=logInfo[i]; else next[i]=logInfo[i]; } evt.after.push(next); next.setContent('emptyEvent'); player.getHistory('useSkill').push(logInfo); //尽可能别往这写插入结算 //不能用来终止技能发动!!! var next2=game.createEvent('logSkillBegin',false); next2.player=player; next2.forceDie=true; next2.includeOut=true; for(var i in logInfo){ if(i=='event') next2.log_event=logInfo[i]; else next2[i]=logInfo[i]; } next2.setContent('emptyEvent'); } if(this._hookTrigger){ for(var i=0;i<this._hookTrigger.length;i++){ var info=lib.skill[this._hookTrigger[i]].hookTrigger; if(info&&info.log){ info.log(this,name,targets); } } } }, unprompt:function(){ if(this.node.prompt){ this.node.prompt.delete(); delete this.node.prompt; } }, prompt:function(str,nature){ var node; if(this.node.prompt){ node=this.node.prompt; node.innerHTML=''; node.className='damage normal-font damageadded'; } else{ node=ui.create.div('.damage.normal-font',this); this.node.prompt=node; ui.refresh(node); node.classList.add('damageadded'); } node.innerHTML=str; node.dataset.nature=nature||'soil'; }, prompt_old:function(name2,className){ var node; if(this.node.prompt){ node=this.node.prompt; node.innerHTML=''; node.className='popup'; } else{ node=ui.create.div('.popup',this.parentNode); this.node.prompt=node; } node.dataset.position=this.dataset.position; if(this.dataset.position==0||parseInt(this.dataset.position)==parseInt(ui.arena.dataset.number)/2|| typeof name2=='number'||this.classList.contains('minskin')){ node.innerHTML=name2; } else{ for(var i=0;i<name2.length;i++){ node.innerHTML+=name2[i]+'<br/>'; } } if(className){ node.classList.add(className); } }, popup:function(name,className,nobroadcast){ var name2=get.translation(name); if(!name2) return; this.$damagepop(name2,className||'water',true,nobroadcast); }, popup_old:function(name,className){ var name2=get.translation(name); var node=ui.create.div('.popup',this.parentNode); if(!name2){ node.remove(); return node; } game.addVideo('popup',this,[name,className]); node.dataset.position=this.dataset.position; if(this.dataset.position==0||parseInt(this.dataset.position)==parseInt(ui.arena.dataset.number)/2|| typeof name2=='number'||this.classList.contains('minskin')){ node.innerHTML=name2; } else{ for(var i=0;i<name2.length;i++){ node.innerHTML+=name2[i]+'<br/>'; } } if(className){ node.classList.add(className); } this.popups.push(node); if(this.popups.length>1){ node.hide(); } else{ var that=this; setTimeout(function(){that._popup();},1000); } return node; }, _popup:function(){ if(this.popups.length){ this.popups.shift().delete(); if(this.popups.length){ this.popups[0].show(); var that=this; setTimeout(function(){that._popup();},1000); } } }, showTimer:function(time){ if(!time&&lib.configOL){ time=parseInt(lib.configOL.choose_timeout)*1000; } if(_status.connectMode&&!game.online){ game.broadcast(function(player,time){ player.showTimer(time); },this,time); } if(this==game.me){ return; } if(this.node.timer){ this.node.timer.remove(); } var timer=ui.create.div('.timerbar',this); this.node.timer=timer; ui.create.div(this.node.timer); var bar=ui.create.div(this.node.timer); ui.refresh(bar); bar.style.transitionDuration=(time/1000)+'s'; bar.style.transform='scale(0,1)'; }, hideTimer:function(){ if(_status.connectMode&&!game.online&&this.playerid){ game.broadcast(function(player){ player.hideTimer(); },this); } if(this.node.timer){ this.node.timer.delete(); delete this.node.timer; } }, markAuto:function(name,info){ if(typeof info!='undefined'){ if(!Array.isArray(this.storage[name])) this.storage[name]=[]; if(Array.isArray(info)){ this.storage[name].addArray(info); } else this.storage[name].add(info); this.markSkill(name); } else{ var storage=this.storage[name]; if(Array.isArray(storage)){ this[storage.length>0?'markSkill':'unmarkSkill'](name); } else if(typeof storage=='number'){ this[storage>0?'markSkill':'unmarkSkill'](name); } } }, unmarkAuto:function(name,info){ var storage=this.storage[name] if(Array.isArray(info)&&Array.isArray(storage)){ storage.removeArray(info.slice(0)); this.markAuto(name); } }, getExpansions:function(tag){ return this.getCards('x',(card)=>card.hasGaintag(tag)); }, countExpansions:function(tag){ return this.getExpansions(tag).length; }, hasExpansions:function(tag){ return this.countExpansions(tag)>0; }, setStorage:function(name,value,mark){ this.storage[name]=value; if(mark) this.markAuto(name); return value; }, getStorage:function(name){ return this.storage[name]||[]; }, hasStorage:function(name,value){ if(!(name in this.storage)) return false; if(typeof value=="undefined") return true; const storage=this.storage[name]; if(storage===value) return true; return Array.isArray(storage) && storage.includes(value); }, hasStorageAny:function(name,values){ const storage=this.storage[name]; if(!Array.isArray(values)) values=Array.from(arguments).slice(1); if(!storage) return false; if (!Array.isArray(storage)) return values.contains(storage); return values.some(item => storage.contains(item)); }, hasStorageAll:function(name,values){ const storage=this.storage[name]; if(!Array.isArray(values)) values=Array.from(arguments).slice(1); if(!storage) return false; if (!Array.isArray(storage)) return false; return values.every(item => storage.contains(item)); }, initStorage:function(name,value,mark){ return this.hasStorage(name)?this.getStorage(name):this.setStorage(name,value,mark); }, updateStorage:function(name,operation,mark){ return this.setStorage(name,operation(this.getStorage(name)),mark); }, updateStorageAsync:function(name,operation,mark){ return Promise.resolve(this.getStorage(name)) .then(value=>operation(value)) .then(value=>this.setStorage(name,value,mark)); }, removeStorage:function(name,mark){ if(!this.hasStorage(name)) return false; delete this.storage[name] if(mark){ this.unmarkSkill(name); } return true; }, markSkill:function(name,info,card,nobroadcast){ if(info===true){ this.syncStorage(name); info=null; } if(get.itemtype(card)=='card'){ game.addVideo('markSkill',this,[name,get.cardInfo(card)]); } else{ game.addVideo('markSkill',this,[name]); } const func=function(storage,player,name,info,card){ player.storage[name]=storage; if(!info){ if(player.marks[name]){ player.updateMarks(); return; } if(lib.skill[name]){ info=lib.skill[name].intro; } if(!info){ return; } } if(player.marks[name]){ player.marks[name].info=info; } else{ if(card){ player.marks[name]=player.mark(card,info,name); } else{ player.marks[name]=player.mark(name,info); } } player.updateMarks(); }; func(this.storage[name],this,name,info,card); if(!nobroadcast) game.broadcast(func,this.storage[name],this,name,info,card); return this; }, unmarkSkill:function(name,nobroadcast){ game.addVideo('unmarkSkill',this,name); if(!nobroadcast) game.broadcast(function(player,name){ if(player.marks[name]){ player.marks[name].delete(); player.marks[name].style.transform+=' scale(0.2)'; delete player.marks[name]; ui.updatem(player); } },this,name); if(this.marks[name]){ this.marks[name].delete(); this.marks[name].style.transform+=' scale(0.2)'; delete this.marks[name]; ui.updatem(this); var info=lib.skill[name]; if(!game.online&&info&&info.intro&&info.intro.onunmark){ if(info.intro.onunmark=='throw'){ if(get.itemtype(this.storage[name])=='cards'){ this.$throw(this.storage[name],1000); game.cardsDiscard(this.storage[name]); game.log(this.storage[name],'进入了弃牌堆'); this.storage[name].length=0; } } else if(typeof info.intro.onunmark=='function'){ info.intro.onunmark(this.storage[name],this); } else delete this.storage[name]; } } return this; }, markSkillCharacter:function(id,target,name,content,nobroadcast){ if(typeof target=='object'){ target=target.name; } const func=function(player,target,name,content,id){ if(player.marks[id]){ player.marks[id].name=name+'_charactermark'; player.marks[id]._name=target; player.marks[id].info={ name:name, content:content, id:id }; player.marks[id].setBackground(target,'character'); game.addVideo('changeMarkCharacter',player,{ id:id, name:name, content:content, target:target }); } else{ player.marks[id]=player.markCharacter(target,{ name:name, content:content, id:id }); player.marks[id]._name=target; game.addVideo('markCharacter',player,{ name:name, content:content, id:id, target:target }); } } func(this,target,name,content,id); if(!nobroadcast) game.broadcast(func,this,target,name,content,id); return this; }, markCharacter:function(name,info,learn,learn2){ if(typeof name=='object'){ name=name.name; } var node; if(name.startsWith('unknown')){ node=ui.create.div('.card.mark.drawinghidden'); ui.create.div('.background.skillmark',node).innerHTML=get.translation(name)[0]; } else{ if(!lib.character[name]) return; node=ui.create.div('.card.mark.drawinghidden').setBackground(name,'character'); } this.node.marks.insertBefore(node,this.node.marks.childNodes[1]); node.name=name+'_charactermark'; if(!info){ info={}; } if(!info.name){ info.name=get.translation(name); } if(!info.content){ info.content=get.skillintro(name,learn,learn2) } node.info=info; node.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.card); if(!lib.config.touchscreen){ if(lib.config.hover_all){ lib.setHover(node,ui.click.hoverplayer); } if(lib.config.right_info){ node.oncontextmenu=ui.click.rightplayer; } } ui.updatem(this); return node; }, mark:function(name,info,skill){ if(get.itemtype(name)=='cards'){ var marks=[]; for(var i=0;i<name.length;i++){ marks.push(this.mark(name[i],info)); } return marks; } else{ var node; if(get.itemtype(name)=='card'){ node=name.copy('mark'); node.classList.add('drawinghidden'); this.node.marks.insertBefore(node,this.node.marks.childNodes[1]); node.suit=name.suit; node.number=name.number; // if(name.name&&lib.card[name.name]&&lib.card[name.name].markimage){ // node.node.image.style.left=lib.card[name.name].markimage; // } if(name.classList.contains('fullborder')){ node.classList.add('fakejudge'); node.classList.add('fakemark'); (node.querySelector('.background')||ui.create.div('.background',node)).innerHTML=lib.translate[name.name+'_bg']||get.translation(name.name)[0]; } name=name.name; } else{ node=ui.create.div('.card.mark.drawinghidden'); this.node.marks.insertBefore(node,this.node.marks.childNodes[1]); if(lib.skill[name]&&lib.skill[name].markimage){ node.setBackgroundImage(lib.skill[name].markimage); node.style['box-shadow']='none'; node.style['background-size']='contain'; } else if(lib.skill[name]&&lib.skill[name].markimage2){ let img=ui.create.div('.background.skillmark',node); img.setBackgroundImage(lib.skill[name].markimage2); img.style['background-size']='contain'; } else{ var str=lib.translate[name+'_bg']; if(!str||str[0]=='+'||str[0]=='-'){ str=get.translation(name)[0]; } ui.create.div('.background.skillmark',node).innerHTML=str; } } node.name=name; node.skill=skill||name; if(typeof info=='object'){ node.info=info; } else if(typeof info=='string'){ node.markidentifer=info; } node.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.card); if(!lib.config.touchscreen){ if(lib.config.hover_all){ lib.setHover(node,ui.click.hoverplayer); } if(lib.config.right_info){ node.oncontextmenu=ui.click.rightplayer; } } this.updateMarks(); ui.updatem(this); return node; } }, unmark:function(name,info){ game.addVideo('unmarkname',this,name); if(get.itemtype(name)=='card'){ this.unmark(name.name,info); } else if(get.itemtype(name)=='cards'){ for(var i=0;i<name.length;i++){ this.unmark(name[i].name,info); } } else{ for(var i=0;i<this.node.marks.childNodes.length;i++){ if(this.node.marks.childNodes[i].name==name&& (!info||this.node.marks.childNodes[i].markidentifer==info)){ this.node.marks.childNodes[i].delete(); this.node.marks.childNodes[i].style.transform+=' scale(0.2)'; ui.updatem(this); return; } } } }, addLink:function(){ if(get.is.linked2(this)){ this.classList.add('linked2'); } else{ this.classList.add('linked'); } }, removeLink:function(){ if(get.is.linked2(this)){ this.classList.remove('linked2'); } else{ this.classList.remove('linked'); } }, canUse:function(card,target,distance,includecard){ if(typeof card=='string') card={name:card,isCard:true}; var info=get.info(card); if(info.multicheck&&!info.multicheck(card,this)) return false; if(!lib.filter.cardEnabled(card,this)) return false; if(includecard&&!lib.filter.cardUsable(card,this)) return false; if(distance!==false&&!lib.filter.targetInRange(card,this,target)) return false; return lib.filter[includecard?'targetEnabledx':'targetEnabled'](card,this,target); }, hasUseTarget:function(card,distance,includecard){ var player=this; return game.hasPlayer(function(current){ return player.canUse(card,current,distance,includecard); }); }, hasValueTarget:function(){ return this.getUseValue.apply(this,arguments)>0; }, getUseValue:function(card,distance,includecard){ if(typeof(card)=='string'){ card={name:card,isCard:true}; } var player=this; var targets=game.filterPlayer(); var value=[]; var min=0; var info=get.info(card); if(!info||info.notarget) return 0; var range; var select=get.copy(info.selectTarget); if(select==undefined){ if(info.filterTarget==undefined) return true; range=[1,1]; } else if(typeof select=='number') range=[select,select]; else if(get.itemtype(select)=='select') range=select; else if(typeof select=='function') range=select(card,player); if(info.singleCard) range=[1,1]; game.checkMod(card,player,range,'selectTarget',player); if(!range) return 0; for(var i=0;i<targets.length;i++){ if(player.canUse(card,targets[i],distance,includecard)){ var eff=get.effect(targets[i],card,player,player); value.push(eff); } } value.sort(function(a,b){ return b-a; }); for(var i=0;i<value.length;i++){ if(i==range[1]||range[1]!=-1&&value[i]<=0) break; min+=value[i]; } return min; }, addSubPlayer:function(cfg){ var skill='subplayer_'+cfg.name+'_'+get.id(); game.log(this,'获得了随从','#g'+get.translation(cfg.name)) cfg.hs=cfg.hs||[]; cfg.es=cfg.es||[]; cfg.skills=cfg.skills||[]; cfg.hp=cfg.hp||1; cfg.maxHp=cfg.maxHp||1; cfg.sex=cfg.sex||'male'; cfg.group=cfg.group||'qun'; cfg.skill=cfg.skill||_status.event.name; if(!cfg.source){ if(this.hasSkill(_status.event.name)&&this.name2&&lib.character[this.name2]&& lib.character[this.name2][3].contains(_status.event.name)){ cfg.source=this.name2; } else{ cfg.source=this.name; } } game.broadcastAll(function(player,skill,cfg){ lib.skill[skill]={ intro:{ content:cfg.intro||'' }, mark:'character', subplayer:cfg.skill, ai:{ subplayer:true } } lib.character[skill]=[cfg.sex,cfg.group,cfg.maxHp,cfg.skills,['character:'+cfg.name]]; lib.translate[skill]=cfg.caption||get.rawName(cfg.name); player.storage[skill]=cfg; },this,skill,cfg); game.addVideo('addSubPlayer',this,[skill,lib.skill[skill],lib.character[skill],lib.translate[skill],{name:cfg.name}]); this.addSkill(skill); return skill; }, removeSubPlayer:function(name){ if(this.hasSkill('subplayer')&&this.name==name){ this.exitSubPlayer(true); } else{ if(player.storage[name].onremove){ player.storage[name].onremove(player); } this.removeSkill(name); delete this.storage[name]; game.log(player,'牺牲了随从','#g'+name); _status.event.trigger('removeSubPlayer'); } }, callSubPlayer:function(){ if(this.hasSkill('subplayer')) return; var next=game.createEvent('callSubPlayer'); next.player=this; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='string'){ next.directresult=arguments[i]; } } next.setContent('callSubPlayer'); return next; }, toggleSubPlayer:function(){ if(!this.hasSkill('subplayer')) return; var next=game.createEvent('toggleSubPlayer'); next.player=this; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='string'){ next.directresult=arguments[i]; } } next.setContent('toggleSubPlayer'); return next; }, exitSubPlayer:function(remove){ if(!this.hasSkill('subplayer')) return; var next=game.createEvent('exitSubPlayer'); next.player=this; next.remove=remove; next.setContent('exitSubPlayer'); return next; }, getSubPlayers:function(tag){ var skills=this.getSkills(); var list=[]; for(var i=0;i<skills.length;i++){ var name=skills[i]; var info=lib.skill[name]; if(tag&&info.subplayer!=tag) continue; if(info.ai&&info.ai.subplayer&&this.storage[name]&&this.storage[name].name){ list.push(name); } } return list; }, addSkillTrigger:function(skill,hidden,triggeronly){ var info=lib.skill[skill]; if(!info) return; if(typeof info.group=='string'){ this.addSkillTrigger(info.group,hidden); } else if(Array.isArray(info.group)){ for(var i=0;i<info.group.length;i++){ this.addSkillTrigger(info.group[i],hidden); } } if(!triggeronly){ if(info.global&&(!hidden||info.globalSilent)){ if(typeof info.global=='string'){ game.addGlobalSkill(info.global,this); } else{ for(var j=0;j<info.global.length;j++){ game.addGlobalSkill(info.global[j],this); } } } if(this.initedSkills.contains(skill)) return this; this.initedSkills.push(skill); if(info.init&&!_status.video){ info.init(this,skill); } } if(info.trigger&&this.playerid){ var playerid=this.playerid; var setTrigger=function(i,evt){ if(i=='global'){ if(!lib.hook.globaltrigger[evt]){ lib.hook.globaltrigger[evt]={}; } if(!lib.hook.globaltrigger[evt][playerid]){ lib.hook.globaltrigger[evt][playerid]=[]; } lib.hook.globaltrigger[evt][playerid].add(skill); } else{ var name=playerid+'_'+i+'_'+evt; if(!lib.hook[name]){ lib.hook[name]=[]; } lib.hook[name].add(skill); } lib.hookmap[evt]=true; } for(var i in info.trigger){ if(typeof info.trigger[i]=='string'){ setTrigger(i,info.trigger[i]); } else if(Array.isArray(info.trigger[i])){ for(var j=0;j<info.trigger[i].length;j++){ setTrigger(i,info.trigger[i][j]); } } } } if(info.hookTrigger){ if(!this._hookTrigger){ this._hookTrigger=[]; } this._hookTrigger.add(skill); } if(_status.event&&_status.event.addTrigger) _status.event.addTrigger(skill,this); return this; }, addSkillLog:function(skill){ this.addSkill(skill); this.popup(skill); game.log(this,'获得了技能','#g【'+get.translation(skill)+'】'); }, addInvisibleSkill:function(skill){ if(Array.isArray(skill)){ _status.event.clearStepCache(); for(var i=0;i<skill.length;i++){ this.addInvisibleSkill(skill[i]); } } else{ if(this.invisibleSkills.contains(skill)) return; _status.event.clearStepCache(); var info=lib.skill[skill]; if(!info) return; this.invisibleSkills.add(skill); this.addSkillTrigger(skill); if(this.awakenedSkills.contains(skill)){ this.awakenSkill(skill); return; } } }, removeInvisibleSkill:function(skill){ if(!skill) return; if(Array.isArray(skill)){ for(var i=0;i<skill.length;i++){ this.removeSkill(skill[i]); } } else{ var info=lib.skill[skill]; if(info&&info.fixed&&arguments[1]!==true) return skill; game.broadcastAll(function(player,skill){ player.invisibleSkills.remove(skill); },this,skill); if(!player.hasSkill(skill,true)) player.removeSkill(skill); } return skill; }, addSkill:function(skill,checkConflict,nobroadcast,addToSkills){ if(Array.isArray(skill)){ _status.event.clearStepCache(); for(var i=0;i<skill.length;i++){ this.addSkill(skill[i]); } } else{ if(this.skills.contains(skill)) return; _status.event.clearStepCache(); var info=lib.skill[skill]; if(!info) return; if(!addToSkills){ this.skills.add(skill); if(!nobroadcast){ game.broadcast(function(player,skill){ player.skills.add(skill); },this,skill); } } this.addSkillTrigger(skill); if(this.awakenedSkills.contains(skill)){ this.awakenSkill(skill); return; } if(info.init2&&!_status.video){ info.init2(this,skill); } if(info.mark){ if(info.mark=='card'&& get.itemtype(this.storage[skill])=='card'){ this.markSkill(skill,null,this.storage[skill],nobroadcast); } else if(info.mark=='card'&& get.itemtype(this.storage[skill])=='cards'){ this.markSkill(skill,null,this.storage[skill][0],nobroadcast); } else if(info.mark=='image'){ this.markSkill(skill,null,ui.create.card(null,'noclick').init([null,null,skill]),nobroadcast); } else if(info.mark=='character'){ var intro=info.intro.content; if(typeof intro=='function'){ intro=intro(this.storage[skill],this); } else if(typeof intro=='string'){ intro=intro.replace(/#/g,this.storage[skill]); intro=intro.replace(/&/g,get.cnNumber(this.storage[skill])); intro=intro.replace(/\$/g,get.translation(this.storage[skill])); } var caption; if(typeof info.intro.name=='function'){ caption=info.intro.name(this.storage[skill],this); } else if(typeof info.intro.name=='string'){ caption=info.name; } else{ caption=get.translation(skill); } this.markSkillCharacter(skill,this.storage[skill],caption,intro,nobroadcast); } else{ this.markSkill(skill,null,null,nobroadcast); } } } if(checkConflict) this.checkConflict(); return skill; }, addAdditionalSkill:function(skill,skills,keep){ if(this.additionalSkills[skill]){ if(keep){ if(typeof this.additionalSkills[skill]=='string'){ this.additionalSkills[skill]=[this.additionalSkills[skill]]; } } else{ this.removeAdditionalSkill(skill); this.additionalSkills[skill]=[]; } } else{ this.additionalSkills[skill]=[]; } if(typeof skills=='string'){ skills=[skills]; } for(var i=0;i<skills.length;i++){ this.addSkill(skills[i],null,true,true); //this.skills.remove(skills[i]); this.additionalSkills[skill].push(skills[i]); } this.checkConflict(); _status.event.clearStepCache(); return this; }, removeAdditionalSkill:function(skill,target){ if(this.additionalSkills[skill]){ var additionalSkills=this.additionalSkills[skill]; if(Array.isArray(additionalSkills)&&typeof target=='string'){ if(additionalSkills.contains(target)){ additionalSkills.remove(target); if(!this.skills.contains(target)&&!this.tempSkills[target]) this.removeSkill(target); } } else{ delete this.additionalSkills[skill]; if(typeof additionalSkills=='string'){ if(!this.skills.contains(additionalSkills)&&!this.tempSkills[additionalSkills]) this.removeSkill(additionalSkills); } else if(Array.isArray(additionalSkills)){ for(var i=0;i<additionalSkills.length;i++){ if(!this.skills.contains(additionalSkills[i])&&!this.tempSkills[additionalSkills[i]]) this.removeSkill(additionalSkills[i]); } } } } _status.event.clearStepCache(); return this; }, awakenSkill:function(skill,nounmark){ if(!nounmark) this.unmarkSkill(skill); this.disableSkill(skill+'_awake',skill); this.awakenedSkills.add(skill); if(this.storage[skill]===false) this.storage[skill]=true; _status.event.clearStepCache(); return this; }, restoreSkill:function(skill,nomark){ if(this.storage[skill]===true) this.storage[skill]=false; this.awakenedSkills.remove(skill); this.enableSkill(skill+'_awake',skill); if(!nomark) this.markSkill(skill); _status.event.clearStepCache(); return this; }, disableSkill:function(skill,skills){ if(typeof skills=='string'){ if(!this.disabledSkills[skills]){ this.disabledSkills[skills]=[]; var info=get.info(skills); if(info.ondisable&&info.onremove){ if(typeof info.onremove=='function'){ info.onremove(this,skill); } else if(typeof info.onremove=='string'){ if(info.onremove=='storage'){ delete this.storage[skill]; } else{ var cards=this.storage[skill]; if(get.itemtype(cards)=='card'){ cards=[cards]; } if(get.itemtype(cards)=='cards'){ if(this.onremove=='discard'){ this.$throw(cards); } if(this.onremove=='discard'||this.onremove=='lose'){ game.cardsDiscard(cards); delete this.storage[skill]; } } } } else if(Array.isArray(info.onremove)){ for(var i=0;i<info.onremove.length;i++){ delete this.storage[info.onremove[i]]; } } else if(info.onremove===true){ delete this.storage[skill]; } } } this.disabledSkills[skills].add(skill); var group=lib.skill[skills].group; if(typeof group=='string'||Array.isArray(group)){ this.disableSkill(skill,group); } } else if(Array.isArray(skills)){ for(var i=0;i<skills.length;i++){ this.disableSkill(skill,skills[i]); } } _status.event.clearStepCache(); return this; }, enableSkill:function(skill){ for(var i in this.disabledSkills){ this.disabledSkills[i].remove(skill); if(this.disabledSkills[i].length==0){ delete this.disabledSkills[i]; } } _status.event.clearStepCache(); return this; }, checkMarks:function(){ var skills=this.getSkills(); game.expandSkills(skills); for(var i in this.marks){ if(!skills.contains(i)&&!this.marks[i].info.fixed){ this.unmarkSkill(i); } } return this; }, addEquipTrigger:function(card){ if(card){ var info=get.info(card); if(info.skills){ for(var j=0;j<info.skills.length;j++){ this.addSkillTrigger(info.skills[j]); } } } else{ var es=this.getCards('e'); for(var i=0;i<es.length;i++){ this.addEquipTrigger(es[i]); } } return this; }, removeEquipTrigger:function(card){ if(card){ var info=get.info(card); var skills=this.getSkills(null,false); if(info.skills){ for(var j=0;j<info.skills.length;j++){ if(skills.contains(info.skills[j])) continue; this.removeSkillTrigger(info.skills[j]); } } if(info.clearLose&&typeof info.onLose=='function'){ var next=game.createEvent('lose_'+card.name); next.setContent(info.onLose); next.player=this; next.card=card; } } else{ var es=this.getCards('e'); for(var i=0;i<es.length;i++){ this.removeEquipTrigger(es[i]); } } return this; }, removeSkillTrigger:function(skill,triggeronly){ var info=lib.skill[skill]; if(!info) return; if(typeof info.group=='string'){ this.removeSkillTrigger(info.group); } else if(Array.isArray(info.group)){ for(var i=0;i<info.group.length;i++){ this.removeSkillTrigger(info.group[i]); } } if(!triggeronly) this.initedSkills.remove(skill); if(info.trigger){ var playerid=this.playerid; var removeTrigger=function(i,evt){ if(i=='global'){ for(var j in lib.hook.globaltrigger){ if(lib.hook.globaltrigger[j][playerid]){ lib.hook.globaltrigger[j][playerid].remove(skill); if(lib.hook.globaltrigger[j][playerid].length==0){ delete lib.hook.globaltrigger[j][playerid]; } if(get.is.empty(lib.hook.globaltrigger[j])){ delete lib.hook.globaltrigger[j]; } } } } else{ var name=playerid+'_'+i+'_'+evt; if(lib.hook[name]){ lib.hook[name].remove(skill); if(lib.hook[name].length==0){ delete lib.hook[name]; } } } } for(var i in info.trigger){ if(typeof info.trigger[i]=='string'){ removeTrigger(i,info.trigger[i]); } else if(Array.isArray(info.trigger[i])){ for(var j=0;j<info.trigger[i].length;j++){ removeTrigger(i,info.trigger[i][j]); } } } } if(info.hookTrigger){ if(this._hookTrigger){ this._hookTrigger.remove(skill); if(!this._hookTrigger.length){ delete this._hookTrigger; } } } return this; }, removeSkill:function(skill){ if(!skill) return; if(Array.isArray(skill)){ for(var i=0;i<skill.length;i++){ this.removeSkill(skill[i]); } } else{ var info=lib.skill[skill]; if(info&&info.fixed&&arguments[1]!==true) return skill; this.unmarkSkill(skill); game.broadcastAll(function(player,skill){ player.skills.remove(skill); player.hiddenSkills.remove(skill); player.invisibleSkills.remove(skill); delete player.tempSkills[skill]; for(var i in player.additionalSkills){ player.additionalSkills[i].remove(skill); } },this,skill); this.checkConflict(skill); if(info){ if(info.onremove){ if(typeof info.onremove=='function'){ info.onremove(this,skill); } else if(typeof info.onremove=='string'){ if(info.onremove=='storage'){ delete this.storage[skill]; } else{ var cards=this.storage[skill]; if(get.itemtype(cards)=='card'){ cards=[cards]; } if(get.itemtype(cards)=='cards'){ if(this.onremove=='discard'){ this.$throw(cards); } if(this.onremove=='discard'||this.onremove=='lose'){ game.cardsDiscard(cards); delete this.storage[skill]; } } } } else if(Array.isArray(info.onremove)){ for(var i=0;i<info.onremove.length;i++){ delete this.storage[info.onremove[i]]; } } else if(info.onremove===true){ delete this.storage[skill]; } } this.removeSkillTrigger(skill); if(!info.keepSkill){ this.removeAdditionalSkill(skill); } } this.enableSkill(skill+'_awake'); } return skill; }, addTempSkill:function(skill,expire,checkConflict){ if(this.hasSkill(skill)&&this.tempSkills[skill]==undefined) return; this.addSkill(skill,checkConflict,true,true); if(!expire){ expire=['phaseAfter','phaseBefore']; } this.tempSkills[skill]=expire; if(typeof expire=='string'){ lib.hookmap[expire]=true; } else if(Array.isArray(expire)){ for(var i=0;i<expire.length;i++){ lib.hookmap[expire[i]]=true; } } else if(get.objtype(expire)=='object'){ var roles=['player','source','target']; for(var i=0;i<roles.length;i++){ if(typeof expire[roles[i]]=='string'){ lib.hookmap[expire[roles[i]]]=true; } else if(Array.isArray(expire[roles[i]])){ for(var j=0;j<expire[roles[i]].length;j++){ lib.hookmap[expire[roles[i]][j]]=true; } } } if(expire.global){ if(typeof expire.global=='string'){ lib.hookmap[expire.global]=true; } else if(Array.isArray(expire.global)){ for(var i=0;i<expire.global.length;i++){ lib.hookmap[expire.global[i]]=true; } } } } return skill; }, attitudeTo:function(target){ if(typeof get.attitude=='function') return get.attitude(this,target); return 0; }, clearSkills:function(all){ var list=[]; var exclude=[]; for(var i=0;i<arguments.length;i++){ exclude.push(arguments[i]); } for(i=0;i<this.skills.length;i++){ if(lib.skill[this.skills[i]].superCharlotte) continue; if(!all&&(lib.skill[this.skills[i]].temp||lib.skill[this.skills[i]].charlotte)) continue; if(!exclude.contains(this.skills[i])){ list.push(this.skills[i]); } } if(all){ for(var i in this.additionalSkills){ this.removeAdditionalSkill(i); } } this.removeSkill(list); this.checkConflict(); this.checkMarks(); return list; }, checkConflict:function(skill){ if(skill){ if(this.forbiddenSkills[skill]){ delete this.forbiddenSkills[skill]; } else{ for(var i in this.forbiddenSkills){ if(this.forbiddenSkills[i].remove(skill)){ if(!this.forbiddenSkills[i].length){ delete this.forbiddenSkills[i]; } } } } } else{ this.forbiddenSkills={}; var forbid=[]; var getName=function(arr){ var str=''; for(var i=0;i<arr.length;i++){ str+=arr[i]+'+'; } return str.slice(0,str.length-1); } var forbidlist=lib.config.forbid.concat(lib.config.customforbid); var skills=this.getSkills(); for(var i=0;i<forbidlist.length;i++){ if(lib.config.customforbid.contains(forbidlist[i])|| !lib.config.forbidlist.contains(getName(forbidlist[i]))){ for(var j=0;j<forbidlist[i].length;j++){ if(!skills.contains(forbidlist[i][j])) break; } if(j==forbidlist[i].length){ forbid.push(forbidlist[i]); } } } for(var i=0;i<forbid.length;i++){ if(forbid[i][1]||this.name2){ this.forbiddenSkills[forbid[i][0]]=this.forbiddenSkills[forbid[i][0]]||[]; if(forbid[i][1]){ this.forbiddenSkills[forbid[i][0]].add(forbid[i][1]); } } } } }, getHistory:function(key,filter,last){ if(!key) return this.actionHistory[this.actionHistory.length-1]; if(!filter) return this.actionHistory[this.actionHistory.length-1][key]; else{ const history=this.getHistory(key); if(last){ const lastIndex=history.indexOf(last); return history.filter((event,index)=>{ if(index>lastIndex) return false; return filter(event); }) } return history.filter(filter); } }, checkHistory:function(key,filter,last){ if(!key||!filter) return; else{ const history=this.getHistory(key); if(last){ const lastIndex=history.indexOf(last); history.forEach((event,index)=>{ if(index>lastIndex) return false; filter(event); }) } else{ history.forEach(filter); } } }, hasHistory:function(key,filter,last){ const history=this.getHistory(key); if(!filter||typeof filter!="function") filter=lib.filter.all; if(last){ const lastIndex=history.indexOf(last); return history.some((event,index)=>{ if(index>lastIndex) return false; return filter(event); }) } return history.some(filter); }, getLastHistory:function(key,filter,last){ let history=false; for(let i=this.actionHistory.length-1;i>=0;i--){ if(this.actionHistory[i].isMe){ history=this.actionHistory[i];break; } } if(!history) return null; if(!key) return history; if(!filter) return history[key]; else{ if(last){ const lastIndex=history.indexOf(last); return history.filter((event,index)=>{ if(index>lastIndex) return false; return filter(event); }) } return history.filter(filter); } }, checkAllHistory:function(key,filter,last){ if(!key||!filter) return; this.actionHistory.forEach((value)=>{ let history=value[key]; if(last&&history.includes(last)){ const lastIndex=history.indexOf(last); history.forEach((event,index)=>{ if(index>lastIndex) return false; return filter(event); }); } else{ history.forEach(filter); } }); }, getAllHistory:function(key,filter,last){ const history=[]; this.actionHistory.forEach((value)=>{ if(!key||!value[key]){ history.push(value); } else{ history.push(...value[key]); } }) if(filter){ if(last){ const lastIndex=history.indexOf(last); return history.filter((event,index)=>{ if(index>lastIndex) return false; return filter(event); }); } return history.filter(filter); } return history; }, hasAllHistory:function(key,filter,last){ return this.actionHistory.some((value)=>{ let history=value[key]; if(last&&history.includes(last)){ const lastIndex=history.indexOf(last); if(history.some(function(event,index){ if(index>lastIndex) return false; return filter(event); })) return true; } else{ if(history.some(filter)) return true; } return false; }) }, getLastUsed:function(num){ if(typeof num!='number') num=0; var history=this.getHistory('useCard'); if(history.length<=num) return null; return history[history.length-num-1]; }, getStat:function(key){ if(!key) return this.stat[this.stat.length-1]; return this.stat[this.stat.length-1][key]; }, getLastStat:function(key){ var stat=false; for(var i=this.stat.length-1;i>=0;i--){ if(this.stat[i].isMe){ stat=this.stat[i];break; } } if(!stat) return null if(!key) return stat; return stat[key]; }, queue:function(time){ if(time==false){ clearTimeout(this.queueTimeout); this.queueCount=0; return; } if(time==undefined) time=500; var player=this; player.queueCount++; this.queueTimeout=setTimeout(function(){ player.queueCount--; if(player.queueCount==0){ player.style.transform=''; player.node.avatar.style.transform=''; player.node.avatar2.style.transform=''; if(game.chess){ ui.placeChess(player,player.dataset.position); } if(player==game.me) ui.me.removeAttribute('style'); } },time) }, getCardUsable:function(card,pure){ var player=this; if(typeof card=='string'){ card={name:card}; } card=get.autoViewAs(card); var num=get.info(card).usable; if(typeof num=='function') num=num(card,player); num=game.checkMod(card,player,num,'cardUsable',player); if(typeof num!='number') return Infinity; if(!pure&&_status.currentPhase==player){ return num-player.countUsed(card); } return num; }, getAttackRange:function(raw){ const player=this; let range=0; if(raw){ range=game.checkMod(player,player,range,'globalFrom',player); range=game.checkMod(player,player,range,'attackFrom',player); const equips=player.getCards('e',function(card){ return !ui.selected.cards||!ui.selected.cards.contains(card); }); equips.forEach(card=>{ const info=get.info(card,false).distance; if(ininfo&&info.globalFrom){ range+=info.globalFrom; } }) return (player.getEquipRange()-range); } let base=game.checkMod(player,'unchanged','attackRangeBase',player); if(base!='unchanged'){ range=base; } else{ range=player.getEquipRange(); } range=game.checkMod(player,range,'attackRange',player); return range; }, getEquipRange:function(cards){ const player=this; if(!cards) cards=player.getCards('e',function(card){ return !ui.selected.cards||!ui.selected.cards.contains(card); }); const range=cards.reduce((range,card)=>{ let newRange=false; const info=get.info(card,false); if(info.distance){ //如果存在attackRange 则通过attackRange动态获取攻击范围 if(typeof info.distance.attackRange=='function'){ newRange=info.distance.attackRange(card,player); } //否则采用祖宗之法 else if(typeof info.distance.attackFrom=='number'){ newRange=(1-info.distance.attackFrom); } } let isN1=(typeof range=='number'); let isN2=(typeof newRange=='number'); if(isN1&&isN2) return Math.max(range,newRange); else return (isN1?range:newRange); },false); return (typeof range=='number')?range:1; }, getGlobalFrom:function(){ var player=this; var range=0; range=game.checkMod(player,player,range,'globalFrom',player); var equips=player.getCards('e',function(card){ return !ui.selected.cards||!ui.selected.cards.contains(card); }); for(var i=0;i<equips.length;i++){ var info=get.info(equips[i]).distance; if(!info) continue; if(info.globalFrom){ range+=info.globalFrom; } } return (-range); }, getGlobalTo:function(){ var player=this; var range=0; range=game.checkMod(player,player,range,'globalTo',player); var equips=player.getCards('e',function(card){ return !ui.selected.cards||!ui.selected.cards.contains(card); }); for(var i=0;i<equips.length;i++){ var info=get.info(equips[i]).distance; if(!info) continue; if(info.globalTo){ range+=info.globalTo; } } return (range); }, getHandcardLimit:function(){ var num=Math.max(this.hp,0); num=game.checkMod(this,num,'maxHandcardBase',this); num=game.checkMod(this,num,'maxHandcard',this); num=game.checkMod(this,num,'maxHandcardFinal',this); return Math.max(0,num); }, getEnemies:function(func){ var player=this; var targets; var mode=get.mode(); if(mode=='identity'){ if(_status.mode=='purple'){ switch(player.identity){ case 'bZhu':case 'bZhong':case 'rNei':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return ['rZhu','rZhong','bNei'].contains(target.identity); });break; case 'rZhu':case 'rZhong':case 'bNei':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return ['bZhu','bZhong','rNei'].contains(target.identity); });break; case 'rYe':case 'bYe':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return !['rYe','bYe'].contains(target.identity); });break; } } else{ var num=get.population('fan'); switch(player.identity){ case 'zhu':case 'zhong':case 'mingzhong':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; if(num>=3) return target.identity=='fan'; return target.identity=='nei'||target.identity=='fan'; });break; case 'nei':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; if(num>=3) return target.identity=='fan'; if(game.players.length==2) return target!=player; return target.identity=='zhong'||target.identity=='mingzhong'||target.identity=='fan'; });break; case 'fan':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return target.identity!='fan'; });break; } } } else if(mode=='guozhan'){ if(player.identity=='ye'){ targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return true; }); } else{ var group=lib.character[player.name1][1]; targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return target.identity=='ye'||lib.character[target.name1][1]!=group; }); } } else if(mode=='doudizhu'){ targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return target.identity!=player.identity; }); } else{ targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return target.side!=player.side; }); } targets.remove(player); return targets; }, getFriends:function(func){ var player=this; var targets; var mode=get.mode(); var self=false; if(func===true){ func=null; self=true; } if(mode=='identity'){ if(_status.mode=='purple'){ switch(player.identity){ case 'rZhu':case 'rZhong':case 'bNei':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return ['rZhu','rZhong','bNei'].contains(target.identity); });break; case 'bZhu':case 'bZhong':case 'rNei':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return ['bZhu','bZhong','rNei'].contains(target.identity); });break; case 'rYe':case 'bYe':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return ['rYe','bYe'].contains(target.identity); });break; } } else{ switch(player.identity){ case 'zhu':case 'zhong':case 'mingzhong':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return ['zhu','zhong','mingzhong'].contains(target.identity); });break; case 'nei':targets=[];break; case 'fan':targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return target.identity=='fan'; });break; } } } else if(mode=='guozhan'){ if(player.identity=='ye'){ targets=[]; } else{ var group=lib.character[player.name1][1]; targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return target.identity!='ye'&&lib.character[target.name1][1]==group; }); } } else if(mode=='doudizhu'){ targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return target.identity==player.identity; }); } else{ targets=game.filterPlayer(function(target){ if(func&&!func(target)) return false; return target.side==player.side; }); } if(self){ targets.add(player); } else{ targets.remove(player); } return targets; }, isEnemyOf:function(){ return !this.isFriendOf.apply(this,arguments); }, isFriendOf:function(player){ if(get.mode()=='guozhan'){ if(this==player) return true; if(this.getStorage('yexinjia_friend').includes(player)||player.getStorage('yexinjia_friend').includes(this)) return true; if(this.identity=='unknown'||this.identity=='ye') return false; if(player.identity=='unknown'||player.identity=='ye') return false; return this.identity==player.identity; } if(get.mode()=='doudizhu'){ return this.identity==player.identity; } if(this.side!=undefined&&typeof player.side=='boolean'){ return this.side==player.side; } return this==player; }, isFriendsOf:function(player){ return player.getFriends(true).contains(this); }, isEnemiesOf:function(player){ return player.getEnemies().contains(this); }, isAlive:function(){ return this.classList.contains('dead')==false; }, isDead:function(){ return this.classList.contains('dead'); }, isDying:function(){ return _status.dying.contains(this)&&this.hp<=0&&this.isAlive(); }, isDamaged:function(){ return this.hp<this.maxHp&&!this.storage.nohp; }, isHealthy:function(){ return this.hp>=this.maxHp||this.storage.nohp; }, isMaxHp:function(only,raw){ return game.players.every(value=>{ if(value.isOut()||value==this) return true; return only?value.getHp(raw)<this.getHp(raw):value.getHp(raw)<=this.getHp(raw); }); }, isMinHp:function(only,raw){ return game.players.every(value=>{ if(value.isOut()||value==this) return true; return only?value.getHp(raw)>this.getHp(raw):value.getHp(raw)>=this.getHp(raw); }); }, isMaxCard:function(only){ const numberOfCards=this.countCards('he'); return game.players.every(value=>{ if(value.isOut()||value==this) return true; return only?value.countCards('he')<numberOfCards:value.countCards('he')<=numberOfCards; }); }, isMinCard:function(only){ const numberOfCards=this.countCards('he'); return game.players.every(value=>{ if(value.isOut()||value==this) return true; return only?value.countCards('he')>numberOfCards:value.countCards('he')>=numberOfCards; }); }, isMaxHandcard:function(only){ const numberOfHandCards=this.countCards('h'); return game.players.every(value=>{ if(value.isOut()||value==this) return true; return only?value.countCards('h')<numberOfHandCards:value.countCards('h')<=numberOfHandCards; }); }, isMinHandcard:function(only){ const numberOfHandCards=this.countCards('h'); return game.players.every(value=>{ if(value.isOut()||value==this) return true; return only?value.countCards('h')>numberOfHandCards:value.countCards('h')>=numberOfHandCards; }); }, isMaxEquip:function(only){ const numberOfEquipAreaCards=this.countCards('e'); return game.players.every(value=>{ if(value.isOut()||value==this) return true; return only?value.countCards('e')<numberOfEquipAreaCards:value.countCards('e')<=numberOfEquipAreaCards; }); }, isMinEquip:function(only){ const numberOfEquipAreaCards=this.countCards('e'); return game.players.every(value=>{ if(value.isOut()||value==this) return true; return only?value.countCards('e')>numberOfEquipAreaCards:value.countCards('e')>=numberOfEquipAreaCards; }); }, isLinked:function(){ if(get.is.linked2(this)){ return this.classList.contains('linked2'); } return this.classList.contains('linked'); }, isTurnedOver:function(){ return this.classList.contains('turnedover'); }, isOut:function(){ return this.classList.contains('out'); }, isMin:function(distance){ if(distance&&lib.config.mode!='stone') return false; if(this.forcemin) return true; return this.classList.contains('minskin')&&!game.chess; }, isIn:function(){ return this.classList.contains('dead')==false&&this.classList.contains('out')==false&&!this.removed; }, isUnseen:function(num){ switch(num){ case 0:return this.classList.contains('unseen'); case 1:return this.classList.contains('unseen2'); case 2:return this.classList.contains('unseen')||this.classList.contains('unseen2'); default:return this.classList.contains('unseen')&&(!this.name2||this.classList.contains('unseen2')); } }, isUnderControl:function(self,me){ me=(me||game.me); var that=this._trueMe||this; if(that.isMad()||game.notMe) return false; if(this===me){ if(self) return true; return false; } if(that===me||this==me._trueMe) return true; if(_status.connectMode) return false; if(lib.config.mode=='versus'){ if(_status.mode=='three') return this.side==me.side; if(_status.mode=='standard') return lib.storage.single_control&&this.side==me.side; if(_status.mode=='four') return get.config('four_phaseswap')&&this.side==me.side; if(_status.mode=='two') return get.config('two_phaseswap')&&this.side==me.side; return false; } else if(lib.config.mode=='boss'){ if(me.side) return false; return this.side==me.side&&get.config('single_control'); } else if(game.chess){ if(lib.config.mode=='chess'){ if(_status.mode=='combat'&&!get.config('single_control')) return false; } return this.side==me.side; } return false; }, isOnline:function(){ if(this.ws&&lib.node&&!this.ws.closed&&this.ws.inited&&!this.isAuto){ return true; } return false; }, isOnline2:function(){ if(this.ws&&lib.node&&!this.ws.closed){ return true; } return false; }, isOffline:function(){ if(this.ws&&lib.node&&this.ws.closed){ return true; } return false; }, checkShow:function(skill,showonly){ var sourceSkill=get.info(skill); var noshow=false; if(sourceSkill&&sourceSkill.sourceSkill){ skill=sourceSkill.sourceSkill; } if(lib.skill.global.contains(skill)) return false; if(get.mode()!='guozhan'||game.expandSkills(this.getSkills()).contains(skill)){ if(showonly){ return false; } else{ noshow=true; } } var unseen0=this.isUnseen(0); var name1=this.name1||this.name; if(lib.character[name1]&&(!showonly||unseen0)){ var skills=game.expandSkills(lib.character[name1][3].slice(0)); if(skills.contains(skill)){ if(!noshow&&this.isUnseen(0)) this.showCharacter(0); return 'main'; } } var unseen1=this.isUnseen(1); var name2=this.name2; if(lib.character[name2]&&(!showonly||unseen1)){ var skills=game.expandSkills(lib.character[name2][3].slice(0)); if(skills.contains(skill)){ if(!noshow&&this.isUnseen(1)) this.showCharacter(1); return 'vice'; } } return false; }, needsToDiscard:function(num){ if(typeof num!='number') num=0; return Math.max(0,num+this.countCards('h',card=>!this.canIgnoreHandcard(card))-this.getHandcardLimit()); }, distanceTo:function(target,method){ return get.distance(this,target,method); }, distanceFrom:function(target,method){ return get.distance(target,this,method); }, hasSkill:function(skill,arg2,arg3,arg4){ return game.expandSkills(this.getSkills(arg2,arg3,arg4)).contains(skill); }, hasStockSkill:function(skill,arg1,arg2,arg3){ return game.expandSkills(this.getStockSkills(arg1,arg2,arg3)).contains(skill); }, isZhu2:function(){ var player=this,mode=get.mode(); if(!this.isZhu) return false; if(mode=='identity') return true; if(mode=='versus'&&(_status.mode=='four'||_status.mode=='guandu')) return true; return false; }, hasZhuSkill:function(skill,player){ if(!this.hasSkill(skill)) return false; if(player){ var mode=get.mode(); if(mode=='identity'&&_status.mode=='purple'){ if(this.identity.slice(0,1)!=player.identity.slice(0,1)) return false; } if(mode=='versus'&&(_status.mode=='four'||_status.mode=='guandu')){ if(this.side!=player.side) return false; } } return true; }, hasGlobalTag:function(tag,arg){ var skills=lib.skill.global.slice(0); game.expandSkills(skills); for(var i=0;i<skills.length;i++){ var info=lib.skill[skills[i]]; if(info&&info.ai){ if(info.ai.skillTagFilter&&info.ai[tag]&& info.ai.skillTagFilter(this,tag,arg)===false) continue; if(typeof info.ai[tag]=='string'){ if(info.ai[tag]==arg) return true; } else if(info.ai[tag]){ return true; } } } return false; }, hasSkillTag:function(tag,hidden,arg,globalskill){ var skills=this.getSkills(hidden); if(globalskill){ skills.addArray(lib.skill.global); } game.expandSkills(skills); for(var i=0;i<skills.length;i++){ var info=lib.skill[skills[i]]; if(info&&info.ai){ if(info.ai.skillTagFilter&&info.ai[tag]&& info.ai.skillTagFilter(this,tag,arg)===false) continue; if(typeof info.ai[tag]=='string'){ if(info.ai[tag]==arg) return true; } else if(info.ai[tag]){ return true; } } } return false; }, hasJudge:function(name){ if(name&&typeof name=='object'){ name=name.viewAs||name.name; } var judges=this.getCards('j'); for(var i=0;i<judges.length;i++){ if((judges[i].viewAs||judges[i].name)==name){ return true; } } return false; }, hasFriend:function(){ for(var i=0;i<game.players.length;i++){ if(game.players[i].isOut()) continue; if(game.players[i]!=this&&get.attitude(game.players[i],this)>0){ return true; } } return false; }, hasUnknown:function(num){ var mode=get.mode(); if(typeof num!='number'){ num=0; } if(mode=='identity'||mode=='guozhan'){ for(var i=0;i<game.players.length;i++){ if(game.players[i].ai.shown==0&&game.players[i]!=this){ num--; if(num<=0){ return true; } } } } return false; }, isUnknown:function(player){ var mode=get.mode(); if(mode=='identity'||mode=='guozhan'){ if(this.ai.shown==0&&this!=player){ return true; } } return false; }, hasWuxie:function(info){ if(this.countCards('hs','wuxie')) return true; var skills=this.getSkills('invisible').concat(lib.skill.global); game.expandSkills(skills); for(var i=0;i<skills.length;i++){ var ifo=get.info(skills[i]); if(ifo.hiddenWuxie&&info){ if(typeof ifo.hiddenWuxie=='function'&&ifo.hiddenWuxie(this,info)){ return true; } } else if(ifo.viewAs&&typeof ifo.viewAs!='function'&&ifo.viewAs.name=='wuxie'){ if(!ifo.viewAsFilter||ifo.viewAsFilter(this)){ return true; } } else{ var hiddenCard=ifo.hiddenCard; if(typeof hiddenCard=='function'&&hiddenCard(this,'wuxie')){ return true; } } } return false; }, hasSha:function(respond,noauto){ if(this.countCards('hs','sha')) return true; if(this.countCards('hs','hufu')) return true; if(!noauto&&this.countCards('hs','yuchanqian')) return true; if(this.hasSkillTag('respondSha',true,respond?'respond':'use',true)) return true; return this.hasUsableCard('sha'); }, hasShan:function(){ if(this.countCards('hs','shan')) return true; if(this.countCards('hs','hufu')) return true; if(this.hasSkillTag('respondShan',true,null,true)) return true; return this.hasUsableCard('shan'); }, mayHaveSha:function(viewer,type){ if((this.hp>2||!this.isZhu&&this.hp>1)&&this.hasSkillTag('respondSha',true,type,true)) return true; if(get.itemtype(viewer)!=='player') viewer=_status.event.player; let cards; if(this===viewer||get.itemtype(viewer)==='player'&&viewer.hasSkillTag('viewHandcard',null,this,true)) cards=this.getCards('h'); else cards=this.getShownCards(); if(cards.some(card=>{ let name=get.name(card,this); if(name=='sha'||name=='hufu'||name=='yuchanqian'){ if(type==='use') return lib.filter.cardEnabled(card,this); if(type==='respond') return lib.filter.cardRespondable(card,this); return true; } return false; })) return true; let hs=this.getCards('hs').removeArray(cards).length; if(hs===0) return false; return Math.pow(hs+(this.isPhaseUsing()?6:4),2)>100*_status.event.getRand('mayHaveSha'); }, mayHaveShan:function(viewer,type){ if((this.hp>2||!this.isZhu&&this.hp>1)&&this.hasSkillTag('respondShan',true,type,true)) return true; if(get.itemtype(viewer)!=='player') viewer=_status.event.player; let cards; if(this===viewer||get.itemtype(viewer)==='player'&&viewer.hasSkillTag('viewHandcard',null,this,true)) cards=this.getCards('h'); else cards=this.getShownCards(); if(cards.some(card=>{ let name=get.name(card,this); if(name==='shan'||name==='hufu'){ if(type==='use') return lib.filter.cardEnabled(card,this); if(type==='respond') return lib.filter.cardRespondable(card,this); return true; } return false; })) return true; let hs=this.getCards('hs').removeArray(cards).length; if(hs===0) return false; return Math.pow(hs+(this.isPhaseUsing()?3:5),2)>100*_status.event.getRand('mayHaveShan'); }, hasCard:function(name,position){ if(typeof name=='function'){ var hs=this.getCards(position); for(var i=0;i<hs.length;i++){ if(name(hs[i])) return true; } } else{ if(this.countCards(position,name)) return true; } return false; }, getEquip:function(name){ var es=this.getCards('e'); if(typeof name=='object'&&get.info(name)){ name=get.info(name).subtype; if(name){ name=parseInt(name[5]); } } else if(typeof name=='string'&&name.startsWith('equip')&&name.length==6){ name=parseInt(name[5]); } if(!name){ return null; } for(var i=0;i<es.length;i++){ if(typeof name==='number'){ if(get.info(es[i]).subtype==='equip'+name){ return es[i]; } } else{ if(es[i].name===name) return es[i]; var source=get.info(es[i]).source; if(Array.isArray(source)&&source.contains(name)){ return es[i]; } } } return null; }, getJudge:function(name){ var judges=this.node.judges.childNodes; for(var i=0;i<judges.length;i++){ if(judges[i].classList.contains('removing')) continue; if((judges[i].viewAs||judges[i].name)==name){ return judges[i]; } } return null; }, $drawAuto:function(cards,target){ if(this.isUnderControl(true,target)){ this.$draw(cards); } else{ this.$draw(cards.length); } }, $draw:function(num,init,config){ if(init!==false&&init!=='nobroadcast'){ game.broadcast(function(player,num,init,config){ player.$draw(num,init,config) },this,num,init,config); } var cards,node; if(get.itemtype(num)=='cards'){ cards=num; num=cards.length; } else if(get.itemtype(num)=='card'){ cards=[num]; num=1; } if(init!==false){ if(cards){ game.addVideo('drawCard',this,get.cardsInfo(cards)); } else{ game.addVideo('draw',this,num); } } if(cards){ cards=cards.slice(0); node=cards.shift().copy('thrown','drawingcard'); } else{ node=ui.create.div('.card.thrown.drawingcard'); } node.fixed=true; node.hide(); var dx,dy; if(game.chess){ var rect=this.getBoundingClientRect(); if(rect.left<=80){ dx=-10; if(rect.top<=80){ dy=-10; } else if(rect.top+rect.height+80>=ui.chessContainer.offsetHeight){ dy=10; } else{ dy=0; } } else if(rect.left+rect.width+80>=ui.chessContainer.offsetWidth){ dx=10; if(rect.top<=80){ dy=-10; } else if(rect.top+rect.height+80>=ui.chessContainer.offsetHeight){ dy=10; } else{ dy=0; } } else if(rect.top<=80){ dx=0; dy=-10; } else if(rect.top+rect.height+80>=ui.chessContainer.offsetHeight){ dx=0; dy=10; } else{ dx=rect.left+this.offsetWidth/2-ui.arena.offsetWidth/2; dy=rect.top+this.offsetHeight/2-ui.arena.offsetHeight/2; } var coeff=240/Math.sqrt(dx*dx+dy*dy); dx*=coeff; dy*=coeff; node.style.left=(this.getLeft()+this.offsetWidth/2-52-dx)+'px'; node.style.top=(this.getTop()+this.offsetHeight/2-52-dy)+'px'; this.parentNode.appendChild(node); } else{ this.parentNode.appendChild(node); node.style.left='calc(50% - 52px)'; node.style.top='calc(50% - 52px)'; dx=this.getLeft()+this.offsetWidth/2-52-node.offsetLeft; dy=this.getTop()+this.offsetHeight/2-52-node.offsetTop; if(get.is.mobileMe(this)){ dx+=get.cardOffset(); if(ui.arena.classList.contains('oblongcard')){ dy-=16; } } } node.style.transitionDuration='0.8s'; ui.refresh(node); if(typeof num=='number'&&init!==false){ config={ total:num, current:1 } } if(config&&config.total>1){ var total=config.total,current=config.current; var dxtotal; if(total<=5){ dxtotal=Math.min(80,(total-1)*20); dx+=-dxtotal+2*dxtotal*(current-1)/(total-1) } else{ var total2=Math.floor(total/2); if(current<=total2){ total=total2; dy-=20; } else{ current-=total2; total-=total2; dy+=20; } dxtotal=Math.min(80,(total-1)*20); dx+=-dxtotal+2*dxtotal*(current-1)/(total-1) } config.current++; } if(node.style.transform&&node.style.transform!='none'&&node.style.transform.indexOf('translate')==-1){ node.style.transform+=' translate('+dx+'px,'+dy+'px)'; } else{ node.style.transform='translate('+dx+'px,'+dy+'px)'; } node.show(); node.listenTransition(function(){ node.style.transitionDuration='0.5s'; ui.refresh(node); node.delete(); }); var that=this; if(num&&num>1){ if(config&&config.total>1){ setTimeout(function(){ if(cards){ that.$draw(cards,false,config) } else{ that.$draw(num-1,false,config) } },50) } else{ setTimeout(function(){ if(cards){ that.$draw(cards,false,config) } else{ that.$draw(num-1,false,config) } },200); } } }, $compareMultiple:function(card1,targets,cards){ game.broadcast(function(player,card1,targets,cards){ player.$compareMultiple(card1,targets,cards); },this,card1,targets,cards); game.addVideo('compareMultiple',this,[get.cardInfo(card1),get.targetsInfo(targets),get.cardsInfo(cards)]); var player=this; var node1=player.$throwxy2(card1, 'calc(50% - 52px)','calc(50% + 10px)','perspective(600px) rotateY(180deg)',true ); if(lib.config.cardback_style!='default'){ node1.style.transitionProperty='none'; ui.refresh(node1); node1.classList.add('infohidden'); ui.refresh(node1); node1.style.transitionProperty=''; } else{ node1.classList.add('infohidden'); } node1.style.transform='perspective(600px) rotateY(180deg) translateX(0)'; var onEnd01=function(){ //node1.removeEventListener('webkitTransitionEnd',onEnd01); setTimeout(function(){ node1.style.transition='all ease-in 0.3s'; node1.style.transform='perspective(600px) rotateY(270deg) translateX(52px)'; var onEnd=function(){ node1.classList.remove('infohidden'); node1.style.transition='all 0s'; ui.refresh(node1); node1.style.transform='perspective(600px) rotateY(-90deg) translateX(52px)'; ui.refresh(node1); node1.style.transition=''; ui.refresh(node1); node1.style.transform=''; //node1.removeEventListener('webkitTransitionEnd',onEnd); } node1.listenTransition(onEnd); },300); }; node1.listenTransition(onEnd01); setTimeout(function(){ var left0=-targets.length*52-(targets.length-1)*8; for(var i=0;i<targets.length;i++){ (function(target,card2,i){ var left=left0+i*120; var node2; if(left<0){ node2=target.$throwxy2(card2, 'calc(50% - '+(-left)+'px)','calc(50% - 114px)','perspective(600px) rotateY(180deg)',true ); } else{ node2=target.$throwxy2(card2, 'calc(50% + '+left+'px)','calc(50% - 114px)','perspective(600px) rotateY(180deg)',true ); } if(lib.config.cardback_style!='default'){ node2.style.transitionProperty='none'; ui.refresh(node2); node2.classList.add('infohidden'); ui.refresh(node2); node2.style.transitionProperty=''; } else{ node2.classList.add('infohidden'); } node2.style.transform='perspective(600px) rotateY(180deg) translateX(0)'; var onEnd02=function(){ //node2.removeEventListener('webkitTransitionEnd',onEnd02); setTimeout(function(){ node2.style.transition='all ease-in 0.3s'; node2.style.transform='perspective(600px) rotateY(270deg) translateX(52px)'; var onEnd=function(){ node2.classList.remove('infohidden'); node2.style.transition='all 0s'; ui.refresh(node2); node2.style.transform='perspective(600px) rotateY(-90deg) translateX(52px)'; ui.refresh(node2); node2.style.transition=''; ui.refresh(node2); node2.style.transform=''; //node2.removeEventListener('webkitTransitionEnd',onEnd); } node2.listenTransition(onEnd); },200); }; node2.listenTransition(onEnd02); }(targets[i],cards[i],i)) } },200); }, $compare:function(card1,target,card2){ game.broadcast(function(player,target,card1,card2){ player.$compare(card1,target,card2); },this,target,card1,card2); game.addVideo('compare',this,[get.cardInfo(card1),target.dataset.position,get.cardInfo(card2)]); var player=this; var node1=player.$throwxy2(card1, 'calc(50% - 114px)','calc(50% - 52px)','perspective(600px) rotateY(180deg)',true ); if(lib.config.cardback_style!='default'){ node1.style.transitionProperty='none'; ui.refresh(node1); node1.classList.add('infohidden'); ui.refresh(node1); node1.style.transitionProperty=''; } else{ node1.classList.add('infohidden'); } node1.style.transform='perspective(600px) rotateY(180deg) translateX(0)'; var onEnd01=function(){ //node1.removeEventListener('webkitTransitionEnd',onEnd01); setTimeout(function(){ node1.style.transition='all ease-in 0.3s'; node1.style.transform='perspective(600px) rotateY(270deg) translateX(52px)'; var onEnd=function(){ node1.classList.remove('infohidden'); node1.style.transition='all 0s'; ui.refresh(node1); node1.style.transform='perspective(600px) rotateY(-90deg) translateX(52px)'; ui.refresh(node1); node1.style.transition=''; ui.refresh(node1); node1.style.transform=''; //node1.removeEventListener('webkitTransitionEnd',onEnd); } node1.listenTransition(onEnd); },300); }; node1.listenTransition(onEnd01); setTimeout(function(){ var node2=target.$throwxy2(card2, 'calc(50% + 10px)','calc(50% - 52px)','perspective(600px) rotateY(180deg)',true ); if(lib.config.cardback_style!='default'){ node2.style.transitionProperty='none'; ui.refresh(node2); node2.classList.add('infohidden'); ui.refresh(node2); node2.style.transitionProperty=''; } else{ node2.classList.add('infohidden'); } node2.style.transform='perspective(600px) rotateY(180deg) translateX(0)'; var onEnd02=function(){ //node2.removeEventListener('webkitTransitionEnd',onEnd02); setTimeout(function(){ node2.style.transition='all ease-in 0.3s'; node2.style.transform='perspective(600px) rotateY(270deg) translateX(52px)'; var onEnd=function(){ node2.classList.remove('infohidden'); node2.style.transition='all 0s'; ui.refresh(node2); node2.style.transform='perspective(600px) rotateY(-90deg) translateX(52px)'; ui.refresh(node2); node2.style.transition=''; ui.refresh(node2); node2.style.transform=''; //node2.removeEventListener('webkitTransitionEnd',onEnd); } node2.listenTransition(onEnd); },200); }; node2.listenTransition(onEnd02); },200); }, $throw:function(card,time,init,nosource){ if(typeof card=='number'){ var tmp=card; card=[]; while(tmp--){ var cardx=ui.create.card(); cardx.classList.add('infohidden'); cardx.classList.add('infoflip'); card.push(cardx); } } if(init!==false){ if(init!=='nobroadcast'){ game.broadcast(function(player,card,time,init,nosource){ player.$throw(card,time,init,nosource); },this,card,time,init); } if(get.itemtype(card)!='cards'){ if(get.itemtype(card)=='card'){ card=[card]; } else{ return; } } game.addVideo('throw',this,[get.cardsInfo(card),time,nosource]); } if(game.chess){ this.chessFocus(); } if(get.itemtype(card)=='cards'){ var node; for(var i=0;i<card.length;i++){ node=this.$throw(card[i],time,false,nosource); } return node; } else{ var node; if(card==undefined||card.length==0) return; node=this.$throwordered(card.copy('thrown'),nosource); if(time!=undefined){ node.fixed=true; setTimeout(function(){node.delete()},time); } lib.listenEnd(node); return node; } }, $throwordered:function(){ return this.$throwordered2.apply(this,arguments); // if(lib.config.low_performance){ // return this.$throwordered2.apply(this,arguments); // } // else{ // return this.$throwordered1.apply(this,arguments); // } }, $throwordered1:function(node,nosource){ node.classList.add('thrown'); node.hide(); node.style.transitionProperty='left,top,opacity,transform'; for(var i=0;i<ui.thrown.length;i++){ if(ui.thrown[i].parentNode!=ui.arena|| ui.thrown[i].classList.contains('removing')){ ui.thrown.splice(i--,1); } } ui.thrown.push(node); var uithrowns=ui.thrown.slice(0); var tops; if(game.chess){ switch(Math.floor((ui.thrown.length-1)/4)){ case 0: tops=['calc(50% - 82px)']; break; case 1: tops=['calc(50% - 139px)','calc(50% - 25px)']; break; case 2: tops=['calc(50% - 196px)','calc(50% - 82px)','calc(50% + 32px)']; break; default: tops=['calc(50% - 253px)','calc(50% - 139px)', 'calc(50% - 25px)','calc(50% + 89px)']; } } else{ switch(Math.floor((ui.thrown.length-1)/4)){ case 0: tops=['calc(50% - 52px)']; break; case 1: tops=['calc(50% - 109px)','calc(50% + 5px)']; break; case 2: tops=['calc(50% - 166px)','calc(50% - 52px)','calc(50% + 62px)']; break; default: tops=['calc(50% - 223px)','calc(50% - 109px)', 'calc(50% + 5px)','calc(50% + 119px)']; } } while(uithrowns.length){ var throwns=uithrowns.splice(0,Math.min(uithrowns.length,4)); switch(throwns.length){ case 1: throwns[0].style.left='calc(50% - 52px)'; break; case 2: throwns[0].style.left='calc(50% - 109px)'; throwns[1].style.left='calc(50% + 5px)'; break; case 3: throwns[0].style.left='calc(50% - 166px)'; throwns[1].style.left='calc(50% - 52px)'; throwns[2].style.left='calc(50% + 62px)'; break; case 4: throwns[0].style.left='calc(50% - 223px)'; throwns[1].style.left='calc(50% - 109px)'; throwns[2].style.left='calc(50% + 5px)'; throwns[3].style.left='calc(50% + 119px)'; break; } var top; if(tops.length){ top=tops.shift(); } else{ if(game.chess){ top='calc(50% - 82px)'; } else{ top='calc(50% - 52px)'; } } for(var i=0;i<throwns.length;i++){ throwns[i].style.top=top; } } if(nosource){ node.style.transform='scale(0)'; node.classList.add('center'); } else{ var parseCalc=function(str){ var per=str.slice(str.indexOf('calc(')+5,str.indexOf('%')); var add=str.slice(str.indexOf('%')+1,str.indexOf('px')).replace(/\s/g,''); return [parseInt(per),parseInt(add)]; } var nx=parseCalc(node.style.left); var ny=parseCalc(node.style.top); nx=nx[0]*ui.arena.offsetWidth/100+nx[1]; ny=ny[0]*ui.arena.offsetHeight/100+ny[1]; var dx,dy; if(game.chess){ var rect=this.getBoundingClientRect(); dx=rect.left+this.offsetWidth/2-52-nx; dy=rect.top+this.offsetHeight/2-52-ny; } else{ dx=this.getLeft()+this.offsetWidth/2-52-nx; dy=this.getTop()+this.offsetHeight/2-52-ny; if(get.is.mobileMe(this)){ dx+=get.cardOffset(); if(ui.arena.classList.contains('oblongcard')){ dy-=16; } } } if(node.style.transform&&node.style.transform!='none'&&node.style.transform.indexOf('translate')==-1){ node.style.transform+=' translate('+dx+'px,'+dy+'px)'; } else{ node.style.transform='translate('+dx+'px,'+dy+'px)'; } } ui.arena.appendChild(node); ui.refresh(node); node.style.transform=''; node.show(); lib.listenEnd(node); return node; }, $throwordered2:function(node,nosource){ node.classList.add('thrown'); node.classList.add('center'); node.hide(); node.style.transitionProperty='left,top,opacity,transform'; if(nosource){ // node.style.transform='scale(0)'; } else{ var nx=[50,-52]; var ny=[50,-52]; nx=nx[0]*ui.arena.offsetWidth/100+nx[1]; ny=ny[0]*ui.arena.offsetHeight/100+ny[1]; var dx,dy; if(game.chess){ var rect=this.getBoundingClientRect(); dx=rect.left+this.offsetWidth/2-52-nx; dy=rect.top+this.offsetHeight/2-52-ny; } else{ dx=this.getLeft()+this.offsetWidth/2-52-nx; dy=this.getTop()+this.offsetHeight/2-52-ny; if(get.is.mobileMe(this)){ dx+=get.cardOffset(); if(ui.arena.classList.contains('oblongcard')){ dy-=16; } } } if(node.style.transform&&node.style.transform!='none'&&node.style.transform.indexOf('translate')==-1){ node.style.transform+=' translate('+dx+'px,'+dy+'px)'; } else{ node.style.transform='translate('+dx+'px,'+dy+'px)'; } } ui.arena.appendChild(node); ui.refresh(node); for(var i=0;i<ui.thrown.length;i++){ if(ui.thrown[i].parentNode!=ui.arena|| ui.thrown[i].classList.contains('removing')){ ui.thrown.splice(i--,1); } } ui.thrown.push(node); var uithrowns=ui.thrown.slice(0); var tops; switch(Math.floor((ui.thrown.length-1)/4)){ case 0: tops=[0]; break; case 1: tops=[-57,57]; break; case 2: tops=[-114,0,114]; break; default: tops=[-171,-57,57,171]; } while(uithrowns.length){ var throwns=uithrowns.splice(0,Math.min(uithrowns.length,4)); switch(throwns.length){ case 1: throwns[0]._transthrown='translate(0px,'; break; case 2: throwns[0]._transthrown='translate(-57px,'; throwns[1]._transthrown='translate(57px,'; break; case 3: throwns[0]._transthrown='translate(-114px,'; throwns[1]._transthrown='translate(0,'; throwns[2]._transthrown='translate(114px,'; break; case 4: throwns[0]._transthrown='translate(-171px,'; throwns[1]._transthrown='translate(-57px,'; throwns[2]._transthrown='translate(57px,'; throwns[3]._transthrown='translate(171px,'; break; } var top; if(tops.length){ top=tops.shift(); } else{ top=0; } if(game.chess){ top-=30; } for(var i=0;i<throwns.length;i++){ throwns[i].style.transform=throwns[i]._transthrown+top+'px)'; delete throwns[i]._transthrown; } } node.show(); lib.listenEnd(node); return node; }, $throwxy:function(card,left,top){ var node=card.copy('thrown','thrownhighlight'); node.dataset.position=this.dataset.position; node.hide(); node.style.transitionProperty='left,top,opacity'; ui.arena.appendChild(node); ui.refresh(node); node.show(); node.style.left=left; node.style.top=top; lib.listenEnd(node); return node; }, $throwxy2:function(card,left,top,trans,flipx,flipy){ if(game.chess){ return this.$throwxy.apply(this,arguments); } var node=card.copy('thrown','thrownhighlight'); node.style.left=left; node.style.top=top; node.hide(); // node.style.transitionProperty='left,top,opacity,transform'; var parseCalc=function(str){ var per=str.slice(str.indexOf('calc(')+5,str.indexOf('%')); var add=str.slice(str.indexOf('%')+1,str.indexOf('px')).replace(/\s/g,''); return [parseInt(per),parseInt(add)]; } var nx=parseCalc(node.style.left); var ny=parseCalc(node.style.top); nx=nx[0]*ui.arena.offsetWidth/100+nx[1]; ny=ny[0]*ui.arena.offsetHeight/100+ny[1]; var dx=this.getLeft()+this.offsetWidth/2-52-nx; var dy=this.getTop()+this.offsetHeight/2-52-ny; if(flipx) dx=-dx; if(flipy) dy=-dy; if(trans){ node.style.transform=trans+' translate('+dx+'px,'+dy+'px)'; } else{ node.style.transform='translate('+dx+'px,'+dy+'px)'; } ui.arena.appendChild(node); ui.refresh(node); node.show(); // node.style.transform=trans||''; lib.listenEnd(node); return node; }, throwDice:function(num){ if(typeof num!='number'){ num=get.rand(6)+1; _status.event.num=num; } if(!game.online){ game.pause(); } game.broadcastAll(function(num){ var diceContainer=ui.create.div('.fullsize.dice-container',ui.window); ui.window.classList.add('dicepaused'); var dice=ui.create.div('.dice'); var side; side=ui.create.div('.side.front',dice); ui.create.div('.dot.center',side); ui.create.div('.side.front.inner',dice); side=ui.create.div('.side.top',dice); ui.create.div('.dot.dtop.dleft',side); ui.create.div('.dot.dbottom.dright',side); ui.create.div('.side.top.inner',dice); side=ui.create.div('.side.right',dice); ui.create.div('.dot.dtop.dleft',side); ui.create.div('.dot.center',side); ui.create.div('.dot.dbottom.dright',side); ui.create.div('.side.right.inner',dice); side=ui.create.div('.side.left',dice); ui.create.div('.dot.dtop.dleft',side); ui.create.div('.dot.dtop.dright',side); ui.create.div('.dot.dbottom.dleft',side); ui.create.div('.dot.dbottom.dright',side); ui.create.div('.side.left.inner',dice); side=ui.create.div('.side.bottom',dice); ui.create.div('.dot.center',side); ui.create.div('.dot.dtop.dleft',side); ui.create.div('.dot.dtop.dright',side); ui.create.div('.dot.dbottom.dleft',side); ui.create.div('.dot.dbottom.dright',side); ui.create.div('.side.bottom.inner',dice); side=ui.create.div('.side.back',dice); ui.create.div('.dot.dtop.dleft',side); ui.create.div('.dot.dtop.dright',side); ui.create.div('.dot.dbottom.dleft',side); ui.create.div('.dot.dbottom.dright',side); ui.create.div('.dot.center dleft',side); ui.create.div('.dot.center dright',side); ui.create.div('.side.back.inner',dice); ui.create.div('.side.cover.x',dice); ui.create.div('.side.cover.y',dice); ui.create.div('.side.cover.z',dice); var map={ 1:[75,0,45], 2:[-15,45,0], 3:[165,-45,90], 4:[345,-45,90], 5:[345,-45,180], 6:[255,0,135] }; dice.roll=function(deg){ if(typeof deg=='number'){ dice.current[0]+=deg; deg=dice.current; } deg=deg.slice(0); dice.current=deg; this.style.transform='rotateX('+deg[0]+'deg) rotateY('+deg[1]+'deg) rotateZ('+deg[2]+'deg)'; }; dice.roll(map[num]); diceContainer.appendChild(dice); ui.refresh(dice); dice.roll(1025); dice.addEventListener('webkitTransitionEnd',function(){ if(!dice.over){ dice.style.transition='transform 0.8s ease'; dice.roll(-20); dice.over=true; } else if(!dice.resumed){ setTimeout(function(){ diceContainer.delete(); ui.window.classList.remove('dicepaused'); },300); if(!game.online){ setTimeout(game.resume,800); } dice.resumed=true; } }); },num); }, $giveAuto:function(card,player){ if(Array.isArray(card)&&card.length==0) return; var args=Array.from(arguments); if(_status.connectMode||(!this.isUnderControl(true)&&!player.isUnderControl(true))){ if(Array.isArray(card)){ card=card.length; } else{ card=1; } args[0]=card; } return this.$give.apply(this,args); }, $give:function(card,player,log,init){ if(init!==false){ game.broadcast(function(source,card,player,init){ source.$give(card,player,false,init); },this,card,player,init); if(typeof card=='number'&&card>=0){ game.addVideo('give',this,[card,player.dataset.position]); } else{ if(get.itemtype(card)=='card'){ card=[card]; } if(get.itemtype(card)=='cards'){ game.addVideo('giveCard',this,[get.cardsInfo(card),player.dataset.position]); } } } if(get.itemtype(card)=='cards'){ if(log!=false&&!_status.video){ game.log(player,'从',this,'获得了',card); } if(this.$givemod){ this.$givemod(card,player); } else{ for(var i=0;i<card.length;i++){ this.$give(card[i],player,false,false); } } } else if(typeof card=='number'&&card>=0){ if(log!=false&&!_status.video){ game.log(player,'从',this,'获得了'+get.cnNumber(card)+'张牌'); } if(this.$givemod){ this.$givemod(card,player); } else{ while(card--) this.$give('',player,false,false); } } else{ if(log!=false&&!_status.video){ if(get.itemtype(card)=='card'&&log!=false){ game.log(player,'从',this,'获得了',card); } else{ game.log(player,'从',this,'获得了一张牌'); } } if(this.$givemod){ this.$givemod(card,player); } else{ var node; if(get.itemtype(card)=='card'){ node=card.copy('card','thrown',false); } else{ node=ui.create.div('.card.thrown'); } // node.dataset.position=this.dataset.position; node.fixed=true; this.$throwordered(node); // lib.listenEnd(node); // node.hide(); // node.style.transitionProperty='left,top,opacity'; // // node.style.transform='rotate('+(Math.random()*16-8)+'deg)'; // // ui.arena.appendChild(node); // ui.refresh(node); // node.show(); // node.style.left='calc(50% - 52px '+((Math.random()-0.5<0)?'+':'-')+' '+Math.random()*100+'px)'; // node.style.top='calc(50% - 52px '+((Math.random()-0.5<0)?'+':'-')+' '+Math.random()*80+'px)'; node.listenTransition(function(){ var dx=player.getLeft()+player.offsetWidth/2-52-node.offsetLeft; var dy=player.getTop()+player.offsetHeight/2-52-node.offsetTop; if(node.style.transform&&node.style.transform!='none'&&node.style.transform.indexOf('translate')==-1){ node.style.transform+=' translate('+dx+'px,'+dy+'px)'; } else{ node.style.transform='translate('+dx+'px,'+dy+'px)'; } node.delete(); }); // setTimeout(function(){ // // node.removeAttribute('style'); // // node.dataset.position=player.dataset.position; // var dx=player.offsetLeft+player.offsetWidth/2-52-node.offsetLeft; // var dy=player.offsetTop+player.offsetHeight/2-52-node.offsetTop; // if(node.style.transform&&node.style.transform!='none'&&node.style.transform.indexOf('translate')==-1){ // node.style.transform+=' translate('+dx+'px,'+dy+'px)'; // } // else{ // node.style.transform='translate('+dx+'px,'+dy+'px)'; // } // // node.delete(); // },700); } } }, $equip:function(card){ game.broadcast(function(player,card){ player.$equip(card); },this,card); card.fix(); card.style.transform=''; card.classList.remove('drawinghidden'); delete card._transform; var player=this; var equipNum=get.equipNum(card); var equipped=false; for(var i=0;i<player.node.equips.childNodes.length;i++){ if(get.equipNum(player.node.equips.childNodes[i])>=equipNum){ player.node.equips.insertBefore(card,player.node.equips.childNodes[i]); equipped=true; break; } } if(!equipped){ player.node.equips.appendChild(card); if(_status.discarded){ _status.discarded.remove(card); } } var info=get.info(card); if(info.skills){ for(var i=0;i<info.skills.length;i++){ player.addSkillTrigger(info.skills[i]); } } return player; }, $gain:function(card,log,init){ if(init!==false){ game.broadcast(function(player,card,init){ player.$gain(card,false,init); },this,card,init); if(typeof card=='number'&&card>=0){ game.addVideo('gain',this,card); } else{ if(get.itemtype(card)=='card'){ card=[card]; } if(get.itemtype(card)=='cards'){ game.addVideo('gainCard',this,get.cardsInfo(card)); } else{ game.addVideo('gain',this,1); } } } if(get.itemtype(card)=='cards'){ if(log!=false&&!_status.video){ game.log(this,'获得了',card); } if(this.$gainmod){ this.$gainmod(card); } else{ for(var i=0;i<card.length;i++){ this.$gain(card[i],false,false); } } } else if(typeof card=='number'&&card>1){ if(log!=false&&!_status.video){ game.log(this,'获得了'+get.cnNumber(card)+'张牌'); } if(this.$gainmod){ this.$gainmod(card); } else{ for(var i=0;i<card;i++){ this.$gain(1,false,false); } } } else{ if(get.itemtype(card)=='card'&&log!=false&&!_status.video){ game.log(this,'获得了',card); } if(this.$gainmod){ this.$gainmod(card); } else{ var node; if(get.itemtype(card)=='card'){ // node=this.$throwordered(card.copy(),true); node=card.copy('thrown',false); } else{ // node=this.$throwordered(ui.create.div('.card.thrown'),true); node=ui.create.div('.card.thrown'); node.moveTo=lib.element.card.moveTo; node.moveDelete=lib.element.card.moveDelete; } node.fixed=true; node.style.left='calc(50% - 52px '+((Math.random()-0.5<0)?'+':'-')+' '+Math.random()*100+'px)'; node.style.top='calc(50% - 52px '+((Math.random()-0.5<0)?'+':'-')+' '+Math.random()*100+'px)'; node.style.transform='scale(0)'; node.hide(); ui.arena.appendChild(node); ui.refresh(node); node.show(); node.style.transform=''; lib.listenEnd(node); var player=this; setTimeout(function(){ node.moveDelete(player); },700); } } }, $gain2:function(cards,log){ if(log===true){ game.log(this,'获得了',cards); } game.broadcast(function(player,cards){ player.$gain2(cards); },this,cards); if(get.itemtype(cards)=='card') cards=[cards]; else if(get.itemtype(cards)!='cards') return; var list=[],list2=[]; for(var i=0;i<cards.length;i++){ if(cards[i].clone&& (cards[i].clone.parentNode==this.parentNode|| cards[i].clone.parentNode==ui.arena)&& parseFloat(getComputedStyle(cards[i].clone).opacity)>0.3){ cards[i].clone.moveDelete(this); list2.push(cards[i].clone); } else{ list.push(cards[i]); } } if(list2.length){ game.addVideo('gain2',this,get.cardsInfo(list2)); } if(list.length){ this.$draw(list,'nobroadcast'); return true; } }, $skill:function(name,type,color,avatar){ if(typeof type!='string') type='legend'; if(!avatar){ this.playerfocus(1500); game.delay(2); } else{ game.addVideo('playerfocus2'); game.broadcastAll(function(){ ui.arena.classList.add('playerfocus'); setTimeout(function(){ ui.arena.classList.remove('playerfocus'); },1800) }); game.delay(3); } var that=this; setTimeout(function(){ game.broadcastAll(function(that,type,name,color,avatar){ if(lib.config.animation&&!lib.config.low_performance){ if(game.chess){ that['$'+type+'2'](1200); } else{ that['$'+type](1200); } } if(name){ that.$fullscreenpop(name,color,avatar); } },that,type,name,color,avatar); },avatar?0:300); }, $fire:function(){ game.addVideo('flame',this,'fire'); var left,top; if(game.chess){ var rect=this.getBoundingClientRect(); left=rect.left; top=rect.top; } else{ left=this.getLeft(); top=this.getTop(); } game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-20,700,'fire'); }, $thunder:function(){ game.addVideo('flame',this,'thunder'); var left,top; if(game.chess){ var rect=this.getBoundingClientRect(); left=rect.left; top=rect.top; } else{ left=this.getLeft(); top=this.getTop(); } game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,700,'thunder'); }, $rare2:function(){ game.addVideo('flame',this,'rare2'); var rect=this.getBoundingClientRect(); var left=rect.left; var top=rect.top+15; game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,700,'rare'); }, $epic2:function(){ game.addVideo('flame',this,'epic2'); var rect=this.getBoundingClientRect(); var left=rect.left; var top=rect.top+15; game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,700,'epic'); }, $legend2:function(){ game.addVideo('flame',this,'legend2'); var rect=this.getBoundingClientRect(); var left=rect.left; var top=rect.top+15; game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,700,'legend'); }, $rare:function(time){ time=time||700; game.addVideo('flame',this,'rare'); var left,top; if(game.chess){ left=this.getLeft()-ui.arena.offsetLeft; top=this.getTop()-ui.arena.offsetTop; } else{ left=this.getLeft(); top=this.getTop(); } if(this.classList.contains('minskin')){ top+=15; } game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,time,'rare'); }, $epic:function(time){ time=time||700; game.addVideo('flame',this,'epic'); var left,top; if(game.chess){ left=this.getLeft()-ui.arena.offsetLeft; top=this.getTop()-ui.arena.offsetTop; } else{ left=this.getLeft(); top=this.getTop(); } if(this.classList.contains('minskin')){ top+=15; } game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,time,'epic'); }, $legend:function(time){ time=time||700; game.addVideo('flame',this,'legend'); var left,top; if(game.chess){ left=this.getLeft()-ui.arena.offsetLeft; top=this.getTop()-ui.arena.offsetTop; } else{ left=this.getLeft(); top=this.getTop(); } if(this.classList.contains('minskin')){ top+=15; } game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,time,'legend'); }, $coin:function(){ game.broadcast(function(player){ if(!lib.config.low_performance){ player.$coin(); } },this); game.addVideo('flame',this,'coin'); var left=this.getLeft()-ui.arena.offsetLeft; var top=this.getTop()-ui.arena.offsetTop; if(this.classList.contains('minskin')){ top+=15; } top-=25; game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,700,'coin'); }, $dust:function(){ game.broadcast(function(player){ if(!lib.config.low_performance){ player.$dust(); } },this); game.addVideo('flame',this,'dust'); var left=this.getLeft()-ui.arena.offsetLeft; var top=this.getTop()-ui.arena.offsetTop; if(this.classList.contains('minskin')){ top+=15; } top-=25; game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,700,'dust'); }, $recover:function(){ game.addVideo('flame',this,'recover'); var left,top; if(game.chess){ var rect=this.getBoundingClientRect(); left=rect.left; top=rect.top; } else{ left=this.getLeft(); top=this.getTop(); } game.animate.flame(left+this.offsetWidth/2, top+this.offsetHeight-30,700,'recover'); }, $fullscreenpop:function(str,nature,avatar,broadcast){ if(broadcast!==false) game.broadcast(function(player,str,nature,avatar){ player.$fullscreenpop(str,nature,avatar); },this,str,nature,avatar); game.addVideo('fullscreenpop',this,[str,nature,avatar]); var node=ui.create.div('.damage'); if(avatar&&this.node){ if(avatar=='vice'){ if(lib.character[this.name2]){ avatar=this.node.avatar2; } } else{ if(lib.character[this.name]){ avatar=this.node.avatar; } } if(!get.is.div(avatar)){ avatar=false; } } else{ avatar=false; } if(avatar){ node.classList.add('fullscreenavatar'); ui.create.div('',ui.create.div(node)); // ui.create.div('',str.split('').join('<br>'),ui.create.div('.text.textbg',node)); ui.create.div('','<div>'+str.split('').join('</div><br><div>')+'</div>',ui.create.div('.text',node)); node.firstChild.firstChild.style.backgroundImage=avatar.style.backgroundImage; node.dataset.nature=nature||'unknown'; var num=0; var nodes=node.lastChild.firstChild.querySelectorAll('div'); var interval=setInterval(function(){ if(num<nodes.length){ nodes[num].classList.add('flashtext'); num++; } else{ clearInterval(interval); } },100); } else{ avatar=false; node.innerHTML=str; node.dataset.nature=nature||'soil'; } if(avatar){ var rect1=ui.window.getBoundingClientRect(); var rect2=this.getBoundingClientRect(); var dx=Math.round(2*rect2.left+rect2.width-rect1.width); var dy=Math.round(2*rect2.top+rect2.height-rect1.height); node.style.transform='scale(0.5) translate('+dx+'px,'+dy+'px)'; } ui.window.appendChild(node); ui.refresh(node); if(avatar){ node.style.transform='scale(1)'; node.style.opacity=1; } else{ node.classList.add('damageadded'); } setTimeout(function(){ node.delete(); node.style.transform='scale(1.5)' },avatar?1600:1000); }, $damagepop:function(num,nature,font,nobroadcast){ if(typeof num=='number'||typeof num=='string'){ game.addVideo('damagepop',this,[num,nature,font]); if(nobroadcast!==false) game.broadcast(function(player,num,nature,font){ player.$damagepop(num,nature,font); },this,num,nature,font); var node=ui.create.div('.damage'); if(font){ node.classList.add('normal-font'); } if(typeof num=='number'&&num>0){ if(num==Infinity) num='+∞' else num='+'+num; } else if(num==-Infinity) num='-∞'; node.innerHTML=num; this.damagepopups.push(node); node.dataset.nature=nature||'soil'; if(this.damagepopups.length==1){ this.$damagepop(); } } else if(this.damagepopups.length){ var node=this.damagepopups[0]; this.appendChild(node); ui.refresh(node); node.classList.add('damageadded'); node.listenTransition(function(){ setTimeout(function(){ node.delete(); },200); }); // setTimeout(function(){ // node.delete(); // },500); var that=this; setTimeout(function(){ that.damagepopups.shift(); that.$damagepop(); },500); } }, $damage:function(source){ if(get.itemtype(source)=='player'){ game.addVideo('damage',this,source.dataset.position); } else{ game.addVideo('damage',this); } game.broadcast(function(player,source){ player.$damage(source); },this,source); if(source&&source!=this&&lib.config.damage_shake){ var left,top; if(source.getTop()==this.getTop()){ left=20; top=0; } else{ var ratio=(source.getLeft()-this.getLeft())/(source.getTop()-this.getTop()); left=Math.abs(20*ratio/Math.sqrt(1+ratio*ratio)); top=Math.abs(20/Math.sqrt(1+ratio*ratio)); } if(source.getLeft()-this.getLeft()>0) left=-left; if(source.getTop()-this.getTop()>0) top=-top; if(get.is.mobileMe(this)){ if(this.classList.contains('linked')){ this.node.avatar.style.transform='translate('+left+'px,'+top+'px) rotate(-90deg)'; this.node.avatar2.style.transform='translate('+left+'px,'+top+'px) rotate(-90deg)'; } else{ this.node.avatar.style.transform='translate('+left+'px,'+top+'px)'; this.node.avatar2.style.transform='translate('+left+'px,'+top+'px)'; } } else if(this.classList.contains('linked')&&get.is.newLayout()){ this.style.transform='translate('+left+'px,'+top+'px) rotate(-90deg)'; } else if(this._chesstransform){ this.style.transform='translate('+(left+this._chesstransform[0])+'px,'+(top+this._chesstransform[1])+'px)'; } else{ this.style.transform='translate('+left+'px,'+top+'px)'; } } else{ var zoom1=0.9,zoom2=0.95; if(arguments[1]=='phase'){ zoom1=1.05; zoom2=1.05; } if(get.is.mobileMe(this)){ if(this.classList.contains('linked')){ this.node.avatar.style.transform='scale('+zoom1+') rotate(-90deg)'; this.node.avatar2.style.transform='scale('+zoom1+') rotate(-90deg)'; } else{ this.node.avatar.style.transform='scale('+zoom1+')'; this.node.avatar2.style.transform='scale('+zoom1+')'; } } else if(this.classList.contains('linked')&&get.is.newLayout()){ this.style.transform='scale('+zoom2+') rotate(-90deg)'; } else if(game.chess&&this._chesstransform){ this.style.transform='translate('+this._chesstransform[0]+'px,'+this._chesstransform[1]+'px) scale('+zoom2+')'; } else{ this.style.transform='scale('+zoom2+')'; } } this.queue(); }, $die:function(){ game.addVideo('die',this); game.broadcast(function(player){ player.$die(); },this); if(lib.config.die_move!='off'){ this.$dieflip(lib.config.die_move); } if(lib.element.player.$dieAfter){ lib.element.player.$dieAfter.call(this); } }, $dieflip:function(type){ var top0=ui.window.offsetHeight/2; var left0=ui.window.offsetWidth/2; var ratio=(left0-this.getLeft())/(top0-this.getTop()); var left=Math.abs(50*ratio/Math.sqrt(1+ratio*ratio)); var top=Math.abs(50/Math.sqrt(1+ratio*ratio)); if(left0-this.getLeft()>0) left=-left; if(top0-this.getTop()>0) top=-top; if(get.is.mobileMe(this)){ left=-Math.random()*5-10; top=Math.random()*5+10; } if(this._chesstransform){ left+=this._chesstransform[0]; top+=this._chesstransform[1]; } var transform='translate('+left+'px,'+top+'px) '+ 'rotate('+(Math.random()*20-10)+'deg) '; if(type=='flip'){ if(game.layout=='long'||game.layout=='long2'){ transform+='rotateY(180deg)'; } else{ transform+=((Math.random()-0.5<0)?'rotateX(180deg)':'rotateY(180deg)'); } } if(get.is.mobileMe(this)){ this.node.avatar.style.transform=transform; this.node.avatar2.style.transform=transform; this.style.transform=''; } else{ this.node.avatar.style.transform=''; this.node.avatar2.style.transform=''; this.style.transform=transform; } this.queue(false); }, $phaseJudge:function(card){ game.addVideo('phaseJudge',this,get.cardInfo(card)); var player=this; var clone=player.$throw(card); if(lib.config.low_performance&&card&&card.clone){ var waitingForTransition=get.time(); _status.waitingForTransition=waitingForTransition; card.clone.listenTransition(function(){ if(_status.waitingForTransition==waitingForTransition&&_status.paused){ game.resume(); } }); game.pause(); } else{ game.delay(); } } }, card:{ hasNature:function(nature,player){ return game.hasNature(this,nature,player); }, //只针对【杀】起效果 addNature:function(nature){ let natures=[]; if(!this.nature) this.nature=''; else{ natures.addArray(get.natureList(this.nature)); } natures.addArray(get.natureList(nature)); this.nature=get.nature(natures); this.classList.add(nature); let str=get.translation(this.nature)+'杀'; this.node.name.innerText=str; let name=get.name(this,false); do{ if(name=='sha'){ let _bg; for(const n of natures) if(lib.natureBg.has(n)) _bg=n; if(_bg){ this.node.image.setBackgroundImage(lib.natureBg.get(_bg)); break; } } this.node.image.setBackgroundImage('image/card/'+name+'.png'); } while(0); return this.nature; }, removeNature:function(nature){ if(!this.nature) return; let natures=get.natureList(this.nature); natures.remove(nature); if(!natures.length) delete this.nature; else this.nature=get.nature(natures); this.classList.remove(nature); let str=get.translation(this.nature)+'杀'; this.node.name.innerText=str; let name=get.name(this,false); do{ if(name=='sha'){ let _bg; for(const n of natures) if(lib.natureBg.has(n)) _bg=n; if(_bg){ this.node.image.setBackgroundImage(lib.natureBg.get(_bg)); break; } } this.node.image.setBackgroundImage('image/card/'+name+'.png'); } while(0); return this.nature; }, addGaintag:function(gaintag){ if(Array.isArray(gaintag)) this.gaintag=gaintag.slice(0); else this.gaintag.add(gaintag); var str=''; for(var gi=0;gi<this.gaintag.length;gi++){ var translate=get.translation(this.gaintag[gi]); if(translate!='invisible'){ str+=translate; if(gi<this.gaintag.length-1) str+=' '; } } this.node.gaintag.innerHTML=str; }, removeGaintag:function(tag){ if(tag===true){ if(this.gaintag&&this.gaintag.length||this.node.gaintag.innerHTML.length) this.addGaintag([]); } else if(this.hasGaintag(tag)){ this.gaintag.remove(tag); this.addGaintag(this.gaintag); } }, hasGaintag:function(tag){ return this.gaintag&&this.gaintag.contains(tag); }, init:function(card){ if(Array.isArray(card)){ if(card[2]=='huosha'){ card[2]='sha'; card[3]='fire'; } else if(card[2]=='leisha'){ card[2]='sha'; card[3]='thunder'; } // else if(card[2]=='kamisha'){ // card[2]='sha'; // card[3]='kami'; // } // else if(card[2]=='icesha'){ // card[2]='sha'; // card[3]='ice'; // } else if(card[2]=='cisha'){ card[2]='sha'; card[3]='stab'; } else if(card[2].length>3){ let prefix=card[2].slice(0,card[2].lastIndexOf('sha')); if(lib.nature.has(prefix)){ if(prefix.length+3==card[2].length){ card[2]='sha'; card[3]=prefix; } } if(card[2].startsWith('sha_')){ let suffix=card[2].slice(4); let natureList=suffix.split('_'); card[2]='sha'; card[3]=get.nature(natureList); } } } else if(typeof card=='object'){ card=[card.suit,card.number,card.name,card.nature]; } var cardnum=card[1]||''; if(parseInt(cardnum)==cardnum) cardnum=parseInt(cardnum); if(cardnum>0&&cardnum<14){ cardnum=['A','2','3','4','5','6','7','8','9','10','J','Q','K'][cardnum-1]; } if(!lib.card[card[2]]){ lib.card[card[2]]={}; } var info=lib.card[card[2]]; if(info.global&&!this.classList.contains('button')){ if(Array.isArray(info.global)){ while(info.global.length){ game.addGlobalSkill(info.global.shift()); } } else if(typeof info.global=='string'){ game.addGlobalSkill(info.global); } delete info.global; } if(this.name){ this.classList.remove('epic'); this.classList.remove('legend'); this.classList.remove('gold'); this.classList.remove('unique'); this.style.background=''; var subtype=get.subtype(this); if(subtype){ this.classList.remove(subtype); } } if(info.epic){ this.classList.add('epic'); } else if(info.legend){ this.classList.add('legend'); } else if(info.gold){ this.classList.add('gold'); } else if(info.unique){ this.classList.add('unique'); } var bg=card[2]; if(info.cardimage){ bg=info.cardimage; } var img=lib.card[bg].image; if(img){ if(img.startsWith('db:')){ img=img.slice(3); } else if(!img.startsWith('ext:')){ img=null; } } this.classList.remove('fullskin'); this.classList.remove('fullimage'); this.classList.remove('fullborder'); this.dataset.cardName=card[2]; this.dataset.cardType=info.type||''; this.dataset.cardSubype=info.subtype||''; this.dataset.cardMultitarget=info.multitarget?'1':'0'; this.node.name.dataset.nature=''; this.node.info.classList.remove('red'); if(!lib.config.hide_card_image&&lib.card[bg].fullskin){ this.classList.add('fullskin'); if(img){ if(img.startsWith('ext:')){ this.node.image.setBackgroundImage(img.replace(/^ext:/,'extension/')); } else{ this.node.image.setBackgroundDB(img); } } else{ if(lib.card[bg].modeimage){ this.node.image.setBackgroundImage('image/mode/'+lib.card[bg].modeimage+'/card/'+bg+'.png'); } else{ do{ let nature=card[3]; if(bg=='sha'&&typeof nature=='string'){ let natures=get.natureList(nature),_bg; for(const n of natures) if(lib.natureBg.has(n)) _bg=n; if(_bg){ this.node.image.setBackgroundImage(lib.natureBg.get(_bg)); break; } } this.node.image.setBackgroundImage('image/card/'+bg+'.png'); } while(0); } } } else if(lib.card[bg].image=='background'){ if(card[3]) this.node.background.setBackground(bg+'_'+get.natureList(card[3])[0],'card'); else this.node.background.setBackground(bg,'card'); } else if(lib.card[bg].fullimage){ this.classList.add('fullimage'); if(img){ if(img.startsWith('ext:')){ this.setBackgroundImage(img.replace(/^ext:/,'extension/')); this.style.backgroundSize='cover'; } else{ this.setBackgroundDB(img); } } else if(lib.card[bg].image){ if(lib.card[bg].image.startsWith('character:')){ this.setBackground(lib.card[bg].image.slice(10),'character'); } else{ this.setBackground(lib.card[bg].image); } } else{ var cardPack=lib.cardPack['mode_'+get.mode()]; if(Array.isArray(cardPack)&&cardPack.contains(bg)){ this.setBackground('mode/'+get.mode()+'/card/'+bg); } else{ this.setBackground('card/'+bg); } } } else if(lib.card[bg].fullborder){ this.classList.add('fullborder'); if(lib.card[bg].fullborder=='gold'){ this.node.name.dataset.nature='metalmm'; } else if(lib.card[bg].fullborder=='silver'){ this.node.name.dataset.nature='watermm'; } if(!this.node.avatar){ this.node.avatar=ui.create.div('.cardavatar'); this.insertBefore(this.node.avatar,this.firstChild); } if(!this.node.framebg){ this.node.framebg=ui.create.div('.cardframebg'); this.node.framebg.dataset.auto=lib.card[bg].fullborder; this.insertBefore(this.node.framebg,this.firstChild); } if(img){ if(img.startsWith('ext:')){ this.node.avatar.setBackgroundImage(img.replace(/^ext:/,'extension/')); this.node.avatar.style.backgroundSize='cover'; } else{ this.node.avatar.setBackgroundDB(img); } } else if(lib.card[bg].image){ if(lib.card[bg].image.startsWith('character:')){ this.node.avatar.setBackground(lib.card[bg].image.slice(10),'character'); } else{ this.node.avatar.setBackground(lib.card[bg].image); } } else{ var cardPack=lib.cardPack['mode_'+get.mode()]; if(Array.isArray(cardPack)&&cardPack.contains(bg)){ this.node.avatar.setBackground('mode/'+get.mode()+'/card/'+bg); } else{ this.node.avatar.setBackground('card/'+bg); } } } else if(lib.card[bg].image=='card'){ if(card[3]) this.setBackground(bg+'_'+get.natureList(card[3])[0],'card'); else this.setBackground(bg,'card'); } else if(typeof lib.card[bg].image=='string'&&!lib.card[bg].fullskin){ if(img){ if(img.startsWith('ext:')){ this.setBackgroundImage(img.replace(/^ext:/,'extension/')); this.style.backgroundSize='cover'; } else{ this.setBackgroundDB(img); } } else{ this.setBackground(lib.card[bg].image); } } else{ this.node.background.innerHTML=lib.translate[bg+'_cbg']||lib.translate[bg+'_bg']||get.translation(bg)[0]; // this.node.background.style.fontFamily=lib.config.card_font; if(this.node.background.innerHTML.length>1) this.node.background.classList.add('tight'); else this.node.background.classList.remove('tight'); } if(!lib.card[bg].fullborder&&this.node.avatar&&this.node.framebg){ this.node.avatar.remove(); this.node.framebg.remove(); delete this.node.avatar; delete this.node.framebg; } if(info.noname&&!this.classList.contains('button')){ this.node.name.style.display='none'; } if(info.color){ this.style.color=info.color; } if(info.textShadow){ this.style.textShadow=info.textShadow; } if(info.opacity){ this.node.info.style.opacity=info.opacity; this.node.name.style.opacity=info.opacity; } if(info.modinfo){ this.node.info.innerHTML=info.modinfo; } else{ this.node.info.innerHTML=get.translation(card[0])+'<span style="font-family:xinwei"> </span><span style="font-family:xinwei">'+cardnum+'</span>'; } if(info.addinfo){ if(!this.node.addinfo){ this.node.addinfo=ui.create.div('.range',this); } this.node.addinfo.innerHTML=info.addinfo; } else if(this.node.addinfo){ this.node.addinfo.remove(); delete this.node.addinfo; } if(card[0]=='heart'||card[0]=='diamond'){ this.node.info.classList.add('red'); } this.node.image.className='image'; var name=get.translation(card[2]); if(card[2]=='sha'){ name=''; let nature=card[3]; if(nature){ let natures=get.natureList(nature); natures.sort(lib.sort.nature); for(let nature of natures){ name+=lib.translate['nature_'+nature]||lib.translate[nature]||''; if(nature!='stab') this.node.image.classList.add(nature); } } name+='杀'; } this.node.name.innerHTML=name; if(name.length>=5){ this.node.name.classList.add('long'); if(name.length>=7){ this.node.name.classList.add('longlong'); } } this.node.name2.innerHTML=get.translation(card[0])+cardnum+' '+name; this.suit=card[0]; this.number=parseInt(card[1])||0; this.name=card[2]; this.classList.add('card'); if(card[3]){ let natures=get.natureList(card[3]); natures.forEach(n=>{if(n) this.classList.add(n)}); this.nature=natures.filter(n=>lib.nature.has(n)).sort(lib.sort.nature).join(lib.natureSeparator); } else if(this.nature){ this.classList.remove(this.nature); delete this.nature; } if(info.subtype) this.classList.add(info.subtype); if(this.inits){ for(var i=0;i<lib.element.card.inits.length;i++){ lib.element.card.inits[i](this); } } if(typeof info.init=='function') info.init(); this.node.range.innerHTML=''; switch(get.subtype(this)){ case 'equip1': var added=false; if(lib.card[this.name]&&lib.card[this.name].distance){ var dist=lib.card[this.name].distance; if(dist.attackFrom){ added=true; this.node.range.innerHTML='范围: '+(-dist.attackFrom+1); } } if(!added){ this.node.range.innerHTML='范围: 1'; } break; case 'equip3': if(info.distance&&info.distance.globalTo){ this.node.range.innerHTML='防御: '+info.distance.globalTo; this.node.name2.innerHTML+='+'; } break; case 'equip4': if(info.distance&&info.distance.globalFrom){ this.node.range.innerHTML='进攻: '+(-info.distance.globalFrom); this.node.name2.innerHTML+='-'; } break; } if(_status.connectMode&&!game.online&&lib.cardOL&&!this.cardid){ this.cardid=get.id(); lib.cardOL[this.cardid]=this; } if(!_status.connectMode&&!_status.video){ this.cardid=get.id(); } var tags=[]; if(Array.isArray(card[4])){ tags.addArray(card[4]); } if(this.cardid){ if(!_status.cardtag){ _status.cardtag={}; } for(var i in _status.cardtag){ if(_status.cardtag[i].contains(this.cardid)){ tags.add(i); } } if(tags.length){ var tagstr=' <span class="cardtag">'; for(var i=0;i<tags.length;i++){ var tag=tags[i]; if(!_status.cardtag[tag]){ _status.cardtag[tag]=[]; } _status.cardtag[tag].add(this.cardid); tagstr+=lib.translate[tag+'_tag']; //if(i<tags.length-1) tagstr+=' '; } tagstr+='</span>'; this.node.range.innerHTML+=tagstr; } } return this; }, updateTransform:function(bool,delay){ if(delay){ var that=this; setTimeout(function(){ that.updateTransform(that.classList.contains('selected')); },delay); } else{ if(_status.event.player!=game.me) return; if(this._transform&&this.parentNode&&this.parentNode.parentNode&& this.parentNode.parentNode.parentNode==ui.me&& (!_status.mousedown||_status.mouseleft)&& (!this.parentNode.parentNode.classList.contains('scrollh')||(game.layout=='long2'||game.layout=='nova'))){ if(bool){ this.style.transform=this._transform+' translateY(-20px)'; } else{ this.style.transform=this._transform||''; } } } }, aiexclude:function(){ _status.event._aiexclude.add(this); }, getSource:function(name){ if(this.name==name) return true; var info=lib.card[this.name]; if(info&&Array.isArray(info.source)){ return info.source.contains(name); } return false; }, moveDelete:function(player){ this.fixed=true; if(!this._listeningEnd||this._transitionEnded){ this.moveTo(player); var that=this; setTimeout(function(){ that.delete(); },200); } else{ this._onEndMoveDelete=player; } }, moveTo:function(player){ this.fixed=true; var dx,dy; if(this.classList.contains('center')){ var nx=[50,-52]; var ny=[50,-52]; nx=nx[0]*ui.arena.offsetWidth/100+nx[1]; ny=ny[0]*ui.arena.offsetHeight/100+ny[1]; dx=player.getLeft()+player.offsetWidth/2-52-nx; dy=player.getTop()+player.offsetHeight/2-52-ny; } else{ this.style.left=this.offsetLeft+'px'; this.style.top=this.offsetTop+'px'; dx=player.getLeft()+player.offsetWidth/2-52-this.offsetLeft; dy=player.getTop()+player.offsetHeight/2-52-this.offsetTop; } if(get.is.mobileMe(player)){ dx+=get.cardOffset(); if(ui.arena.classList.contains('oblongcard')){ dy-=16; } } if(this.style.transform&&this.style.transform!='none'&&this.style.transform.indexOf('translate')==-1){ this.style.transform+=' translate('+dx+'px,'+dy+'px)'; } else{ this.style.transform='translate('+dx+'px,'+dy+'px)'; } return this; }, copy:function(){ var node=this.cloneNode(true); node.style.transform=''; node.name=this.name; node.suit=this.suit; node.number=this.number; node.classList.remove('hidden'); node.classList.remove('start'); node.classList.remove('thrown'); node.classList.remove('selectable'); node.classList.remove('selected'); node.classList.remove('removing'); node.classList.remove('drawinghidden'); node.classList.remove('glows'); node.node={ name:node.querySelector('.name'), info:node.querySelector('.info'), intro:node.querySelector('.intro'), background:node.querySelector('.background'), image:node.querySelector('.image'), gaintag:node.querySelector('.gaintag'), } node.node.gaintag.innerHTML=''; var clone=true; var position; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='string') node.classList.add(arguments[i]); else if(get.objtype(arguments[i])=='div') position=arguments[i]; else if(typeof arguments[i]=='boolean') clone=arguments[i]; } node.moveTo=lib.element.card.moveTo; node.moveDelete=lib.element.card.moveDelete; if(clone) this.clone=node; if(position) position.appendChild(node); return node; }, uncheck:function(skill){ if(skill) this._uncheck.add(skill); this.classList.add('uncheck'); }, recheck:function(skill){ if(skill) this._uncheck.remove(skill); else this._uncheck.length=0; if(this._uncheck.length==0) this.classList.remove('uncheck'); }, discard:function(bool){ if(!this.destroyed){ ui.discardPile.appendChild(this); } this.fix(); this.classList.remove('glow'); if(bool===false){ ui.cardPile.insertBefore(this,ui.cardPile.childNodes[Math.floor(Math.random()*ui.cardPile.childNodes.length)]); } else{ if(_status.discarded){ _status.discarded.add(this); } } }, hasTag:function(tag){ if(this.cardid&&_status.cardtag&&_status.cardtag[tag]&&_status.cardtag[tag].contains(this.cardid)){ return true; } return false; }, hasPosition:function(){ return ['h','e','j','s','x'].contains(get.position(this)); }, isInPile:function(){ return ['c','d'].contains(get.position(this)); } }, button:{ exclude:function(){ if(_status.event.excludeButton==undefined){ _status.event.excludeButton=[]; } _status.event.excludeButton.add(this); } }, event:{ changeToZero:function(){ this.num=0; this.numFixed=true; }, finish:function(){ this.finished=true; }, putStepCache:function(key,value){ if(!this._stepCache){ this._stepCache = {}; } this._stepCache[key] = value; }, getStepCache:function(key){ if(!this._stepCache)return undefined; return this._stepCache[key]; }, clearStepCache:function(key){ if(key !== undefined && key !== null){ delete this._stepCache[key]; } delete this._stepCache; }, callFuncUseStepCache:function(prefix,func,params){ if(typeof func != 'function')return; if(_status.closeStepCache)return func.apply(null,params); var cacheKey = "["+prefix+"]"+get.paramToCacheKey.apply(null,params); var ret = this.getStepCache(cacheKey); if(ret === undefined || ret === null){ ret = func.apply(null,params); this.putStepCache(cacheKey,ret); } return ret; }, putTempCache:function(key1,key2,value){ if(!this._tempCache){ this._tempCache = {}; } if(!this._tempCache[key1]){ this._tempCache[key1] = {}; } this._tempCache[key1][key2] = value; return value; }, getTempCache:function(key1,key2){ if(!this._tempCache){ return undefined; } if(!this._tempCache[key1]){ return undefined; } return this._tempCache[key1][key2]; }, cancel:function(arg1,arg2,notrigger){ this.untrigger(arg1,arg2); this.finish(); if(notrigger!='notrigger'){ this.trigger(this.name+'Cancelled'); if(this.player&&lib.phaseName.contains(this.name)) this.player.getHistory('skipped').add(this.name)} }, neutralize:function(event){ this.untrigger(); this.finish(); this._neutralized=true; this.trigger('eventNeutralized'); this._neutralize_event=event||_status.event; }, unneutralize:function(){ this.untrigger(); delete this._neutralized; delete this.finished; if(this.type=='card'&&this.card&&this.name=='sha') this.directHit=true; }, goto:function(step){ this.step=step-1; }, redo:function(){ this.step--; }, setHiddenSkill:function(skill){ if(!this.player) return this; var hidden=this.player.hiddenSkills.slice(0); game.expandSkills(hidden); if(hidden.contains(skill)) this.set('hsskill',skill); return this; }, set:function(key,value){ if(arguments.length==1&&Array.isArray(arguments[0])){ for(var i=0;i<arguments[0].length;i++){ if(Array.isArray(arguments[0][i])){ this.set(arguments[0][i][0],arguments[0][i][1]); } } } else{ if(typeof key!='string'){ console.log('warning: using non-string object as event key'); console.log(key,value); console.log(_status.event); } this[key]=value; this._set.push([key,value]); } return this; }, setContent:function(item){ switch(typeof item){ case "object": case "function": this.content=lib.init.parsex(item); break; default: try{ if(!lib.element.content[item]._parsed){ lib.element.content[item]=lib.init.parsex(lib.element.content[item]); lib.element.content[item]._parsed=true; } } catch(_){ throw new Error(`Content ${item} may not exist.\nlib.element.content[${item}] = ${lib.element.content[item]}`); } this.content=lib.element.content[item]; break; } return this; }, getLogv:function(){ for(var i=1;i<=3;i++){ var event=this.getParent(i); if(event&&event.logvid) return event.logvid; } return null; }, send:function(){ this.player.send(function(name,args,set,event,skills){ game.me.applySkills(skills); var next=game.me[name].apply(game.me,args); for(var i=0;i<set.length;i++){ next.set(set[i][0],set[i][1]); } if(next._backupevent){ next.backup(next._backupevent); } next._modparent=event; game.resume(); },this.name,this._args||[],this._set, get.stringifiedResult(this.parent),get.skillState(this.player)); this.player.wait(); game.pause(); }, resume:function(){ delete this._cardChoice; delete this._targetChoice; delete this._skillChoice; }, getParent:function(level,forced){ var parent,historys=[]; if(this._modparent&&game.online){ parent=this._modparent; } else{ parent=this.parent; } var toreturn={}; if(typeof level=='string'&&forced==true){ toreturn=null; } if(!parent) return toreturn; if(typeof level=='number'){ for(var i=1;i<level;i++){ if(!parent) return toreturn; parent=parent.parent; } } else if(typeof level=='string'){ while(true){ if(!parent) return toreturn; historys.push(parent); if(parent.name==level) return parent; parent=parent.parent; if(historys.contains(parent)) return toreturn; } if(!parent) return toreturn; } if(toreturn===null){ return null; } return parent; }, getTrigger:function(){ return this.getParent()._trigger; }, getRand:function(name){ if(name){ if(!this._rand_map) this._rand_map={}; if(!this._rand_map[name]) this._rand_map[name]=Math.random(); return this._rand_map[name]; } if(!this._rand) this._rand=Math.random(); return this._rand; }, insert:function(func,map){ var next=game.createEvent(this.name+'Inserted',false,this); next.setContent(func); for(var i in map){ next.set(i,map[i]); } return next; }, insertAfter:function(func,map){ var next=game.createEvent(this.name+'Inserted',false,{next:[]}); this.after.push(next); next.setContent(func); for(var i in map){ next.set(i,map[i]); } return next; }, backup:function(skill){ this._backup={ filterButton:this.filterButton, selectButton:this.selectButton, filterTarget:this.filterTarget, selectTarget:this.selectTarget, filterCard:this.filterCard, selectCard:this.selectCard, position:this.position, forced:this.forced, fakeforce:this.fakeforce, _aiexclude:this._aiexclude, complexSelect:this.complexSelect, complexCard:this.complexCard, complexTarget:this.complexTarget, _cardChoice:this._cardChoice, _targetChoice:this._targetChoice, _skillChoice:this._skillChoice, ai1:this.ai1, ai2:this.ai2, filterOk:this.filterOk, } if(skill){ var info=get.info(skill); this.skill=skill; this._aiexclude=[]; if(typeof info.viewAs=='function'){ if(info.filterButton!=undefined) this.filterButton=get.filter(info.filterButton); if(info.selectButton!=undefined) this.selectButton=info.selectButton; if(info.filterTarget!=undefined) this.filterTarget=get.filter(info.filterTarget); if(info.selectTarget!=undefined) this.selectTarget=info.selectTarget; if(info.filterCard!=undefined){ if(info.ignoreMod) this.ignoreMod=true; this.filterCard2=get.filter(info.filterCard); this.filterCard=function(card,player,event){ var evt=event||_status.event; if(!evt.ignoreMod&&player){ var mod=game.checkMod(card,player,'unchanged','cardEnabled2',player); if(mod!='unchanged') return mod; } return get.filter(evt.filterCard2).apply(this,arguments); }; } if(info.filterOk==undefined){ this.filterOk=function(){ var evt=_status.event; var card=get.card(),player=get.player(); var filter=evt._backup.filterCard; if(filter&&!filter(card,player,evt)) return false; if(evt._backup.filterOk) return evt._backup.filterOk(); return true; }; } else this.filterOk=info.filterOk; if(info.selectCard!=undefined) this.selectCard=info.selectCard; if(info.position!=undefined) this.position=info.position; //if(info.forced!=undefined) this.forced=info.forced; if(info.complexSelect!=undefined) this.complexSelect=info.complexSelect; if(info.complexCard!=undefined) this.complexCard=info.complexCard; if(info.complexTarget!=undefined) this.complexTarget=info.complexTarget; if(info.ai1!=undefined) this.ai1=info.ai1; if(info.ai2!=undefined) this.ai2=info.ai2; } else if(info.viewAs){ if(info.filterButton!=undefined) this.filterButton=get.filter(info.filterButton); if(info.selectButton!=undefined) this.selectButton=info.selectButton; if(info.filterTarget!=undefined) this.filterTarget=get.filter(info.filterTarget); if(info.selectTarget!=undefined) this.selectTarget=info.selectTarget; if(info.filterCard!=undefined){ if(info.ignoreMod) this.ignoreMod=true; this.filterCard2=get.filter(info.filterCard); this.filterCard=function(card,player,event){ var evt=event||_status.event; if(!evt.ignoreMod&&player){ var mod=game.checkMod(card,player,'unchanged','cardEnabled2',player); if(mod!='unchanged') return mod; } return get.filter(evt.filterCard2).apply(this,arguments); }; } if(info.filterOk==undefined){ this.filterOk=function(){ var evt=_status.event; var card=get.card(),player=get.player(); var filter=evt._backup.filterCard; if(filter&&!filter(card,player,evt)) return false; if(evt._backup.filterOk) return evt._backup.filterOk() return true; }; } else this.filterOk=info.filterOk; if(info.selectCard!=undefined) this.selectCard=info.selectCard; if(info.position!=undefined) this.position=info.position; //if(info.forced!=undefined) this.forced=info.forced; if(info.complexSelect!=undefined) this.complexSelect=info.complexSelect; if(info.complexCard!=undefined) this.complexCard=info.complexCard; if(info.complexTarget!=undefined) this.complexTarget=info.complexTarget; if(info.ai1!=undefined) this.ai1=info.ai1; if(info.ai2!=undefined) this.ai2=info.ai2; } else{ this.filterButton=info.filterButton?get.filter(info.filterButton):undefined; this.selectButton=info.selectButton; this.filterTarget=info.filterTarget?get.filter(info.filterTarget):undefined; this.selectTarget=info.selectTarget; this.filterCard=info.filterCard?get.filter(info.filterCard):undefined; this.selectCard=info.selectCard; this.position=info.position; //this.forced=info.forced; this.complexSelect=info.complexSelect; this.complexCard=info.complexCard; this.complexTarget=info.complexTarget; if(info.ai1!=undefined) this.ai1=info.ai1; if(info.ai2!=undefined) this.ai2=info.ai2; this.filterOk=info.filterOk; } delete this.fakeforce; } delete this._cardChoice; delete this._targetChoice; delete this._skillChoice; }, restore:function(){ if(this._backup){ this.filterButton=this._backup.filterButton; this.selectButton=this._backup.selectButton; this.filterTarget=this._backup.filterTarget; this.selectTarget=this._backup.selectTarget; this.filterCard=this._backup.filterCard; this.selectCard=this._backup.selectCard; this.position=this._backup.position; this.forced=this._backup.forced; this.fakeforce=this._backup.fakeforce; this._aiexclude=this._backup._aiexclude; this.complexSelect=this._backup.complexSelect; this.complexCard=this._backup.complexCard; this.complexTarget=this._backup.complexTarget; this.ai1=this._backup.ai1; this.ai2=this._backup.ai2; this._cardChoice=this._backup._cardChoice; this._targetChoice=this._backup._targetChoice; this._skillChoice=this._backup._skillChoice; this.filterOk=this._backup.filterOk; } delete this.skill; delete this.ignoreMod; delete this.filterCard2; }, isMine:function(){ return (this.player&&this.player==game.me&&!_status.auto&&!this.player.isMad()&&!game.notMe); }, isOnline:function(){ return (this.player&&this.player.isOnline()); }, notLink:function(){ return this.getParent().name!='_lianhuan'&&this.getParent().name!='_lianhuan2'; }, isPhaseUsing:function(player){ var evt=this.getParent('phaseUse'); if(!evt||evt.name!='phaseUse') return false; return !player||player==evt.player; }, addTrigger:function(skill,player){ if(!player) return; var evt=this; while(true){ var evt=evt.getParent('arrangeTrigger'); if(!evt||evt.name!='arrangeTrigger'||!evt.map) return; if(typeof skill=='string') skill=[skill]; game.expandSkills(skill); var filter=function(content){ if(typeof content=='string') return content==triggername; return content.contains(triggername); }; var trigger=evt._trigger; var triggername=evt.triggername; var map=false; if(evt.doing&&evt.doing.player==player) map=evt.doing; else{ for(var i=0;i<evt.map.length;i++){ if(evt.map[i].player==player){map=evt.map[i];break;} } } if(!map) return; var func=function(skillx){ var info=lib.skill[skillx]; var bool=false; for(var i in info.trigger){ if(filter(info.trigger[i])){bool=true;break} } if(!bool) return; var priority=get.priority(skill); var toadd=[skillx,player,priority]; if(map.list2){ for(var i=0;i<map.list2.length;i++){ if(map.list2[i][0]==toadd[0]&&map.list2[i][1]==toadd[1]) return; } }; for(var i=0;i<map.list.length;i++){ if(map.list[i][0]==toadd[0]&&map.list[i][1]==toadd[1]) return; } map.list.add(toadd); map.list.sort(function(a,b){ return b[2]-a[2]; }); } for(var j=0;j<skill.length;j++){ func(skill[j]); } } }, trigger:function(name){ if(_status.video) return; if((this.name==='gain'||this.name==='lose')&&!_status.gameDrawed) return; if(name==='gameDrawEnd') _status.gameDrawed=true; if(name==='gameStart'){ lib.announce.publish('gameStart',{}); if(_status.brawl&&_status.brawl.gameStart){ _status.brawl.gameStart(); } if(lib.config.show_cardpile){ ui.cardPileButton.style.display=''; } _status.gameStarted=true; game.showHistory(); } if(!lib.hookmap[name]&&!lib.config.compatiblemode) return; if(!game.players||!game.players.length) return; var event=this; 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; } } if(!start) return; if(!game.players.contains(start)&&!game.dead.contains(start)){ start=game.findNext(start); } var list=[]; var list2=[]; var mapx=[]; var allbool=false; var roles=['player','source','target']; var listAdded; var mapxx; var addList=function(skill,player){ if(listAdded[skill]) return; if(player.forbiddenSkills[skill]) return; if(player.disabledSkills[skill]) return; listAdded[skill]=true; var info=lib.skill[skill]; var num=0; if(info.priority){ num=info.priority*100; } if(info.silent){ num++; } if(info.equipSkill) num-=30; if(info.ruleSkill) num-=30; if(info.firstDo){ list.push([skill,player,num]); list.sort(function(a,b){ return b[2]-a[2]; }); allbool=true; return; } else if(info.lastDo){ list2.push([skill,player,num]); list2.sort(function(a,b){ return b[2]-a[2]; }); allbool=true; return; } mapxx.list.push([skill,player,num]); mapxx.list.sort(function(a,b){ return b[2]-a[2]; }); allbool=true; }; var totalPopulation=game.players.length+game.dead.length+1; var player=start; var globalskill='global_'+name; var map=_status.connectMode?lib.playerOL:game.playerMap; for(var iwhile=0;iwhile<totalPopulation;iwhile++){ var id=player.playerid; var mapxx={ player:player, list:[], list2:[], }; listAdded={}; var notemp=player.skills.slice(0); for(var j in player.additionalSkills){ if(!j.startsWith('hidden:')) notemp.addArray(player.additionalSkills[j]); } for(var j in player.tempSkills){ if(notemp.contains(j)) continue; var expire=player.tempSkills[j]; if(expire===name|| (Array.isArray(expire)&&expire.contains(name))|| (typeof expire==='function'&&expire(event,player,name))){ delete player.tempSkills[j]; player.removeSkill(j); } else if(get.objtype(expire)==='object'){ for(var i=0;i<roles.length;i++){ if(expire[roles[i]]&&player===event[roles[i]]&& (expire[roles[i]]===name||(Array.isArray(expire[roles[i]])&&expire[roles[i]].contains(name)))){ delete player.tempSkills[j]; player.removeSkill(j); } } } } if(lib.config.compatiblemode){ (function(){ var skills=player.getSkills('invisible').concat(lib.skill.global); game.expandSkills(skills); for(var i=0;i<skills.length;i++){ var info=get.info(skills[i]); if(info&&info.trigger){ var trigger=info.trigger; var add=false; if(trigger.player){ if(typeof trigger.player==='string'){ if(trigger.player===name) add=true; } else if(trigger.player.contains(name)) add=true; } if(trigger.target){ if(typeof trigger.target==='string'){ if(trigger.target===name) add=true; } else if(trigger.target.contains(name)) add=true; } if(trigger.source){ if(typeof trigger.source==='string'){ if(trigger.source===name) add=true; } else if(trigger.source.contains(name)) add=true; } if(trigger.global){ if(typeof trigger.global==='string'){ if(trigger.global===name) add=true; } else if(trigger.global.contains(name)) add=true; } if(add){ addList(skills[i],player); } } } }()); } else{ for(var i=0;i<roles.length;i++){ var triggername=player.playerid+'_'+roles[i]+'_'+name; if(lib.hook[triggername]){ for(var j=0;j<lib.hook[triggername].length;j++){ addList(lib.hook[triggername][j],player); } } triggername=roles[i]+'_'+name; if(lib.hook.globalskill[triggername]){ for(var j=0;j<lib.hook.globalskill[triggername].length;j++){ addList(lib.hook.globalskill[triggername][j],player); } } } if(lib.hook.globalskill[globalskill]){ for(var j=0;j<lib.hook.globalskill[globalskill].length;j++){ addList(lib.hook.globalskill[globalskill][j],player); } } for(var i in lib.hook.globaltrigger[name]){ if(map[i]===player){ for(var j=0;j<lib.hook.globaltrigger[name][i].length;j++){ addList(lib.hook.globaltrigger[name][i][j],map[i]); } } } } mapx.push(mapxx); player=player.nextSeat; if(!player||player===start){ break; } } if(allbool){ var next=game.createEvent('arrangeTrigger',false,event); next.setContent('arrangeTrigger'); next.list=list; next.list2=list2; next.map=mapx; next._trigger=event; next.triggername=name; //next.starter=start; event._triggering=next; } }, untrigger:function(all,player){ if(typeof all=='undefined') all=true; var evt=this._triggering; if(all){ if(evt&&evt.map){ for(var i=0;i<evt.map.length;i++){ evt.map[i].list=[]; } evt.list=[]; if(evt.doing) evt.doing.list=[]; }; this._triggered=5; } else{ if(player){ this._notrigger.add(player); if(!evt||!evt.map) return; for(var i=0;i<evt.map.length;i++){ if(evt.map[i].player==player) evt.map[i].list.length=0; } } } } }, dialog:{ add:function(item,noclick,zoom){ if(typeof item=='string'){ if(item.startsWith('###')){ var items=item.slice(3).split('###'); this.add(items[0],noclick,zoom); this.addText(items[1],items[1].length<=20,zoom); } else if(noclick){ var strstr=item; item=ui.create.div('',this.content); item.innerHTML=strstr; } else{ item=ui.create.caption(item,this.content); } } else if(get.objtype(item)=='div'){ this.content.appendChild(item); } else if(get.itemtype(item)=='cards'){ var buttons=ui.create.div('.buttons',this.content); if(zoom) buttons.classList.add('smallzoom'); this.buttons=this.buttons.concat(ui.create.buttons(item,'card',buttons,noclick)); } else if(get.itemtype(item)=='players'){ var buttons=ui.create.div('.buttons',this.content); if(zoom) buttons.classList.add('smallzoom'); this.buttons=this.buttons.concat(ui.create.buttons(item,'player',buttons,noclick)); } else if(item[1]=='textbutton'){ ui.create.textbuttons(item[0],this,noclick); } else{ var buttons=ui.create.div('.buttons',this.content); if(zoom) buttons.classList.add('smallzoom'); this.buttons=this.buttons.concat(ui.create.buttons(item[0],item[1],buttons,noclick)); } if(this.buttons.length) { if(this.forcebutton!==false) this.forcebutton=true; if(this.buttons.length>3||(zoom&&this.buttons.length>5)){ this.classList.remove('forcebutton-auto'); } else if(!this.noforcebutton){ this.classList.add('forcebutton-auto'); } } ui.update(); return item; }, addText:function(str,center){ if(str&&str.startsWith('<div')) this.add(str); else if(center!==false){ this.add('<div class="text center">'+str+'</div>'); } else{ this.add('<div class="text">'+str+'</div>'); } return this; }, addSmall:function(item,noclick){ return this.add(item,noclick,true); }, addAuto:function(content){ if(content&&content.length>4&&!this._hovercustomed){ this.addSmall(content); } else{ this.add(content); } }, open:function(){ if(this.noopen) return; for(var i=0;i<ui.dialogs.length;i++){ if(ui.dialogs[i]==this){ this.show(); this.refocus(); ui.dialogs.remove(this); ui.dialogs.unshift(this); ui.update(); return this; } if(ui.dialogs[i].static) ui.dialogs[i].unfocus(); else ui.dialogs[i].hide(); } ui.dialog=this; var translate; if(lib.config.remember_dialog&&lib.config.dialog_transform&&!this.classList.contains('fixed')){ translate=lib.config.dialog_transform; this._dragtransform=translate; this.style.transform='translate('+translate[0]+'px,'+translate[1]+'px) scale(0.8)'; } else{ this.style.transform='scale(0.8)'; } this.style.transitionProperty='opacity,transform'; this.style.opacity=0; ui.arena.appendChild(this); ui.dialogs.unshift(this); ui.update(); ui.refresh(this); if(lib.config.remember_dialog&&lib.config.dialog_transform&&!this.classList.contains('fixed')){ this.style.transform='translate('+translate[0]+'px,'+translate[1]+'px) scale(1)'; } else{ this.style.transform='scale(1)'; } this.style.opacity=1; var that=this; setTimeout(function(){ that.style.transitionProperty=''; },500); return this; }, close:function(){ ui.dialogs.remove(this); this.delete(); if(ui.dialogs.length>0){ ui.dialog=ui.dialogs[0]; ui.dialog.show(); ui.dialog.refocus(); ui.update(); } // if(ui.arenalog){ // ui.arenalog.classList.remove('withdialog'); // } return this; }, setCaption:function(str){ this.querySelector('.caption').innerHTML=str; return this; } }, control:{ open:function(){ ui.control.insertBefore(this,_status.createControl||ui.confirm); ui.controls.unshift(this); if(this.childNodes.length){ this.style.transition='opacity 0.5s'; ui.refresh(this); this.style.transform='translateX(-'+(this.offsetWidth/2)+'px)'; this.style.opacity=1; ui.refresh(this); this.style.transition=''; } else{ this.animate('controlpressdownx',500); } ui.updatec(); return this; }, add:function(item){ var node=document.createElement('div'); this.appendChild(node); node.link=item; node.innerHTML=get.translation(item); node.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.control); }, close:function(){ this.animate('controlpressdownx',500); ui.controls.remove(this); this.delete(); setTimeout(ui.updatec,100); if(ui.confirm==this) delete ui.confirm; if(ui.skills==this) delete ui.skills; if(ui.skills2==this) delete ui.skills2; if(ui.skills3==this) delete ui.skills3; }, replace:function(){ // this.animate('controlpressdownx',500); if(this.replaceTransition===false){ this.style.transitionProperty='none'; ui.refresh(this); } while(this.childNodes.length) this.firstChild.remove(); var i,controls; if(Array.isArray(arguments[0])) controls=arguments[0]; else controls=arguments; delete this.custom; for(i=0;i<controls.length;i++){ if(typeof controls[i]=='function'){ this.custom=controls[i]; } else{ this.add(controls[i]); } } if(this.childNodes.length){ var width=0; for(i=0;i<this.childNodes.length;i++) width+=this.childNodes[i].offsetWidth; ui.refresh(this); this.style.width=width+'px'; } ui.updatec(); if(this.replaceTransition===false){ var that=this; setTimeout(function(){ that.style.transitionProperty=''; },200); } return this; } }, client:{ send:function(){ if(this.closed) return this; var args=Array.from(arguments); if(typeof args[0]=='function'){ args.unshift('exec'); } for(var i=1;i<args.length;i++){ args[i]=get.stringifiedResult(args[i]); } try{ this.ws.send(JSON.stringify(args)); } catch(e){ this.ws.close(); } return this; }, close:function(){ lib.node.clients.remove(this); lib.node.observing.remove(this); if(ui.removeObserve&&!lib.node.observing.length){ ui.removeObserve.remove(); delete ui.removeObserve; } this.closed=true; if(_status.waitingForPlayer){ for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].playerid==this.id){ game.connectPlayers[i].uninitOL(); delete game.connectPlayers[i].playerid; } } if(game.onlinezhu==this.id){ game.onlinezhu=null; } game.updateWaiting(); } else if(lib.playerOL[this.id]){ var player=lib.playerOL[this.id]; player.setNickname(player.nickname+' - 离线'); game.broadcast(function(player){ player.setNickname(player.nickname+' - 离线'); },player); player.unwait('ai'); } if(window.isNonameServer){ document.querySelector('#server_count').innerHTML=lib.node.clients.length; } return this; } }, nodews:{ send:function(message){ game.send('server','send',this.wsid,message); }, on:function(type,func){ this['on'+type]=func; }, close:function(){ game.send('server','close',this.wsid); } }, ws:{ onopen:function(){ if(_status.connectCallback){ _status.connectCallback(true); delete _status.connectCallback; } }, onmessage:function(messageevent){ if(messageevent.data=='heartbeat'){ this.send('heartbeat'); return; } var message; try{ message=JSON.parse(messageevent.data); if(!Array.isArray(message)|| typeof lib.message.client[message[0]]!=='function'){ throw('err'); } for(var i=1;i<message.length;i++){ message[i]=get.parsedResult(message[i]); } } catch(e){ console.log(e); console.log('invalid message: '+messageevent.data); return; } lib.message.client[message.shift()].apply(null,message); }, onerror:function(e){ if(this._nocallback) return; if(_status.connectCallback){ _status.connectCallback(false); delete _status.connectCallback; } else{ alert('连接失败'); } }, onclose:function(){ if(this._nocallback) return; if(_status.connectCallback){ _status.connectCallback(false); delete _status.connectCallback; } if(game.online||game.onlineroom){ if((game.servermode||game.onlinehall)&&_status.over){ } else{ localStorage.setItem(lib.configprefix+'directstart',true); game.reload(); } } else{ // game.saveConfig('reconnect_info'); } game.online=false; game.ws=null; } } }, card:{ list:[], cooperation_damage:{ fullskin:true, }, cooperation_draw:{ fullskin:true, cardimage:'cooperation_damage', }, cooperation_discard:{ fullskin:true, cardimage:'cooperation_damage', }, cooperation_use:{ fullskin:true, cardimage:'cooperation_damage', }, pss_paper:{ type:'pss', fullskin:true, }, pss_scissor:{ type:'pss', fullskin:true, }, pss_stone:{ type:'pss', fullskin:true, }, feichu_equip1:{ type:"equip", subtype:"equip1", }, feichu_equip2:{ type:"equip", subtype:"equip2", }, feichu_equip3:{ type:"equip", subtype:"equip3", }, feichu_equip4:{ type:"equip", subtype:"equip4", }, feichu_equip5:{ type:"equip", subtype:"equip5", }, zhengsu_leijin:{}, zhengsu_mingzhi:{}, zhengsu_bianzhen:{}, disable_judge:{}, group_wei:{fullskin:true}, group_shu:{fullskin:true}, group_wu:{fullskin:true}, group_qun:{fullskin:true}, group_key:{fullskin:true}, group_jin:{fullskin:true}, db_atk1:{ type:'db_atk', fullimage:true, }, db_atk2:{ type:'db_atk', fullimage:true, }, db_def1:{ type:'db_def', fullimage:true, }, db_def2:{ type:'db_def', fullimage:true, }, }, filter:{ all:()=>true, none:()=>false, //Check if the card does not count toward the player's hand limit //检测此牌是否不计入此角色的手牌上限 ignoredHandcard:(card,player)=>game.checkMod(card,player,false,'ignoredHandcard',player), //Check if the card is giftable //检测此牌是否可赠予 cardGiftable:(card,player,target,strict)=>{ const mod=game.checkMod(card,player,target,'unchanged','cardGiftable',player); if(!mod||strict&&(mod=='unchanged'&&(get.position(card)!='h'||!get.cardtag(card,'gifts'))||player==target)) return false; return get.type(card,false)!='equip'||target.canEquip(card,true); }, //Check if the card is recastable //检查此牌是否可重铸 cardRecastable:(card,player,source,strict)=>{ if(typeof player=='undefined') player=get.owner(card); const mod=game.checkMod(card,player,source,'unchanged','cardRecastable',player); if(!mod) return false; if(strict&&mod=='unchanged'){ if(get.position(card)!='h') return false; const info=get.info(card),recastable=info.recastable||info.chongzhu; return Boolean(typeof recastable=='function'?recastable(_status.event,player):recastable); } return true; }, //装备栏相关 canBeReplaced:function(card,player){ var mod=game.checkMod(card,player,'unchanged','canBeReplaced',player); if(mod!='unchanged') return mod; return true; }, //装备栏 END buttonIncluded:function(button){ return !(_status.event.excludeButton&&_status.event.excludeButton.contains(button)); }, filterButton:function(button){ return true; }, cardSavable:function(card,player,target){ if(get.itemtype(card)=='card'){ var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); if(mod2!='unchanged') return mod2; } var mod=game.checkMod(card,player,target,'unchanged','cardSavable',player); if(mod!='unchanged') return mod; var savable=get.info(card).savable; if(typeof savable=='function') savable=savable(card,player,target); return savable; }, filterTrigger:function(event,player,name,skill){ if(player._hookTrigger){ for(var i=0;i<player._hookTrigger.length;i++){ var info=lib.skill[player._hookTrigger[i]].hookTrigger; if(info){ if(info.block&&info.block(event,player,name,skill)){ return false; } } } } var fullskills=game.expandSkills(player.getSkills(false).concat(lib.skill.global)); var info=get.info(skill); if(((info&&info.noHidden)||get.mode()!='guozhan')&&!fullskills.contains(skill)){ return false; } if(!info.trigger) return false; var bool=false; var has=function(obj){ if(typeof obj=='string') return obj==name; else if(obj.contains(name)) return true; return false; } for(var i in info.trigger){ if((i=='global'||player==event[i])&&has(info.trigger[i])){ bool=true;break; } } if(!bool) return false; if(info.filter&&!info.filter(event,player,name)){ return false; } if(event._notrigger.contains(player)&&!lib.skill.global.contains(skill)){ return false; } if(typeof info.usable=='number'&&player.hasSkill('counttrigger')&& player.storage.counttrigger&&player.storage.counttrigger[skill]>=info.usable){ return false; } if(info.round&&(info.round-(game.roundNumber-player.storage[skill+'_roundcount'])>0)){ return false; } return true; }, characterDisabled:function(i,libCharacter){ if(!lib.character[i]||lib.character[i][4]&&lib.character[i][4].contains('forbidai')) return true; if(lib.character[i][4]&&lib.character[i][4].contains('unseen')) return true; if(lib.config.forbidai.contains(i)) return true; if(lib.characterFilter[i]&&!lib.characterFilter[i](get.mode())) return true; if(_status.connectMode){ if(lib.configOL.banned.contains(i)||lib.connectBanned.contains(i)) return true; var double_character=false; if(lib.configOL.mode=='guozhan'){ double_character=true; } else if(lib.configOL.double_character&&(lib.configOL.mode=='identity'||lib.configOL.mode=='stone')){ double_character=true; } else if(lib.configOL.double_character_jiange&&(lib.configOL.mode=='versus'&&_status.mode=='jiange')){ double_character=true; } if(double_character&&lib.config.forbiddouble.contains(i)){ return true; } // if(lib.configOL.ban_weak){ // if(lib.config.replacecharacter[i]&&libCharacter&&libCharacter[lib.config.replacecharacter[i]]) return true; // if(lib.config.forbidall.contains(i)) return true; // if(!double_character&&get.rank(i,true)<=2){ // return true; // } // } // if(lib.configOL.ban_strong&&get.rank(i,true)>=8){ // return true; // } } else{ if(lib.config.banned.contains(i)) return true; var double_character=false; if(get.mode()=='guozhan'){ double_character=true; } else if(get.config('double_character')&&(lib.config.mode=='identity'||lib.config.mode=='stone')){ double_character=true; } else if(get.config('double_character_jiange')&&(lib.config.mode=='versus'&&_status.mode=='jiange')){ double_character=true; } if(double_character&&lib.config.forbiddouble.contains(i)){ return true; } // if(get.config('ban_weak')){ // if(lib.config.replacecharacter[i]&&lib.character[lib.config.replacecharacter[i]]) return true; // if(lib.config.forbidall.contains(i)) return true; // if(!double_character&&get.rank(i,true)<=2){ // return true; // } // } // if(get.config('ban_strong')&&get.rank(i,true)>=8){ // return true; // } } }, characterDisabled2:function(i){ var info=lib.character[i]; if(!info) return true; if(info[4]){ if(info[4].contains('boss')) return true; if(info[4].contains('hiddenboss')) return true; if(info[4].contains('minskin')) return true; if(info[4].contains('unseen')) return true; if(info[4].contains('forbidai')&&(!_status.event.isMine||!_status.event.isMine())) return true; if(lib.characterFilter[i]&&!lib.characterFilter[i](get.mode())) return true; } return false; }, skillDisabled:function(skill){ if(!lib.translate[skill]||!lib.translate[skill+'_info']) return true; var info=lib.skill[skill]; if(info&&!info.unique&&!info.temp&&!info.sub&&!info.fixed&&!info.vanish){ return false; } return true; }, cardEnabled:function(card,player,event){ if(player==undefined) player=_status.event.player; if(!player) return false; if(get.itemtype(card)=='card'){ var mod2=game.checkMod(card,player,event,'unchanged','cardEnabled2',player); if(mod2!='unchanged') return mod2; } card=get.autoViewAs(card); if(event==='forceEnable'){ var mod=game.checkMod(card,player,event,'unchanged','cardEnabled',player); if(mod!='unchanged') return mod; return true; } else{ var filter=get.info(card).enable; if(!filter) return; var mod=game.checkMod(card,player,event,'unchanged','cardEnabled',player); if(mod!='unchanged') return mod; if(typeof filter=='boolean') return filter; if(typeof filter=='function') return filter(card,player,event); } }, cardRespondable:function(card,player,event){ event=event||_status.event; if(event.name!='chooseToRespond') return true; var source=event.getParent().player; if(source&&source!=player){ if(source.hasSkillTag('norespond',false,[card,player,event],true)){ return false; } } if(player==undefined) player=_status.event.player; if(get.itemtype(card)=='card'){ var mod2=game.checkMod(card,player,event,'unchanged','cardEnabled2',player); if(mod2!='unchanged') return mod2; } var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); if(mod!='unchanged') return mod; return true; }, cardUsable2:function(card,player,event){ card=get.autoViewAs(card); var info=get.info(card); if(info.updateUsable=='phaseUse'){ event=event||_status.event; if(event.type=='chooseToUse_button') event=event.getParent(); if(player!=_status.event.player) return true; if(event.getParent().name!='phaseUse') return true; if(event.getParent().player!=player) return true; } var num=info.usable; if(typeof num=='function') num=num(card,player); num=game.checkMod(card,player,num,'cardUsable',player); if(typeof num!='number') return true; else return(player.countUsed(card)<num); }, cardUsable:function(card,player,event){ card=get.autoViewAs(card); var info=get.info(card); event=event||_status.event; if(event.type=='chooseToUse_button') event=event.getParent(); if(player!=_status.event.player) return true; if(info.updateUsable=='phaseUse'){ if(event.getParent().name!='phaseUse') return true; if(event.getParent().player!=player) return true; } event.addCount_extra=true; var num=info.usable; if(typeof num=='function') num=num(card,player); num=game.checkMod(card,player,num,'cardUsable',player); if(typeof num!='number'){ return (typeof num=='boolean')?num:true; } if(player.countUsed(card)<num) return true; if(game.hasPlayer(function(current){ return game.checkMod(card,player,current,false,'cardUsableTarget',player); })){ return true; } return false; }, cardDiscardable:function(card,player,event){ event=event||_status.event; if(typeof event!='string') event=event.getParent().name; var mod=game.checkMod(card,player,event,'unchanged','cardDiscardable',player); if(mod!='unchanged') return mod; return true; }, canBeDiscarded:function(card,player,target,event){ event=event||_status.event; if(typeof event!='string') event=event.getParent().name; var mod=game.checkMod(card,player,target,event,'unchanged','canBeDiscarded',target); if(mod!='unchanged') return mod; return true; }, canBeGained:function(card,player,target,event){ event=event||_status.event; if(typeof event!='string') event=event.getParent().name; var mod=game.checkMod(card,player,target,event,'unchanged','canBeGained',target); if(mod!='unchanged') return mod; return true; }, cardAiIncluded:function(card){ if(_status.event.isMine()) return true; return (_status.event._aiexclude.contains(card)==false); }, filterCard:function(card,player,event){ var info=get.info(card); //if(info.toself&&!lib.filter.targetEnabled(card,player,player)) return false; if(player==undefined) player=_status.event.player; if(!lib.filter.cardEnabled(card,player,event)||!lib.filter.cardUsable(card,player,event)) return false; if(info.notarget) return true; var range; var select=get.copy(info.selectTarget); if(select==undefined){ if(info.filterTarget==undefined) return true; range=[1,1]; } else if(typeof select=='number') range=[select,select]; else if(get.itemtype(select)=='select') range=select; else if(typeof select=='function') range=select(card,player); game.checkMod(card,player,range,'selectTarget',player); if(!range||range[1]!=-1) return true; var filterTarget=(event&&event.filterTarget)?event.filterTarget:lib.filter.filterTarget; return game.hasPlayer(function(current){ return filterTarget(card,player,current); }); }, targetEnabledx:function(card,player,target){ if(!card) return false; var event=_status.event; if(event._backup&&event._backup.filterCard==lib.filter.filterCard&&(!lib.filter.cardEnabled(card,player,event)||!lib.filter.cardUsable(card,player,event))) return false; if(event.addCount_extra){ if(!lib.filter.cardUsable2(card,player)&&!game.checkMod(card,player,target,false,'cardUsableTarget',player)) return false; } var info=get.info(card); if(info.singleCard&&info.filterAddedTarget&&ui.selected.targets.length) return Boolean(info.filterAddedTarget(card,player,target,ui.selected.targets[ui.selected.targets.length-1])); return lib.filter.targetEnabled.apply(this,arguments); }, targetEnabled:function(card,player,target){ if(!card) return false; var info=get.info(card); var filter=info.filterTarget; if(!info.singleCard||ui.selected.targets.length==0){ var mod=game.checkMod(card,player,target,'unchanged','playerEnabled',player); if(mod!='unchanged') return mod; var mod=game.checkMod(card,player,target,'unchanged','targetEnabled',target); if(mod!='unchanged') return mod; } if(typeof filter=='boolean') return filter; if(typeof filter=='function') return Boolean(filter(card,player,target)); }, targetEnabled2:function(card,player,target){ if(lib.filter.targetEnabled(card,player,target)) return true; if(!card) return false; if(game.checkMod(card,player,target,'unchanged','playerEnabled',player)==false) return false; if(game.checkMod(card,player,target,'unchanged','targetEnabled',target)==false) return false; var filter=get.info(card).modTarget; if(typeof filter=='boolean') return filter; if(typeof filter=='function') return Boolean(filter(card,player,target)); return false; }, targetEnabled3:function(card,player,target){ if(!card) return false; var info=get.info(card); if(info.filterTarget==true) return true; if(typeof info.filterTarget=='function'&&info.filterTarget(card,player,target)) return true; if(info.modTarget==true) return true; if(typeof info.modTarget=='function'&&info.modTarget(card,player,target)) return true; return false; }, targetInRange:function(card,player,target){ var info=get.info(card); var range=info.range; var outrange=info.outrange; if(range==undefined&&outrange==undefined) return true; var mod=game.checkMod(card,player,target,'unchanged','targetInRange',player); var extra=0; if(mod!='unchanged'){ if(typeof mod=='boolean') return mod; if(typeof mod=='number') extra=mod; } if(typeof info.range=='function') return info.range(card,player,target); if(player.hasSkill('undist')||target.hasSkill('undist')) return false; for(var i in range){ if(i=='attack'){ var range2=player.getAttackRange(); if(range2<=0) return false; var distance=get.distance(player,target)+extra; if(range[i]<=distance-range2) return false; } else{ var distance=get.distance(player,target,i)+extra; if(range[i]<distance) return false; } } for(var i in outrange){ if(i=='attack'){ var range2=player.getAttackRange(); if(range2<=0) return false; var distance=get.distance(player,target)+extra; if(outrange[i]>distance-range2+1) return false; } else{ var distance=get.distance(player,target,i)+extra; if(outrange[i]>distance) return false; } } return true; }, filterTarget:function(card,player,target){ return (lib.filter.targetEnabledx(card,player,target)&& lib.filter.targetInRange(card,player,target)); }, filterTarget2:function(card,player,target){ return (lib.filter.targetEnabled2(card,player,target)&& lib.filter.targetInRange(card,player,target)); }, notMe:function(card,player,target){ return player!=target; }, isMe:function(card,player,target){ return player==target; }, attackFrom:function(card,player,target){ return get.distance(player,target,'attack')<=1; }, globalFrom:function(card,player,target){ return get.distance(player,target)<=1; }, selectCard:function(){ return [1,1]; }, selectTarget:function(card,player){ if(!card) card=get.card(); if(!player) player=get.player(); if(card==undefined) return; var range,info=get.info(card); var select=get.copy(info.selectTarget); if(select==undefined){ if(info.filterTarget==undefined) return [0,0]; range=[1,1]; } else if(typeof select=='number') range=[select,select]; else if(get.itemtype(select)=='select') range=select; else if(typeof select=='function') range=select(card,player); game.checkMod(card,player,range,'selectTarget',player); if(info.singleCard&&info.filterAddedTarget) return [range[0]*2,range[1]*2]; return range; }, judge:function(card,player,target){ return target.canAddJudge(card); }, autoRespondSha:function(){ return !this.player.hasSha(true); }, autoRespondShan:function(){ return !this.player.hasShan(); }, wuxieSwap:function(event){ if(event.type=='wuxie'){ if(ui.wuxie&&ui.wuxie.classList.contains('glow')){ return true; } if(ui.tempnowuxie&&ui.tempnowuxie.classList.contains('glow')&&event.state>0){ var triggerevent=event.getTrigger(); if(triggerevent){ if(ui.tempnowuxie._origin==triggerevent.parent.id){ return true; } } else if(ui.tempnowuxie._origin==_status.event.id2){ return true; } } if(lib.config.wuxie_self){ var tw=event.info_map; if(tw.player&&tw.player.isUnderControl(true)&&!tw.player.hasSkillTag('noautowuxie')&& (!tw.targets||tw.targets.length<=1)&&!tw.noai){ return true; } } } } }, sort:{ nature:function(a,b){ return (lib.nature.get(b)||0)-(lib.nature.get(a)||0); }, group:function(a,b){ const groupSort=function(group){ let base=0; if(group=='wei') return base; if(group=='shu') return base+1; if(group=='wu') return base+2; if(group=='qun') return base+3; if(group=='jin') return base+4; if(group=='key') return base+5; if(group=='western') return base+6; if(group=='shen') return base+7; if(group=='double') return base+7; return base+9; } return groupSort(a)-groupSort(b); }, character:function(a,b){ const groupSort=function(name){ const info=get.character(name); if(!info) return 7; let base=0; if(get.is.double(name,true)) base=9; const group=info[1]; if(group=='shen') return base-1; if(group=='wei') return base; if(group=='shu') return base+1; if(group=='wu') return base+2; if(group=='qun') return base+3; if(group=='jin') return base+4; if(group=='key') return base+5; if(group=='western') return base+6; return base+7; } const del=groupSort(a)-groupSort(b); if(del!=0) return del; let aa=a,bb=b; if(a.includes('_')){ a=a.slice(a.indexOf('_')+1); } if(b.includes('_')){ b=b.slice(b.indexOf('_')+1); } if(a!=b){ return a>b?1:-1; } return aa>bb?1:-1; }, card:function(a,b){ var typeSort=function(name){ var type=get.type(name); if(!type) return 10; if(type=='basic') return -1; if(type=='trick') return 0; if(type=='delay') return 1; if(type=='equip'){ var type2=get.subtype(name); if(type2&&type2.slice) return 1+parseInt(type2.slice(5)||7); return 8.5 } return 9; } var del=typeSort(a)-typeSort(b); if(del!=0) return del; var aa=a,bb=b; if(a.includes('_')){ a=a.slice(a.indexOf('_')+1); } if(b.includes('_')){ b=b.slice(b.indexOf('_')+1); } if(a!=b){ return a>b?1:-1; } return aa>bb?1:-1; }, random:function(){ return (Math.random()-0.5); }, seat:function(a,b){ var player=lib.tempSortSeat||_status.event.player; var delta=get.distance(player,a,'absolute')-get.distance(player,b,'absolute'); if(delta) return delta; delta=parseInt(a.dataset.position)-parseInt(b.dataset.position); if(player.side==game.me.side) return delta; return -delta; }, position:function(a,b){ return parseInt(a.dataset.position)-parseInt(b.dataset.position); }, priority:function(a,b){ var i1=get.info(a[0]),i2=get.info(b[0]); if(i1.priority==undefined) i1.priority=0; if(i2.priority==undefined) i2.priority=0; if(i1.priority==i2.priority){ if(i1.forced==undefined&&i2.forced==undefined) return 0; if(i1.forced&&i2.forced) return 0; if(i1.forced) return 1; if(i2.forced) return -1; } return i2.priority-i1.priority; }, number:function(a,b){ return get.number(a)-get.number(b); }, number2:function(a,b){ return get.number(b)-get.number(a); }, capt:function(a,b){ 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; }, name:function(a,b){ if(a>b) return 1; if(a<b) return -1; return 0; } }, skill:{ expandedSlots:{ markimage:'image/card/expandedSlots.png', intro:{ markcount:function(storage,player){ var all=0,storage=player.expandedSlots; if(!storage) return 0; for(var key in storage){ var num=storage[key]; if(typeof num=='number'&&num>0){ all+=num; } } return all; }, content:function(storage,player){ storage=player.expandedSlots; if(!storage) return '当前没有扩展装备栏'; var keys=Object.keys(storage).sort(); var str=''; for(var key of keys){ var num=storage[key]; if(typeof num=='number'&&num>0){ str+='<li>'+get.translation(key)+'栏:'+num+'个<br>' } } if(str.length) return str.slice(0,str.length-4); return '当前没有扩展装备栏'; }, }, }, charge:{ markimage:'image/card/charge.png', intro:{ content:'当前蓄力点数:#', }, }, cooperation:{ charlotte:true, trigger:{ global:['phaseAfter','dieAfter'], }, forced:true, lastDo:true, filter:function(event,player){ if(event.name=='die'&&event.player.isAlive()) return false; var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.target==event.player) return true; } return false; }, content:function(){ for(var i=0;i<player.storage.cooperation.length;i++){ var info=player.storage.cooperation[i]; if(info.target==trigger.player){ player.removeCooperation(info); i--; } } }, onremove:function(player,skill){ var storage=player.getStorage(skill); var reasons=[]; for(var i of storage) reasons.add(i.type); for(var i of reasons) player.removeSkill(skill+'_'+i); delete player.storage[i]; }, subSkill:{ damage:{ mark:true, trigger:{global:'damage'}, forced:true, charlotte:true, popup:false, firstDo:true, filter:function(event,player){ if(!event.source) return false; var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='damage'&&(event.source==player||event.source==info.target)) return true; } return false; }, checkx:(info)=>(info.damage&&info.damage>3), content:function(){ var source=trigger.source; var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='damage'&&(source==player||source==info.target)){ if(!info.damage) info.damage=0; info.damage+=trigger.num; } } player.markSkill('cooperation_damage'); }, marktext:'仇', intro:{ name:'协力 - 同仇', markcount:function(storage,player){ return Math.max.apply(Math,player.getStorage('cooperation').map(function(info){ return info.damage||0; })); }, content:function(storage,player){ var str='',storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='damage'){ str+='<br><li>协力角色:'+get.translation(info.target); str+='<br><li>协力原因:'+get.translation(info.reason); str+='<br><li>协力进度:' var num=(info.damage||0); str+=num; str+='/4'; str+=(num>3?' (已完成)':' (未完成)'); str+='<br> '; } } return str.slice(4,str.length-6); }, }, }, draw:{ mark:true, trigger:{global:'gainAfter'}, forced:true, charlotte:true, popup:false, firstDo:true, filter:function(event,player){ if(event.getParent().name!='draw') return false; var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='draw'&&(event.player==player||event.player==info.target)) return true; } return false; }, checkx:(info)=>(info.draw&&info.draw>7), content:function(){ var source=trigger.player; var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='draw'&&(source==player||source==info.target)){ if(!info.draw) info.draw=0; info.draw+=trigger.cards.length; } } player.markSkill('cooperation_draw'); }, marktext:'进', intro:{ name:'协力 - 并进', markcount:function(storage,player){ return Math.max.apply(Math,player.getStorage('cooperation').map(function(info){ return info.draw||0; })); }, content:function(storage,player){ var str='',storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='draw'){ str+='<br><li>协力角色:'+get.translation(info.target); str+='<br><li>协力原因:'+get.translation(info.reason); str+='<br><li>协力进度:' var num=(info.draw||0); str+=num; str+='/8'; str+=(num>7?' (已完成)':' (未完成)'); str+='<br> '; } } return str.slice(4,str.length-6); }, }, }, discard:{ mark:true, trigger:{global:'loseAfter'}, forced:true, charlotte:true, popup:false, firstDo:true, filter:function(event,player){ if(event.type!='discard') return false; var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='discard'&&(event.player==player||event.player==info.target)) return true; } return false; }, checkx:(info)=>(info.discard&&info.discard.length>3), content:function(){ var source=trigger.player; var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='discard'&&(source==player||source==info.target)){ if(!info.discard) info.discard=[]; for(var i of trigger.cards2){ var suit=get.suit(i,player); if(lib.suit.contains(suit)) info.discard.add(suit); } } } player.markSkill('cooperation_discard'); }, marktext:'财', intro:{ name:'协力 - 疏财', markcount:function(storage,player){ return Math.max.apply(Math,player.getStorage('cooperation').map(function(info){ return info.discard?info.discard.length:0; })); }, content:function(storage,player){ var str='',storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='discard'){ str+='<br><li>协力角色:'+get.translation(info.target); str+='<br><li>协力原因:'+get.translation(info.reason); str+='<br><li>进度:'; var suits=info.discard||[]; var suits2=[['spade','♠','♤'],['heart','♥','♡'],['club','♣','♧'],['diamond','♦','♢']]; for(var i of suits2){ str+=(suits.contains(i[0])?i[1]:i[2]); } str+=(suits.length>3?' (已完成)':' (未完成)'); str+='<br> '; } } return str.slice(4,str.length-6); }, }, }, use:{ mark:true, trigger:{global:'useCard1'}, forced:true, charlotte:true, popup:false, firstDo:true, filter:function(event,player){ var suit=get.suit(event.card); if(!lib.suit.contains(suit)) return false; var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='use' &&(event.player==player||event.player==info.target)&& (!info.used||!info.used.contains(suit))) return true; } return false; }, checkx:(info)=>(info.used&&info.used.length>3), content:function(){ var source=trigger.player,suit=get.suit(trigger.card); var storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='use'&&(source==player||source==info.target)){ if(!info.used) info.used=[]; info.used.add(suit); } } player.markSkill('cooperation_use'); }, marktext:'戮', intro:{ name:'协力 - 戮力', markcount:function(storage,player){ return Math.max.apply(Math,player.getStorage('cooperation').map(function(info){ return info.used?info.used.length:0; })); }, content:function(storage,player){ var str='',storage=player.getStorage('cooperation'); for(var info of storage){ if(info.type=='use'){ str+='<br><li>协力角色:'+get.translation(info.target); str+='<br><li>协力原因:'+get.translation(info.reason); str+='<br><li>进度:'; var suits=info.used||[]; var suits2=[['spade','♠','♤'],['heart','♥','♡'],['club','♣','♧'],['diamond','♦','♢']]; for(var i of suits2){ str+=(suits.contains(i[0])?i[1]:i[2]); } str+=(suits.length>3?' (已完成)':' (未完成)'); str+='<br> '; } } return str.slice(4,str.length-6); }, }, }, }, }, zhengsu:{ trigger:{player:'phaseDiscardEnd'}, forced:true, charlotte:true, filter:function(event,player){ return (player.storage.zhengsu_leijin||player.storage.zhengsu_bianzhen||player.storage.zhengsu_mingzhi); }, content:function(){ player.chooseDrawRecover(2,'整肃奖励:摸两张牌或回复1点体力'); }, subSkill:{ leijin:{ mod:{ aiOrder:function(player,card,num){ if(typeof card.number!='number') return; var history=player.getHistory('useCard',evt=>evt.isPhaseUsing()); if(history.length==0) return num+10*(14-card.number); var num=get.number(history[0].card); if(!num) return; for(var i=1;i<history.length;i++){ var num2=get.number(history[i].card); if(!num2||num2<=num) return; num=num2; } if(card.number>num) return num+10*(14-card.number); }, }, mark:true, trigger:{player:'useCard1'}, lastDo:true, charlotte:true, forced:true, popup:false, onremove:true, filter:function(event,player){ return player.isPhaseUsing()&&player.storage.zhengsu_leijin!==false; }, content:function(){ var list=player.getHistory('useCard',function(evt){ return evt.isPhaseUsing(player); }); var goon=true; for(var i=0;i<list.length;i++){ var num=get.number(list[i].card); if(typeof num!='number'){ goon=false; break; } if(i>0){ var num2=get.number(list[i-1].card); if(typeof num2!='number'||num2>=num){ goon=false; break; } } } if(!goon){ game.broadcastAll(function(player){ player.storage.zhengsu_leijin=false; if(player.marks.zhengsu_leijin) player.marks.zhengsu_leijin.firstChild.innerHTML='╳'; delete player.storage.zhengsu_leijin_markcount; },player); } else{ if(list.length>2){ game.broadcastAll(function(player,num){ if(player.marks.zhengsu_leijin) player.marks.zhengsu_leijin.firstChild.innerHTML='○'; player.storage.zhengsu_leijin=true; player.storage.zhengsu_leijin_markcount=num; },player,num); } else game.broadcastAll(function(player,num){ player.storage.zhengsu_leijin_markcount=num; },player,num); } player.markSkill('zhengsu_leijin'); }, intro:{ content:'<li>条件:回合内所有于出牌阶段使用的牌点数递增且不少于三张。', }, }, bianzhen:{ mark:true, trigger:{player:'useCard1'}, firstDo:true, charlotte:true, forced:true, popup:false, onremove:true, filter:function(event,player){ return player.isPhaseUsing()&&player.storage.zhengsu_bianzhen!==false; }, content:function(){ var list=player.getHistory('useCard',function(evt){ return evt.isPhaseUsing(); }); var goon=true,suit=get.suit(list[0].card,false); if(suit=='none'){ goon=false; } else{ for(var i=1;i<list.length;i++){ if(get.suit(list[i])!=suit){ goon=false; break; } } } if(!goon){ game.broadcastAll(function(player){ player.storage.zhengsu_bianzhen=false; if(player.marks.zhengsu_bianzhen) player.marks.zhengsu_bianzhen.firstChild.innerHTML='╳'; },player); } else{ if(list.length>1){ game.broadcastAll(function(player){ if(player.marks.zhengsu_bianzhen) player.marks.zhengsu_bianzhen.firstChild.innerHTML='○'; player.storage.zhengsu_bianzhen=true; },player); } else game.broadcastAll(function(player,suit){ if(player.marks.zhengsu_bianzhen) player.marks.zhengsu_bianzhen.firstChild.innerHTML=get.translation(suit); },player,suit); } player.markSkill('zhengsu_bianzhen'); }, intro:{ content:'<li>条件:回合内所有于出牌阶段使用的牌花色相同且不少于两张。', }, ai:{ effect:{ player_use:function(card,player,target){ if(typeof card!='object'||!player.isPhaseUsing()) return; var suitx=get.suit(card); var history=player.getHistory('useCard'); if(!history.length){ var val=0; if(player.hasCard(function(cardx){ return get.suit(cardx)==suitx&&card!=cardx&&(!card.cards||!card.cards.contains(cardx))&&player.hasValueTarget(cardx); },'hs')) val=[2,0.1]; if(val) return val; return; } var num=0; var suit=false; for(var i=0;i<history.length;i++){ var suit2=get.suit(history[i].card); if(!lib.suit.contains(suit2)) return; if(suit&&suit!=suit2) return; suit=suit2; num++; } if(suitx==suit&&num==1) return [1,0.1]; if(suitx!=suit&&(num>1||num<=1&&player.hasCard(function(cardx){ return get.suit(cardx)==suit&&player.hasValueTarget(cardx); },'hs'))) return 'zeroplayertarget'; }, }, }, }, mingzhi:{ mark:true, trigger:{player:'loseAfter'}, firstDo:true, charlotte:true, forced:true, popup:false, onremove:true, filter:function(event,player){ if(player.storage.zhengsu_mingzhi===false||event.type!='discard') return false; var evt=event.getParent('phaseDiscard'); return evt&&evt.player==player; }, content:function(){ var goon=true,list=[]; player.getHistory('lose',function(event){ if(!goon||event.type!='discard') return false; var evt=event.getParent('phaseDiscard'); if(evt&&evt.player==player){ for(var i of event.cards2){ var suit=get.suit(i,player); if(list.contains(suit)){ goon=false; break; } else list.push(suit); } } }); if(!goon){ game.broadcastAll(function(player){ player.storage.zhengsu_mingzhi=false; if(player.marks.zhengsu_mingzhi) player.marks.zhengsu_mingzhi.firstChild.innerHTML='╳'; delete player.storage.zhengsu_mingzhi_list; },player); } else{ if(list.length>1){ game.broadcastAll(function(player,list){ if(player.marks.zhengsu_mingzhi) player.marks.zhengsu_mingzhi.firstChild.innerHTML='○'; player.storage.zhengsu_mingzhi=true; player.storage.zhengsu_mingzhi_list=list; player.storage.zhengsu_mingzhi_markcount=list.length; },player,list); } else game.broadcastAll(function(player,list){ player.storage.zhengsu_mingzhi_list=list; player.storage.zhengsu_mingzhi_markcount=list.length; },player,list); } player.markSkill('zhengsu_mingzhi'); }, intro:{ content:'<li>条件:回合内所有于弃牌阶段弃置的牌花色均不相同且不少于两张。', }, }, }, }, renku:{ intro:{ markcount:function(){ return _status.renku.length; }, mark:function(dialog,content,player){ if(!_status.renku.length) return '仁库中没有牌'; else dialog.addAuto(_status.renku); }, content:function(){ if(!_status.renku.length) return '仁库中没有牌'; return get.translation(_status.renku); }, }, }, _showHiddenCharacter:{ trigger:{player:['changeHp','phaseBeginStart','loseMaxHpBegin','gainMaxHpBegin']}, firstDo:true, forced:true, popup:false, priority:25, filter:function(event,player,name){ return player.isUnseen(2)&&get.mode()!='guozhan'; }, content:function(){ player.showCharacter(2); player.removeSkill('g_hidden_ai'); }, }, _kamisha:{ trigger:{source:'damageBegin2'}, //forced:true, popup:false, prompt:function(event,player){ return '是否防止即将对'+get.translation(event.player)+'造成的伤害,改为令其减少'+get.cnNumber(event.num)+'点体力上限?'; }, filter:function(event,player){ return event.hasNature('kami')&&event.num>0; }, ruleSkill:true, check:function(event,player){ var att=get.attitude(player,event.player); if(event.player.hp==event.player.maxHp) return att<0; if(event.player.hp==event.player.maxHp-1&& (event.player.maxHp<=3||event.player.hasSkillTag('maixie'))) return att<0; return att>0; }, content:function(){ trigger.cancel(); trigger.player.loseMaxHp(trigger.num).source=player; }, }, aozhan:{ charlotte:true, mod:{ targetEnabled:function(card){ if(card.name=='tao'&&(card.isCard&&card.cardid||get.itemtype(card)=='card')) return false; }, cardSavable:function(card){ if(card.name=='tao'&&(card.isCard&&card.cardid||get.itemtype(card)=='card')) return false; }, }, group:["aozhan_sha","aozhan_shan"], subSkill:{ sha:{ enable:["chooseToUse","chooseToRespond"], filterCard:{ name:"tao", }, viewAs:{ name:"sha", isCard:true, }, viewAsFilter:function (player){ if(!player.countCards('hs','tao')) return false; }, position:'hs', prompt:"将一张桃当杀使用或打出", check:function (){return 1}, ai:{ respondSha:true, skillTagFilter:function(player){ if(!player.countCards('hs','tao')) return false; }, order:function(){ return get.order({name:'sha'})-0.1; }, }, sub:true, }, shan:{ enable:["chooseToRespond","chooseToUse"], filterCard:{ name:"tao", }, viewAs:{ name:"shan", isCard:true, }, prompt:"将一张桃当闪打出", check:function (){return 1}, viewAsFilter:function (player){ if(!player.countCards('hs','tao')) return false; }, position:'hs', ai:{ respondShan:true, skillTagFilter:function(player){ if(!player.countCards('hs','tao')) return false; }, }, sub:true, }, }, }, global:[], globalmap:{}, storage:{}, undist:{}, others:{}, zhu:{}, zhuSkill:{}, land_used:{}, unequip:{ai:{unequip:true}}, subplayer:{ trigger:{player:'dieBefore'}, forced:true, priority:-9, onremove:true, mark:'character', intro:{ content:function(storage,player){ if(typeof storage.intro2=='string') return storage.intro2; if(typeof storage.intro2=='function') return storage.intro2(storage,player); return '死亡前切换回主武将' }, name:function(storage){ return get.rawName(storage.name); } }, content:function(){ trigger.cancel(); var evt=trigger.getParent('damage'); if(evt.player==player){ evt.untrigger(false,player); } player.exitSubPlayer(true); }, ai:{ nosave:true } }, autoswap:{ firstDo:true, trigger:{player:['playercontrol','chooseToUseBegin','chooseToRespondBegin','chooseToDiscardBegin','chooseToCompareBegin', 'chooseButtonBegin','chooseCardBegin','chooseTargetBegin','chooseCardTargetBegin','chooseControlBegin', 'chooseBoolBegin','choosePlayerCardBegin','discardPlayerCardBegin','gainPlayerCardBegin','chooseToMoveBegin','chooseToPlayBeatmapBegin']}, forced:true, priority:100, forceDie:true, popup:false, filter:function(event,player){ if(event.autochoose&&event.autochoose()) return false; if(lib.filter.wuxieSwap(event)) return false; if(_status.auto||!player.isUnderControl()) return false; return true; }, content:function(){ game.swapPlayerAuto(player); }, }, dualside:{ charlotte:true, subSkill:{ turn:{ trigger:{player:['turnOverAfter','dieBefore']}, silent:true, filter:function(event,player){ if(player.storage.dualside_over) return false; return Array.isArray(player.storage.dualside); }, content:function(){ var cfg=player.storage.dualside; var bool=player.isTurnedOver(); if(trigger.name=='die'){ bool=!bool; } if(bool){ cfg[1]=player.hp; cfg[2]=player.maxHp; player.reinit(cfg[0],cfg[3],[cfg[4],cfg[5]]); player.unmarkSkill('dualside'); player.markSkillCharacter('dualside',{name:cfg[0]},'正面','当前体力:'+cfg[1]+'/'+cfg[2]); } else{ cfg[4]=player.hp; cfg[5]=player.maxHp; player.reinit(cfg[3],cfg[0],[cfg[1],cfg[2]]); player.unmarkSkill('dualside'); player.markSkillCharacter('dualside',{name:cfg[3]},'背面','当前体力:'+cfg[4]+'/'+cfg[5]); } if(trigger.name=='die'){ trigger.cancel(); delete player.storage.dualside; player.storage.dualside_over=true; player.unmarkSkill('dualside'); } } }, init:{ trigger:{global:'gameStart',player:'enterGame'}, silent:true, content:function(){ var list=[player.name,player.name1,player.name2]; for(var i=0;i<list.length;i++){ if(list[i]&&lib.character[list[i]]){ var info=lib.character[list[i]]; if(info[3].contains('dualside')&&info[4]){ player.storage.dualside=[list[i],player.hp,player.maxHp]; for(var j=0;j<info[4].length;j++){ if(info[4][j].startsWith('dualside:')){ var name2=info[4][j].slice(9); var info2=lib.character[name2]; player.storage.dualside.push(name2); player.storage.dualside.push(get.infoHp(info2[2])); player.storage.dualside.push(get.infoMaxHp(info2[2])); } } } } } var cfg=player.storage.dualside; if(get.mode()=='guozhan'){ if(player.name1==cfg[0]){ player.showCharacter(0); } else{ player.showCharacter(1); } } player.markSkillCharacter('dualside',{name:cfg[3]},'背面','当前体力:'+cfg[4]+'/'+cfg[5]); } } }, group:['dualside_init','dualside_turn'] }, fengyin:{ init:function(player,skill){ player.addSkillBlocker(skill); }, onremove:function(player,skill){ player.removeSkillBlocker(skill); }, charlotte:true, skillBlocker:function(skill,player){ return !lib.skill[skill].charlotte&&!get.is.locked(skill,player); }, mark:true, intro:{ content:function(storage,player,skill){ var list=player.getSkills(null,false,false).filter(function(i){ return lib.skill.fengyin.skillBlocker(i,player); }); if(list.length) return '失效技能:'+get.translation(list); return '无失效技能'; } } }, baiban:{ init:function(player,skill){ player.addSkillBlocker(skill); }, onremove:function(player,skill){ player.removeSkillBlocker(skill); }, charlotte:true, skillBlocker:function(skill,player){ return !lib.skill[skill].charlotte; }, mark:true, intro:{ content:function(storage,player,skill){ var list=player.getSkills(null,false,false).filter(function(i){ return lib.skill.baiban.skillBlocker(i,player); }); if(list.length) return '失效技能:'+get.translation(list); return '无失效技能'; } } }, qianxing:{ mark:true, nopop:true, init:function(player){ game.log(player,'获得了','【潜行】'); }, intro:{ content:'锁定技,你不能成为其他角色的卡牌的目标' }, mod:{ targetEnabled:function(card,player,target){ if(player!=target) return false; } } }, mianyi:{ trigger:{player:'damageBefore'}, mark:true, forced:true, init:function(player){ game.log(player,'获得了','【免疫】'); }, content:function(){ trigger.cancel(); }, ai:{ nofire:true, nothunder:true, nodamage:true, effect:{ target:function(card,player,target,current){ if(get.tag(card,'damage')) return [0,0]; } }, }, intro:{ content:'防止一切伤害' } }, mad:{ mark:true, locked:true, intro:{ content:'已进入混乱状态', name:'混乱', onunmark:function(storage,player){ game.log(player,'解除混乱状态'); } } }, ghujia:{ intro:{ content:function(content,player){ return '已有'+get.cnNumber(player.hujia)+'点护甲值'; } }, markimage:'image/card/shield.png', }, counttrigger:{ trigger:{global:'phaseAfter'}, silent:true, charlotte:true, priority:-100, content:function(){ player.removeSkill('counttrigger'); delete player.storage.counttrigger; }, group:'counttrigger_2', subSkill:{ 2:{ trigger:{global:'phaseBefore'}, silent:true, charlotte:true, priority:100, content:function(){ player.removeSkill('counttrigger'); delete player.storage.counttrigger; }, } } }, _recovercheck:{ trigger:{player:'recoverBefore'}, forced:true, priority:100, firstDo:true, popup:false, filter:function(event,player){ return player.hp>=player.maxHp; }, content:function(){ trigger.cancel(); }, }, /** * @deprecated */ /*_turnover:{ trigger:{player:'phaseBefore'}, forced:true, forceOut:true, priority:100, popup:false, firstDo:true, content:function(){ if(player.isTurnedOver()&&!trigger._noTurnOver){ trigger.cancel(); player.turnOver(); player.phaseSkipped=true; } else{ player.phaseSkipped=false; } var isRound=false; if(!trigger.skill){ isRound=_status.roundSkipped; if(_status.isRoundFilter){ isRound=_status.isRoundFilter(trigger,player); } else if(_status.seatNumSettled){ var seatNum=player.getSeatNum(); if(seatNum!=0){ if(typeof _status.lastSeatNum!='number'||seatNum<_status.lastSeatNum) isRound=true; _status.lastSeatNum=seatNum; } } else if(player==_status.roundStart) isRound=true; if(isRound){ delete _status.roundSkipped; game.roundNumber++; trigger._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(!player.phaseSkipped){ player.getHistory().isMe=true; player.getStat().isMe=true; } if(isRound){ game.getGlobalHistory().isRound=true; } }, },*/ _usecard:{ trigger:{global:'useCardAfter'}, forced:true, popup:false, priority:-100, lastDo:true, filter:function(event){ return !event._cleared&&event.card.name!='wuxie'; }, content:function(){ game.broadcastAll(function(){ ui.clear(); }); event._cleared=true; } }, _discard:{ trigger:{global:['discardAfter','loseToDiscardpileAfter','loseAsyncAfter']}, forced:true, popup:false, priority:-100, lastDo:true, filter:function(event){ return ui.todiscard[event.discardid]?true:false; }, content:function(){ game.broadcastAll(function(id){ var todiscard=ui.todiscard[id]; delete ui.todiscard[id]; if(todiscard){ var time=1000; if(typeof todiscard._discardtime=='number'){ time+=todiscard._discardtime-get.time(); } if(time<0){ time=0; } setTimeout(function(){ for(var i=0;i<todiscard.length;i++){ todiscard[i].delete(); } },time); } },trigger.discardid); } }, _save:{ //trigger:{source:'dying2',player:'dying2'}, priority:5, forced:true, popup:false, filter:function(event,player){ //if(!event.player.isDying()) return false; //if(event.source&&event.source.isIn()&&event.source!=player) return false; //return true; return false; }, content:function(){ "step 0" event.dying=trigger.player; if(!event.acted) event.acted=[]; "step 1" if(trigger.player.isDead()){ event.finish(); return; } event.acted.push(player); var str=get.translation(trigger.player)+'濒死,是否帮助?'; var str2='当前体力:'+trigger.player.hp; if(lib.config.tao_enemy&&event.dying.side!=player.side&&lib.config.mode!='identity'&&lib.config.mode!='guozhan'&&!event.dying.hasSkillTag('revertsave')){ event._result={bool:false} } else if(player.canSave(event.dying)){ player.chooseToUse({ filterCard:function(card,player,event){ event=event||_status.event; return lib.filter.cardSavable(card,player,event.dying); }, filterTarget:function(card,player,target){ if(target!=_status.event.dying) return false; if(!card) return false; var info=get.info(card); if(!info.singleCard||ui.selected.targets.length==0){ var mod=game.checkMod(card,player,target,'unchanged','playerEnabled',player); if(mod==false) return false; var mod=game.checkMod(card,player,target,'unchanged','targetEnabled',target); if(mod!='unchanged') return mod; } return true; }, prompt:str, prompt2:str2, ai1:function(card){ if(typeof card=='string'){ var info=get.info(card); if(info.ai&&info.ai.order){ if(typeof info.ai.order=='number'){ return info.ai.order; } else if(typeof info.ai.order=='function'){ return info.ai.order(); } } } return 1; }, ai2:get.effect_use, type:'dying', targetRequired:true, dying:event.dying }); } else{ event._result={bool:false} } "step 2" if(result.bool){ var player=trigger.player; if(player.hp<=0&&!trigger.nodying&&!player.nodying&&player.isAlive()&&!player.isOut()&&!player.removed) event.goto(0); else trigger.untrigger(); } else{ for(var i=0;i<20;i++){ if(event.acted.contains(event.player.next)){ break; } else{ event.player=event.player.next; if(!event.player.isOut()){ event.goto(1); break; } } } } } }, _ismin:{ mod:{ cardEnabled:function(card,player){ if(player.isMin()){ if(get.type(card)=='equip') return false; } } } }, _recasting:{ enable:'phaseUse', logv:false, prompt:'将要重铸的牌置入弃牌堆并摸一张牌', filter:(event,player)=>player.hasCard(card=>lib.skill._recasting.filterCard(card,player),lib.skill._recasting.position), position:'he', filterCard:(card,player)=>player.canRecast(card,null,true), discard:false, lose:false, delay:false, content:()=>{ player.recast(cards,null,(player,cards)=>{ var numberOfCardsToDraw=cards.length; cards.forEach(value=>{ if(lib.config.mode=='stone'&&_status.mode=='deck'&&!player.isMin()&&get.type(value).startsWith('stone')){ var stonecard=get.stonecard(1,player.career); if(stonecard.length){ numberOfCardsToDraw-=stonecard.length; player.gain(game.createCard(stonecard.randomGet()),'draw'); } else player.draw({ drawDeck:1 }).log=false; } else if(get.subtype(value)=='spell_gold'){ var libCard=get.libCard(info=>info.subtype=='spell_silver'); if(!libCard.length) return; numberOfCardsToDraw--; player.gain(game.createCard(libCard.randomGet()),'draw'); } else if(get.subtype(value)=='spell_silver'){ var libCard=get.libCard(info=>info.subtype=='spell_bronze'); if(!libCard.length) return; numberOfCardsToDraw--; player.gain(game.createCard(libCard.randomGet()),'draw'); } }); if(numberOfCardsToDraw) player.draw(numberOfCardsToDraw).log=false; }); }, ai:{ basic:{ order:6 }, result:{ player:1 } } }, _lianhuan:{ trigger:{player:'damageAfter'}, filter:function(event,player){ return event.lianhuanable==true; }, forced:true, popup:false, logv:false, forceDie:true, //priority:-5, content:function(){ "step 0" event.logvid=trigger.getLogv(); "step 1" event.targets=game.filterPlayer(function(current){ return current!=event.player&¤t.isLinked(); }); lib.tempSortSeat=_status.currentPhase||player; event.targets.sort(lib.sort.seat); delete lib.tempSortSeat; event._args=[trigger.num,trigger.nature,trigger.cards,trigger.card]; if(trigger.source) event._args.push(trigger.source); else event._args.push("nosource"); "step 2" if(event.targets.length){ var target=event.targets.shift(); if(target.isLinked()) target.damage.apply(target,event._args.slice(0)); event.redo(); } }, }, _lianhuan4:{ trigger:{player:'changeHp'}, priority:-10, forced:true, popup:false, forceDie:true, filter:function(event,player){ var evt=event.getParent(); return evt&&evt.name=='damage'&&evt.hasNature('linked')&&player.isLinked(); }, content:function(){ player.link(); if(trigger.getParent().notLink()) trigger.getParent().lianhuanable=true; } }, /** * @deprecated */ _chongzhu:{ get filter(){ return lib.skill._recasting.filter; }, set filter(filter){ lib.skill._recasting.filter=filter; }, get filterCard(){ return lib.skill._recasting.filterCard; }, set filterCard(filterCard){ lib.skill._recasting.filterCard=filterCard; }, get content(){ return lib.skill._recasting.content; }, set content(content){ lib.skill._recasting.content=content; }, get ai(){ return lib.skill._recasting.ai; }, set ai(ai){ lib.skill._recasting.ai=ai; } } }, character:{}, perfectPair:{}, cardPile:{}, message:{ server:{ init:function(version,config,banned_info){ if(lib.node.banned.contains(banned_info)){ this.send('denied','banned'); } else if(config.id&&lib.playerOL&&lib.playerOL[config.id]){ var player=lib.playerOL[config.id]; player.setNickname(); player.ws=this; player.isAuto=false; this.id=config.id; game.broadcast(function(player){ player.setNickname(); },player); this.send('reinit',lib.configOL,get.arenaState(),game.getState?game.getState():{},game.ip,null,_status.onreconnect,_status.cardtag,_status.postReconnect); } else if(version!=lib.versionOL){ this.send('denied','version'); lib.node.clients.remove(this); this.closed=true; } else if(!_status.waitingForPlayer){ if(game.phaseNumber&&lib.configOL.observe){ lib.node.observing.push(this); this.send('reinit',lib.configOL,get.arenaState(),game.getState?game.getState():{},game.ip,game.players[0].playerid,null,_status.cardtag); if(!ui.removeObserve){ ui.removeObserve=ui.create.system('移除旁观',function(){ lib.configOL.observe=false; if(game.onlineroom){ game.send('server','config',lib.configOL); } while(lib.node.observing.length){ lib.node.observing.shift().ws.close(); } this.remove(); delete ui.removeObserve; },true,true); } } else{ this.send('denied','gaming'); lib.node.clients.remove(this); this.closed=true; } } else if(lib.node.clients.length-(window.isNonameServer?1:0)>=parseInt(lib.configOL.number)){ this.send('denied','number'); lib.node.clients.remove(this); this.closed=true; } else{ if(config){ this.avatar=config.avatar; this.nickname=config.nickname; } for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].classList.contains('unselectable2')) continue; if(game.connectPlayers[i]!=game.me&&!game.connectPlayers[i].playerid){ game.connectPlayers[i].playerid=this.id; game.connectPlayers[i].initOL(this.nickname,this.avatar); game.connectPlayers[i].ws=this; break; } } this.send('init',this.id,lib.configOL,game.ip,window.isNonameServer,game.roomId); } }, inited:function(){ this.inited=true; if(_status.waitingForPlayer){ game.updateWaiting(); } }, reinited:function(){ this.inited=true; }, result:function(result){ if(lib.node.observing.contains(this)) return; var player=lib.playerOL[this.id]; if(player){ player.unwait(result); } }, tempResult:function(result){ if(lib.node.observing.contains(this)) return; var player=lib.playerOL[this.id]; if(player){ player.tempUnwait(result); } }, startGame:function(){ if(this.id==game.onlinezhu){ game.resume(); } }, changeRoomConfig:function(config){ if(this.id==game.onlinezhu){ game.broadcastAll(function(config){ for(var i in config){ lib.configOL[i]=config[i]; } if(ui.connectStartBar){ ui.connectStartBar.firstChild.innerHTML=get.modetrans(lib.configOL,true); } },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); } for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].playerid==this.id){ game.connectPlayers[i].chat('房间设置已更改'); } } } }, changeNumConfig:function(num,index,bool){ if(this.id==game.onlinezhu){ lib.configOL.number=num; game.send('server','config',lib.configOL); if(game.connectPlayers&&game.connectPlayers[index]){ if(bool){ game.connectPlayers[index].classList.add('unselectable2'); } else{ game.connectPlayers[index].classList.remove('unselectable2'); } game.updateWaiting(); } } }, throwEmotion:function(target,emotion){ if(lib.node.observing.contains(this)) return; var player=lib.playerOL[this.id]; if(player){ player.throwEmotion(target,emotion); } }, emotion:function(id,pack,emotion){ if(lib.node.observing.contains(this)) return; var that=this; if(!this.id||(!lib.playerOL[this.id]&&(!game.connectPlayers||!function(){ for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].playerid==that.id){ return true; } } return false; }()))) return; var player; if(lib.playerOL[id]){ player=lib.playerOL[id]; } else if(game.connectPlayers){ for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].playerid==id){ player=game.connectPlayers[i];break; } } } if(player) lib.element.player.emotion.apply(player,[pack,emotion]); }, chat:function(id,str){ if(lib.node.observing.contains(this)) return; var that=this; if(!this.id||(!lib.playerOL[this.id]&&(!game.connectPlayers||!function(){ for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].playerid==that.id){ return true; } } return false; }()))) return; var player; if(lib.playerOL[id]){ player=lib.playerOL[id]; } else if(game.connectPlayers){ for(var i=0;i<game.connectPlayers.length;i++){ if(game.connectPlayers[i].playerid==id){ player=game.connectPlayers[i];break; } } } if(player) lib.element.player.chat.call(player,str); }, giveup:function(player){ if(lib.node.observing.contains(this)||!player||!player._giveUp) return; _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; }, auto:function(){ if(lib.node.observing.contains(this)) return; var player=lib.playerOL[this.id]; if(player){ player.isAuto=true; player.setNickname(player.nickname+' - 托管'); game.broadcast(function(player){ player.setNickname(player.nickname+' - 托管'); },player); } }, unauto:function(){ if(lib.node.observing.contains(this)) return; var player=lib.playerOL[this.id]; if(player){ player.isAuto=false; player.setNickname(player.nickname); game.broadcast(function(player){ player.setNickname(player.nickname); },player); } }, exec:function(func){ // if(typeof func=='function'){ // var args=Array.from(arguments); // args.shift(); // func.apply(this,args); // } }, log:function(){ var items=[]; try{ for(var i=0;i<arguments.length;i++){ eval('items.push('+arguments[i]+')'); } } catch(e){ this.send('log',['err']); return; } this.send('log',items); } }, client:{ log:function(arr){ if(Array.isArray(arr)){ for(var i=0;i<arr.length;i++){ console.log(arr[i]); } } }, opened:function(){ game.send('init',lib.versionOL,{ id:game.onlineID, avatar:lib.config.connect_avatar, nickname:get.connectNickname() },lib.config.banned_info); if(ui.connecting&&!ui.connecting.splashtimeout){ ui.connecting.firstChild.innerHTML='重连成功'; } }, onconnection:function(id){ var ws={wsid:id}; for(var i in lib.element.nodews){ ws[i]=lib.element.nodews[i]; } lib.wsOL[id]=ws; lib.init.connection(ws); }, onmessage:function(id,message){ if(lib.wsOL[id]){ lib.wsOL[id].onmessage(message); } }, onclose:function(id){ if(lib.wsOL[id]){ lib.wsOL[id].onclose(); } }, selfclose:function(){ if(game.online||game.onlineroom){ if((game.servermode||game.onlinehall)&&_status.over){ // later } else{ game.saveConfig('tmp_user_roomId'); } } game.ws.close(); }, reloadroom:function(forced){ if(window.isNonameServer&&(forced||!_status.protectingroom)){ game.reload(); } }, createroom:function(index,config,mode){ game.online=false; game.onlineroom=true; game.roomId=index; lib.node={}; if(config&&mode&&window.isNonameServer){ if(mode=='auto'){ mode=lib.configOL.mode; } game.switchMode(mode,config); } else{ game.switchMode(lib.configOL.mode); } ui.create.connecting(true); }, enterroomfailed:function(){ alert('请稍后再试'); _status.enteringroom=false; ui.create.connecting(true); }, roomlist:function(list,events,clients,wsid){ game.send('server','key',[game.onlineKey,lib.version]); game.online=true; game.onlinehall=true; lib.config.recentIP.remove(_status.ip); lib.config.recentIP.unshift(_status.ip); lib.config.recentIP.splice(5); if(!lib.config.reconnect_info||lib.config.reconnect_info[0]!=_status.ip){ game.saveConfig('reconnect_info',[_status.ip,null]); } game.saveConfig('recentIP',lib.config.recentIP); _status.connectMode=true; game.clearArena(); game.clearConnect(); ui.pause.hide(); ui.auto.hide(); clearTimeout(_status.createNodeTimeout); game.send('server','changeAvatar',get.connectNickname(),lib.config.connect_avatar); var proceed=function(){ game.ip=get.trimip(_status.ip); ui.create.connectRooms(list); if(events){ ui.connectEvents=ui.create.div('.forceopaque.menubutton.large.connectevents.pointerdiv','约战',ui.window,ui.click.connectEvents); ui.connectEventsCount=ui.create.div('.forceopaque.menubutton.icon.connectevents.highlight.hidden','',ui.window); ui.connectClients=ui.create.div('.forceopaque.menubutton.large.connectevents.pointerdiv.left','在线',ui.window,ui.click.connectClients); ui.connectClientsCount=ui.create.div('.forceopaque.menubutton.icon.connectevents.highlight.left','1',ui.window); ui.createRoomButton=ui.create.div('.forceopaque.menubutton.large.connectevents.pointerdiv.left2','创建房间',ui.window,function(){ if(!_status.creatingroom){ _status.creatingroom=true; ui.click.connectMenu(); } }); if(events.length){ ui.connectEventsCount.innerHTML=events.filter(function(evt){ return evt.creator==game.onlineKey||!get.is.banWords(evt.content) }).length; ui.connectEventsCount.show(); } } game.wsid=wsid; lib.message.client.updaterooms(list,clients); lib.message.client.updateevents(events); ui.exitroom=ui.create.system('退出房间',function(){ game.saveConfig('tmp_owner_roomId'); game.saveConfig('tmp_user_roomId'); if(ui.rooms){ game.saveConfig('reconnect_info'); } else{ if(lib.config.reconnect_info){ lib.config.reconnect_info.length=1; game.saveConfig('reconnect_info',lib.config.reconnect_info); } } game.reload(); },true); var findRoom=function(id){ for(var room of ui.rooms){ if(room.key==id) return room; } return false; }; if(typeof lib.config.tmp_owner_roomId=='string'){ if(typeof game.roomId!='string'&&!findRoom(lib.config.tmp_owner_roomId)){ lib.configOL.mode=lib.config.connect_mode; game.roomId=lib.config.tmp_owner_roomId; } game.saveConfig('tmp_owner_roomId'); } if(typeof lib.config.tmp_user_roomId=='string'){ if(typeof game.roomId!='string'){ if(findRoom(lib.config.tmp_user_roomId)){ game.roomId=lib.config.tmp_user_roomId; } else{ ui.create.connecting(); (function(){ var n=10; var id=lib.config.tmp_user_roomId; var interval=setInterval(function(){ if(n>0){ n--; if(findRoom(id)){ clearInterval(interval); game.send('server','enter',id,get.connectNickname(),lib.config.connect_avatar); } } else{ ui.create.connecting(true); clearInterval(interval); } },500); }()); } } game.saveConfig('tmp_user_roomId'); } if(window.isNonameServer){ var cfg='pagecfg'+window.isNonameServer; if(lib.config[cfg]){ lib.configOL=lib.config[cfg][0]; game.send('server','server',lib.config[cfg].slice(1)); game.saveConfig(cfg); _status.protectingroom=true; setTimeout(function(){ _status.protectingroom=false; if(!lib.node||!lib.node.clients||!lib.node.clients.length){ game.reload(); } },15000); } else{ game.send('server','server'); } } else if(typeof game.roomId=='string'){ var room=findRoom(game.roomId); if(game.roomIdServer&&room&&(room.serving||!room.version)){ console.log(); if(lib.config.reconnect_info){ lib.config.reconnect_info[2]=null; game.saveConfig('reconnect_info',lib.config.reconnect_info); } } else{ ui.create.connecting(); game.send('server',(game.roomId==game.onlineKey)?'create':'enter',game.roomId,get.connectNickname(),lib.config.connect_avatar); } } lib.init.onfree(); } if(_status.event.parent){ game.forceOver('noover',proceed); } else{ proceed(); } }, updaterooms:function(list,clients){ if(ui.rooms){ var map={},map2={}; for(var i of ui.rooms) map2[i.key]=true; for(var i of list){ if(!i) continue; map[i[4]]=i; } ui.window.classList.add('more_room'); for(var i=0;i<ui.rooms.length;i++){ if(!map[ui.rooms[i].key]){ ui.rooms[i].remove(); ui.rooms.splice(i--,1); } else ui.rooms[i].initRoom(list[i]); } for(var i of list){ if(!i) continue; map[i[4]]=i; if(!map2[i[4]]){ var player=ui.roombase.add('<div class="popup text pointerdiv" style="width:calc(100% - 10px);display:inline-block;white-space:nowrap">空房间</div>'); player.roomindex=i; player.initRoom=lib.element.player.initRoom; player.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.connectroom); player.initRoom(i); ui.rooms.push(player); } } } lib.message.client.updateclients(clients,true); }, updateclients:function(clients,bool){ if(clients&&ui.connectClients){ ui.connectClients.info=clients; ui.connectClientsCount.innerHTML=clients.length; } if(_status.connectClientsCallback){ _status.connectClientsCallback(); } }, updateevents:function(events){ if(events&&ui.connectEvents){ ui.connectEvents.info=events; var num=events.filter(function(evt){ return typeof evt.creator=='string'&&(evt.creator==game.onlineKey||!get.is.banWords(evt.content)) }).length; if(num){ ui.connectEventsCount.innerHTML=num; ui.connectEventsCount.show(); } else{ ui.connectEventsCount.hide(); } if(_status.connectEventsCallback){ _status.connectEventsCallback(); } } }, eventsdenied:function(reason){ var str='创建约战失败'; if(reason=='total'){ str+=',约战总数不能超过20'; } else if(reason=='time'){ str+=',时间已过'; } else if(reason=='ban'){ str+=',请注意文明发言'; } alert(str); }, init:function(id,config,ip,servermode,roomId){ game.online=true; game.onlineID=id; game.ip=ip; game.servermode=servermode; game.roomId=roomId; if(game.servermode){ game.saveConfig('reconnect_info',[_status.ip,id,game.roomId]); } else{ game.saveConfig('reconnect_info',[_status.ip,id]); game.saveConfig('tmp_user_roomId',roomId); } lib.config.recentIP.remove(_status.ip); lib.config.recentIP.unshift(_status.ip); lib.config.recentIP.splice(5); game.saveConfig('recentIP',lib.config.recentIP); _status.connectMode=true; lib.configOL=config; lib.playerOL={}; lib.cardOL={}; game.clearArena(); game.finishCards(); ui.create.roomInfo(); ui.create.chat(); if(game.servermode){ ui.create.connectPlayers(get.modetrans(config,true)); } else{ ui.create.connectPlayers(ip); } ui.pause.hide(); ui.auto.hide(); game.clearConnect(); clearTimeout(_status.createNodeTimeout); var proceed=function(){ game.loadModeAsync(config.mode,function(mode){ for(var i in mode.ai){ if(typeof mode.ai[i]=='object'){ if(ai[i]==undefined) ai[i]={}; for(var j in mode.ai[i]){ ai[i][j]=mode.ai[i][j]; } } else{ ai[i]=mode.ai[i]; } } for(var i in mode.get){ if(typeof mode.get[i]=='object'){ if(get[i]==undefined) get[i]={}; for(var j in mode.get[i]){ get[i][j]=mode.get[i][j]; } } else{ get[i]=mode.get[i]; } } for(var i in mode.translate){ lib.translate[i]=mode.translate[i]; } if(mode.game){ game.getIdentityList=mode.game.getIdentityList; game.updateState=mode.game.updateState; game.getRoomInfo=mode.game.getRoomInfo; } if(mode.element&&mode.element.player){ for(var i in mode.element.player){ lib.element.player[i]=mode.element.player[i]; } } if(mode.skill){ for(var i in mode.skill){ lib.skill[i]=mode.skill[i]; } } if(mode.card){ for(var i in mode.card){ lib.card[i]=mode.card[i]; } } game.finishCards(); if(mode.characterPack){ for(var i in mode.characterPack){ lib.characterPack[i]=mode.characterPack[i]; } } _status.event={ finished:true, next:[], after:[] }; _status.paused=false; game.createEvent('game',false).setContent(lib.init.startOnline); game.loop(); game.send('inited'); ui.create.connecting(true); }); } if(_status.event.parent){ game.forceOver('noover',proceed); } else{ proceed(); } for(var i in lib.characterPack){ for(var j in lib.characterPack[i]){ lib.character[j]=lib.character[j]||lib.characterPack[i][j]; } } }, reinit:function(config,state,state2,ip,observe,onreconnect,cardtag,postReconnect){ ui.auto.show(); ui.pause.show(); game.clearConnect(); clearTimeout(_status.createNodeTimeout); game.online=true; game.ip=ip; game.servermode=state.servermode; game.roomId=state.roomId; if(state.over){ _status.over=true; } if(observe){ game.observe=true; game.onlineID=null; game.roomId=null; } if(game.servermode&&!observe){ game.saveConfig('reconnect_info',[_status.ip,game.onlineID,game.roomId]); } else{ game.saveConfig('reconnect_info',[_status.ip,game.onlineID]); if(!observe){ game.saveConfig('tmp_user_roomId',game.roomId); } } _status.connectMode=true; lib.configOL=config; lib.playerOL={}; lib.cardOL={}; game.loadModeAsync(config.mode,function(mode){ for(var i in mode.ai){ if(typeof mode.ai[i]=='object'){ if(ai[i]==undefined) ai[i]={}; for(var j in mode.ai[i]){ ai[i][j]=mode.ai[i][j]; } } else{ ai[i]=mode.ai[i]; } } for(var i in mode.get){ if(typeof mode.get[i]=='object'){ if(get[i]==undefined) get[i]={}; for(var j in mode.get[i]){ get[i][j]=mode.get[i][j]; } } else{ get[i]=mode.get[i]; } } for(var i in mode.translate){ lib.translate[i]=mode.translate[i]; } if(mode.game){ game.getIdentityList=mode.game.getIdentityList; game.getIdentityList2=mode.game.getIdentityList2; game.updateState=mode.game.updateState; game.showIdentity=mode.game.showIdentity; } if(mode.element&&mode.element.player){ for(var i in mode.element.player){ lib.element.player[i]=mode.element.player[i]; } } if(mode.skill){ for(var i in mode.skill){ lib.skill[i]=mode.skill[i]; } } if(mode.card){ for(var i in mode.card){ lib.card[i]=mode.card[i]; } } game.finishCards(); if(mode.characterPack){ for(var i in mode.characterPack){ lib.characterPack[i]=mode.characterPack[i]; } } if(mode.onreinit){ mode.onreinit(); } _status.cardtag=get.parsedResult(cardtag); game.players=[]; game.dead=[]; for(var i in lib.characterPack){ for(var j in lib.characterPack[i]){ lib.character[j]=lib.character[j]||lib.characterPack[i][j]; } } game.clearArena(); game.finishCards(); if(!observe){ ui.create.chat(); if(ui.exitroom){ ui.exitroom.remove(); delete ui.exitroom; } } else{ if(!ui.exitroom){ ui.create.system('退出旁观',function(){ game.saveConfig('reconnect_info'); game.reload(); },true); } if(!lib.configOL.observe_handcard){ ui.arena.classList.add('observe'); } } postReconnect=get.parsedResult(postReconnect); for(var i in postReconnect){ if(Array.isArray(postReconnect[i])){ postReconnect[i].shift().apply(this,postReconnect[i]); } } state=get.parsedResult(state); ui.arena.setNumber(state.number); _status.mode=state.mode; _status.renku=state.renku; lib.inpile=state.inpile; lib.inpile_nature=state.inpile_nature; var pos=state.players[observe||game.onlineID].position; for(var i in state.players){ var info=state.players[i]; var player=ui.create.player(ui.arena).animate('start'); player.dataset.position=(info.position<pos)?info.position-pos+parseInt(state.number):info.position-pos; if(i==observe||i==game.onlineID){ game.me=player; } if(player.setModeState){ player.setModeState(info); } else{ player.init(info.name1,info.name2); if(info.name&&info.name!=info.name1) player.name=info.name; } if(!info.unseen) player.classList.remove('unseen'); if(!info.unseen2) player.classList.remove('unseen2'); if(!player.isUnseen(2)&&player.storage.nohp){ delete player.storage.nohp; player.node.hp.show(); } player.playerid=i; player.nickname=info.nickname; player.changeGroup(info.group,false,'nobroadcast'); player.identity=info.identity; player.identityShown=info.identityShown; player.hp=info.hp; player.maxHp=info.maxHp; player.hujia=info.hujia; player.sex=info.sex; player.side=info.side; player.phaseNumber=info.phaseNumber; player.seatNum=info.seatNum; player.disabledSlots=info.disabledSlots; player.expandedSlots=info.expandedSlots; player.setNickname(); if(info.dead){ player.classList.add('dead'); if(lib.config.die_move){ player.$dieflip(); } if(lib.element.player.$dieAfter){ lib.element.player.$dieAfter.call(player); } game.dead.push(player); } else{ game.players.push(player); } if(info.linked){ player.addLink(); } if(info.turnedover){ player.classList.add('turnedover'); } if(info.out){ player.classList.add('out'); } if(info.disableJudge){ player.$disableJudge(); } player.$syncDisable(); player.directgain(info.handcards); lib.playerOL[i]=player; for(var i=0;i<info.equips.length;i++){ player.$equip(info.equips[i]); } for(var i=0;i<info.handcards.length;i++){ info.handcards[i].addGaintag(info.gaintag[i]); } for(var i=0;i<info.specials.length;i++){ info.specials[i].classList.add('glows'); } if(info.expansions.length){ var expansion_gaintag=[]; player.$addToExpansion(info.expansions); for(var i=0;i<info.expansions.length;i++){ info.expansions[i].addGaintag(info.expansion_gaintag[i]); expansion_gaintag.addArray(info.expansion_gaintag[i]); } for(var i of expansion_gaintag) player.markSkill[i]; } for(var i=0;i<info.judges.length;i++){ if(info.views[i]&&info.views[i]!=info.judges[i]){ info.judges[i].classList.add('fakejudge'); info.judges[i].viewAs=info.views[i]; info.judges[i].node.background.innerHTML=lib.translate[info.views[i]+'_bg']||get.translation(info.views[i])[0] } player.node.judges.appendChild(info.judges[i]); } ui.updatej(player); if(!player.setModeState){ if(!game.getIdentityList&&info.identityNode){ player.node.identity.innerHTML=info.identityNode[0]; player.node.identity.dataset.color=info.identityNode[1]; } else if(player==game.me||player.identityShown||observe){ player.setIdentity(); player.forceShown=true; } else{ player.setIdentity('cai'); } if(!lib.configOL.observe_handcard&&(lib.configOL.mode=='identity'||lib.configOL.mode=='guozhan')){ if(observe&&!player.identityShown){ player.setIdentity('cai'); player.forceShown=false; } } } player.update(); } game.arrangePlayers(); ui.create.me(true); _status.event={ finished:true, next:[], after:[] }; _status.paused=false; _status.dying=get.parsedResult(state.dying)||[]; if(game.updateState){ game.updateState(state2); } var next=game.createEvent('game',false); next.setContent(lib.init.startOnline); if(observe){ next.custom.replace.target=function(player){ if(!lib.configOL.observe_handcard&&lib.configOL.mode=='guozhan'){ return; } if(player.isAlive()){ if(!game.me.identityShown&&lib.configOL.mode=='guozhan'){ game.me.node.identity.firstChild.innerHTML='猜'; game.me.node.identity.dataset.color='unknown'; } game.swapPlayer(player); if(!game.me.identityShown&&lib.configOL.mode=='guozhan'){ game.me.node.identity.firstChild.innerHTML=''; } } } } else{ if(Array.isArray(onreconnect)){ onreconnect.shift().apply(this,onreconnect); } } game.loop(); game.send('reinited'); game.showHistory(); _status.gameStarted=true; if(lib.config.show_cardpile){ ui.cardPileButton.style.display=''; } if(!observe&&game.me&&(game.me.isDead()||_status.over)){ ui.create.exit(); } ui.updatehl(); ui.create.connecting(true); }); }, exec:function(func){ var key=game.onlineKey; if(typeof func=='function'){ var args=Array.from(arguments); args.shift(); func.apply(this,args); } if(key){ game.onlineKey=key; localStorage.setItem(lib.configprefix+'key',game.onlineKey); } }, denied:function(reason){ switch(reason){ case 'version': alert('加入失败:版本不匹配,请将游戏更新至最新版'); game.saveConfig('tmp_owner_roomId'); game.saveConfig('tmp_user_roomId'); game.saveConfig('reconnect_info'); break; case 'gaming':alert('加入失败:游戏已开始');break; case 'number':alert('加入失败:房间已满');break; case 'banned':alert('加入失败:房间拒绝你加入');break; case 'key': alert('您的游戏版本过低,请升级到最新版'); game.saveConfig('tmp_owner_roomId'); game.saveConfig('tmp_user_roomId'); game.saveConfig('reconnect_info'); break; case 'offline': if(_status.paused&&_status.event.name=='game'){ setTimeout(game.resume,500); } break; } game.ws.close(); if(_status.connectDenied){ _status.connectDenied(); } }, cancel:function(id){ if(_status.event._parent_id==id){ ui.click.cancel(); } if(_status.event.id==id){ if(_status.event._backup) ui.click.cancel(); ui.click.cancel(); if(ui.confirm){ ui.confirm.close(); } if(_status.event.result){ _status.event.result.id=id; } } }, closeDialog:function(id){ var dialog=get.idDialog(id); if(dialog){ dialog.close(); } }, createDialog:function(id){ var args=Array.from(arguments); args.shift(); ui.create.dialog.apply(this,args).videoId=id; }, gameStart:function(){ for(var i=0;i<game.connectPlayers.length;i++){ game.connectPlayers[i].delete(); } delete game.connectPlayers; if(ui.connectStartButton){ ui.connectStartButton.delete(); delete ui.connectStartButton; } if(ui.connectStartBar){ ui.connectStartBar.delete(); delete ui.connectStartBar; } if(ui.roomInfo){ ui.roomInfo.remove(); delete ui.roomInfo; } if(ui.exitroom){ ui.exitroom.remove(); delete ui.exitroom; } ui.auto.show(); ui.pause.show(); if(lib.config.show_cardpile){ ui.cardPileButton.style.display=''; } _status.gameStarted=true; game.showHistory(); }, updateWaiting:function(map){ if(!game.connectPlayers) return; if(!lib.translate.zhu){ lib.translate.zhu='主'; } game.onlinezhu=false; _status.waitingForPlayer=true; for(var i=0;i<map.length;i++){ if(map[i]=='disabled'){ game.connectPlayers[i].classList.add('unselectable2'); } else{ game.connectPlayers[i].classList.remove('unselectable2'); if(map[i]){ game.connectPlayers[i].initOL(map[i][0],map[i][1]); game.connectPlayers[i].playerid=map[i][2]; if(map[i][3]=='zhu'){ game.connectPlayers[i].setIdentity('zhu'); if(map[i][2]==game.onlineID){ game.onlinezhu=true; if(ui.roomInfo){ ui.roomInfo.innerHTML='房间设置'; } if(ui.connectStartButton){ ui.connectStartButton.innerHTML='开始游戏'; } } } else{ game.connectPlayers[i].node.identity.firstChild.innerHTML=''; } } else{ game.connectPlayers[i].uninitOL(); delete game.connectPlayers[i].playerid; } } } } } }, suit:['club','spade','diamond','heart'], suits:['club','spade','diamond','heart','none'], color:{ black:['club','spade'], red:['diamond','heart'], none:['none'], }, group:['wei','shu','wu','qun','jin','shen'], //数值代表各元素在名称中排列的先后顺序 nature:new Map([ ['fire',20], ['thunder',30], ['kami',60], ['ice',40], ['stab',10], ['poison',50] ]), linked:['fire','thunder','kami','ice'], natureBg:new Map([ ['stab','image/card/cisha.png'] ]), natureSeparator:'|', namePrefix:new Map([ ['界',{ color:'#fdd559', nature:'soilmm', }], ['谋',{ color:'#def7ca', nature:'woodmm', }], ['武',{ color:'#fd8359', nature:'soilmm', }], ['乐',{ color:'#f7f4fc', nature:'keymm', }], ['神',{ color:'#faecd1', nature:'orangemm', }], ['族',{ color:'#ee9ac7', nature:'firemm', }], ['晋',{ color:'#f3c5ff', nature:'blackmm', }], ['侠',{ color:'#eeeeee', nature:'qunmm', }], ['起',{ color:'#c3f9ff', nature:'thundermm', }], ['承',{ color:'#c3f9ff', nature:'thundermm', }], ['用间',{ color:'#c3f9ff', nature:'thundermm', }], ['战役篇',{ color:'#c3f9ff', nature:'thundermm', showName:'战', }], ['武将传',{ color:'#c3f9ff', nature:'thundermm', showName:'传', }], ['将',{ nature:'firemm', }], ['新杀',{ color:'#fefedc', nature:'metalmm', showName:'新', }], ['旧',{ color:'#a4a4a4', nature:'black', }], ['旧界',{ color:'#a4a4a4', nature:'black', }], ['节钺',{ color:'#a4a4a4', nature:'black', }], ['毅重',{ color:'#a4a4a4', nature:'black', }], ['★SP',{ showName:'★', }], ['K系列',{ showName:'K', }], ['经典',{ showName:'典', }], ['君',{ color:'#fefedc', nature:'shenmm', }], ['骰子',{ getSpan:()=>{ return `<span style="font-family:NonameSuits">🎲</span>`; } }], ['SP',{ getSpan:(prefix,name)=>{ return `<span style="writing-mode:horizontal-tb;-webkit-writing-mode:horizontal-tb;font-family:MotoyaLMaru;transform:scaleY(0.85)">SP</span>`; }, }], ['OL',{ getSpan:(prefix,name)=>{ return `<span style="writing-mode:horizontal-tb;-webkit-writing-mode:horizontal-tb;font-family:MotoyaLMaru;transform:scaleY(0.85)">OL</span>`; }, }], ['RE',{ getSpan:(prefix,name)=>{ return `<span style="writing-mode:horizontal-tb;-webkit-writing-mode:horizontal-tb;font-family:MotoyaLMaru;transform:scaleY(0.85)">RE</span>`; }, }], ['手杀',{ getSpan:(prefix,name)=>{ const simple=(lib.config.buttoncharacter_prefix=='simple'); if(lib.characterPack.shiji&&name in lib.characterPack.shiji){ for(let i in lib.characterSort.shiji){ if(lib.characterSort.shiji[i].includes(name)){ prefix=get.translation(i).slice(-1); break; } } if(simple) return `<span>${prefix}</span>`; return `<span style="color:#def7ca" data-nature="watermm">${prefix}</span>`; } if(simple) return '<span>手杀</span>'; return `<span style="font-family:NonameSuits">📱</span>`; }, }], ['TW',{ getSpan:(prefix,name)=>{ return `<span style="writing-mode:horizontal-tb;-webkit-writing-mode:horizontal-tb;font-family:MotoyaLMaru;transform:scaleY(0.85)">TW</span>`; }, }], ['TW神',{ getSpan:(prefix,name)=>{ return `${get.prefixSpan('TW')}${get.prefixSpan('神')}` }, }], ['TW将',{ getSpan:(prefix,name)=>{ return `${get.prefixSpan('TW')}${get.prefixSpan('将')}` }, }], ['OL神',{ getSpan:(prefix,name)=>{ return `${get.prefixSpan('OL')}${get.prefixSpan('神')}` }, }], ['旧神',{ getSpan:(prefix,name)=>{ return `${get.prefixSpan('旧')}${get.prefixSpan('神')}` }, }], ['旧晋',{ getSpan:(prefix,name)=>{ return `${get.prefixSpan('旧')}${get.prefixSpan('晋')}` }, }], ['新杀SP',{ getSpan:(prefix,name)=>{ return `${get.prefixSpan('新杀')}${get.prefixSpan('SP')}` }, }], ['界SP',{ getSpan:(prefix,name)=>{ return `${get.prefixSpan('界')}${get.prefixSpan('SP')}` }, }], ['S特神',{ getSpan:(prefix,name)=>{ return `${get.prefixSpan('★')}${get.prefixSpan('神')}` }, }], ]), groupnature:{ shen:'shen', wei:'water', shu:'soil', wu:'wood', qun:'qun', western:'thunder', key:'key', jin:'thunder', ye:'thunder', }, lineColor:new Map([ ['fire',[255,146,68]], ['yellow',[255,255,122]], ['blue',[150,202,255]], ['green',[141,255,216]], ['ice',[59,98,115]], ['thunder',[141,216,255]], ['kami',[90,118,99]], ['white',[255,255,255]], ['poison',[104,221,127]], ['brown',[195,161,223]], ['legend',[233,131,255]] ]), phaseName:['phaseZhunbei','phaseJudge','phaseDraw','phaseUse','phaseDiscard','phaseJieshu'], quickVoice:[ '我从未见过如此厚颜无耻之人!', '这波不亏', '请收下我的膝盖', '你咋不上天呢', '放开我的队友,冲我来', '你随便杀,闪不了算我输', '见证奇迹的时刻到了', '能不能快一点啊,兵贵神速啊', '主公,别开枪,自己人', '小内再不跳,后面还怎么玩儿啊', '你们忍心,就这么让我酱油了?', '我,我惹你们了吗', '姑娘,你真是条汉子', '三十六计,走为上,容我去去便回', '人心散了,队伍不好带啊', '昏君,昏君啊!', '风吹鸡蛋壳,牌去人安乐', '小内啊,您老悠着点儿', '不好意思,刚才卡了', '你可以打得再烂一点吗', '哥们,给力点儿行嘛', '哥哥,交个朋友吧', '妹子,交个朋友吧', ], other:{ ignore:()=>void 0 } }; const game={ //添加新的属性杀 addNature:(nature,translation,config)=>{ if(!nature) throw new TypeError(); if(translation&&translation.length) lib.translate['nature_'+nature]=translation; game.callHook("addNature",[nature,translation,config]); return nature; }, //判断卡牌信息/事件是否有某个属性 hasNature:(item,nature,player)=>{ var natures=get.natureList(item,player); if(!nature) return natures.length>0; if(nature=='linked') return natures.some(n=>lib.linked.includes(n)); return get.is.sameNature(natures,nature); }, //设置卡牌信息/事件的属性 setNature:(item,nature,addNature)=>{ if(!nature) nature=[]; if(!addNature){ item.nature=get.nature(nature); if(!item.nature.length) delete item.nature; } else{ let natures=Array.isArray(nature)?nature:nature.split(lib.natureSeparator); let _nature=get.natureList(item,false); _nature.addArray(natures); item.nature=_nature.join(lib.natureSeparator); } return item.nature; }, //洗牌 washCard:()=>{ if(!ui.cardPile.hasChildNodes()&&!ui.discardPile.hasChildNodes()) return false; if(_status.maxShuffle!=undefined){ if(_status.maxShuffle==0){ if(_status.maxShuffleCheck){ game.over(_status.maxShuffleCheck()); } else{ game.over('平局'); } return []; } _status.maxShuffle--; } game.shuffleNumber++; const cards=Array.from(ui.cardPile.childNodes); if(_status.discarded){ _status.discarded.length=0; } for(let i=0;i<ui.discardPile.childNodes.length;i++){ var currentcard=ui.discardPile.childNodes[i]; currentcard.vanishtag.length=0; if(get.info(currentcard).vanish||currentcard.storage.vanish){ currentcard.remove(); continue; } cards.push(currentcard); } cards.randomSort(); return game.cardsGotoPile(cards,'triggeronly','washCard',['shuffleNumber',game.shuffleNumber]) }, //addGroup //基于钩子的添加势力方法 addGroup:(id,short,name,config)=>{ if(!id) throw new TypeError(); if(lib.comparator.typeEquals(short,"object")){ config=short; short=null; } if(lib.comparator.typeEquals(name,"object")){ config=name; name=null; } if(!lib.comparator.typeEquals(short,"string")&&short){ name=short; } lib.group.add(id); if(short)lib.translate[id] = short; if(name)lib.translate[`${id}2`] = name; game.callHook("addGroup",[id,short,name,config]); return id; }, //通用的调用钩子函数 callHook:(name,args)=>{ const callHook=()=>{ for(const hook of lib.hooks[name]){ if(hook!=null&&typeof hook=="function"){ hook(...args); } } } if ("onload" in lib) lib.onload.add(callHook); else callHook(); }, //Yingbian //应变 yingbianEffect:function(event,content){ const yingbianEffect=game.createEvent('yingbianEffect'); yingbianEffect.player=event.player; yingbianEffect.card=event.card; yingbianEffect._trigger=event; yingbianEffect.setContent(content); yingbianEffect._args=Array.from(arguments); return yingbianEffect; }, setYingbianConditionColor:(yingbianCondition,color)=>game.broadcastAll((yingbianCondition,color)=>lib.yingbian.condition.color.set(yingbianCondition,color),yingbianCondition,color), setComplexYingbianCondition:(yingbianCondition,condition)=>game.broadcastAll((yingbianCondition,condition)=>lib.yingbian.condition.complex.set(yingbianCondition,condition),yingbianCondition,condition), setSimpleYingbianCondition:(yingbianCondition,condition)=>game.broadcastAll((yingbianCondition,condition)=>lib.yingbian.condition.simple.set(yingbianCondition,condition),yingbianCondition,condition), setYingbianEffect:(yingbianEffect,effect)=>game.broadcastAll((yingbianEffect,effect)=>lib.yingbian.effect.set(yingbianEffect,effect),yingbianEffect,effect), setYingbianPrompt:(yingbian,prompt)=>game.broadcastAll((yingbian,prompt)=>lib.yingbian.prompt.set(yingbian,prompt),yingbian,prompt), //动态CSS from libnodiz dynamicStyle:{ init:()=>{ const that=game.dynamicStyle; that._cache={}; that._cache.rules=[]; that._cache.style=document.createElement("style"); that._cache.style.id="game.dynamicStyle"; document.head.appendChild(that._cache.style); that._cache.sheet = that._cache.style.sheet; delete game.dynamicStyle.init; return true; }, translate:style=>{ let result=[]; for(const name in style){ result.push(`${name.replace(/([A-Z])/g, match => `-${match.toLowerCase()}`)}: ${style[name]};`); } return result.join(" "); }, generate:(name, style)=>[`${name} {`, game.dynamicStyle.translate(style), "}"].join(" "), has:name=>game.dynamicStyle._cache.rules.some(item=>item[0]==name), get:name=>game.dynamicStyle.find(item=>item[0]==name)[1], find:fn=>game.dynamicStyle._cache.rules.find(fn), size:()=>game.dynamicStyle._cache.rules.length, indexOf:name=>{ for (let i=0;i<game.dynamicStyle._cache.rules.length;++i){ if(name==game.dynamicStyle._cache.rules[i][0]) return i; } return -1; }, add:(name,style)=>{ const that=game.dynamicStyle; return that.update(name,that.has(name)?Object.assign({},that.get(name),style):style); }, addObject:object=>{ const that=game.dynamicStyle; let result=[]; for(const name in object){ result.push(that.add(name, object[name])); } return result; }, remove:name=>{ const that=game.dynamicStyle; if(!that.has(name)) return false; const index=that.indexOf(name); that._cache.rules.splice(index,1); that._cache.sheet.deleteRule(index); return true; }, update:(name,style)=>{ const that=game.dynamicStyle; try{ if(that.has(name)){ const index=that.indexOf(name); that._cache.sheet.deleteRule(index); that._cache.sheet.insertRule(that.generate(name,style),index); that._cache.rules[index] = [name, style]; }else{ const index=that._cache.rules.length; that._cache.rules.push([name,style]); that._cache.sheet.insertRule(that.generate(name,style),index); } return true; } catch(e){ console.log(e); return false; } } }, //Add a background music to the config option //在设置选项中添加一首背景音乐 addBackgroundMusic:(link,musicName,aozhan)=>{ const backgroundMusicSetting=ui[aozhan?'aozhan_bgm':'background_music_setting'],menu=backgroundMusicSetting._link.menu,config=backgroundMusicSetting._link.config; if(typeof musicName!='string') musicName=link; if(aozhan) lib.mode.guozhan.config.aozhan_bgm.item[link]=musicName; else lib.config.all.background_music.add(link); config.item[link]=musicName; const textMenu=ui.create.div('',musicName,menu,function(){ const node=this.parentNode._link,config=node._link.config; node._link.current=this.link; const tmpName=node.lastChild.innerHTML; node.lastChild.innerHTML=config.item[this._link]; if(config.onclick&&config.onclick.call(node,this._link,this)===false) node.lastChild.innerHTML=tmpName; if(config.update) config.update(); },menu.childElementCount-2); textMenu._link=link; config.updatex.call(backgroundMusicSetting,[]); }, //Remove a background music from the config option //从设置选项中移除一首背景音乐 removeBackgroundMusic:(link,aozhan)=>{ if(aozhan){ if(['disabled','random'].includes(link)) return; delete lib.mode.guozhan.config.aozhan_bgm.item[link]; if(!Array.isArray(_status.aozhanBGMToRemove)) _status.aozhanBGMToRemove=[]; _status.aozhanBGMToRemove.add(link); } else{ if(['music_off','music_custom','music_random'].includes(link)) return; lib.config.all.background_music.remove(link); } const backgroundMusicSetting=ui[aozhan?'aozhan_bgm':'background_music_setting'],config=backgroundMusicSetting._link.config; config.updatex.call(backgroundMusicSetting,[]); }, updateBackground:()=>{ const background=_status.tempBackground||lib.config.image_background; ui.background.delete(); const uiBackground=ui.background=ui.create.div('.background'),style=uiBackground.style; if(lib.config.image_background_blur){ style.filter='blur(8px)'; style.webkitFilter='blur(8px)'; style.transform='scale(1.05)'; } document.body.insertBefore(uiBackground,document.body.firstChild); if(background.startsWith('db:')) uiBackground.setBackgroundDB(background.slice(3)); else if(background.startsWith('ext:')) uiBackground.setBackgroundImage(`extension/${background.slice(4)}`); else if(background=='default'){ uiBackground.animate('start'); style.backgroundImage='none'; } else if(background.startsWith('custom_')){ style.backgroundImage='none'; game.getDB('image',background).then(fileToLoad=>{ if(!fileToLoad) return; const fileReader = new FileReader(); fileReader.onload=fileLoadedEvent=>style.backgroundImage=`url(${fileLoadedEvent.target.result})`; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } else uiBackground.setBackgroundImage(`image/background/${background}.jpg`); style.backgroundSize='cover'; style.backgroundPosition='50% 50%'; }, //Generate a beatmap using the given BPM, beats, and offset //用给定的BPM、节拍和偏移生成谱面 generateBeatmapTimeleap:(bpm,beats,offset)=>beats.map(value=>Math.round(value*60000/bpm+(offset||0))), updateRenku:function(){ game.broadcast(function(renku){ _status.renku=renku; },_status.renku); for(var i of game.players){ if(i.storage.renku) i.markSkill('renku'); } }, loseAsync:function(arg){ var next=game.createEvent('loseAsync'); next.forceDie=true; next.getd=function(player,key,position){ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); }); return cards; }; next.getl=function(player){ const that=this; const map={ player:player, hs:[], es:[], js:[], ss:[], xs:[], cards:[], cards2:[], gaintag_map:{}, }; player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); map.js.addArray(evt.js); map.ss.addArray(evt.ss); map.xs.addArray(evt.xs); map.cards.addArray(evt.cards); map.cards2.addArray(evt.cards2); for(let key in evt.gaintag_map){ if(!map.gaintag_map[key]) map.gaintag_map[key]=[]; map.gaintag_map[key].addArray(evt.gaintag_map[key]); } } }); return map; }; next.getg=function(player){ var that=this; var cards=[]; player.checkHistory('gain',function(evt){ if(evt.parent==that){ cards.addArray(evt.cards); } }); return cards; }; if(arg&&get.is.object(arg)){ for(var i in arg) next[i]=arg[i]; } return next; }, callFuncUseStepCache:function(prefix,func,params){ if(typeof func != 'function')return; if(_status.closeStepCache || !_status.event)return func.apply(null,params); var cacheKey = "["+prefix+"]"+get.paramToCacheKey.apply(null,params); var ret = _status.event.getStepCache(cacheKey); if(ret === undefined || ret === null){ ret = func.apply(null,params); _status.event.putStepCache(cacheKey,ret); } return ret; }, getRarity:function(name){ var rank=lib.rank.rarity; if(rank.legend.contains(name)) return 'legend'; if(rank.epic.contains(name)) return 'epic'; if(rank.rare.contains(name)) return 'rare'; if(get.mode()!='chess'&&rank.junk.contains(name)) return 'junk'; return 'common'; }, hasGlobalHistory:function(key,filter,last){ if(!key) return _status.globalHistory[_status.globalHistory.length-1]; if(!filter) return _status.globalHistory[_status.globalHistory.length-1][key]; else{ const history=game.getGlobalHistory(key); if(last){ const lastIndex=history.indexOf(last); return history.some((event,index)=>{ if(index>lastIndex) return false; return filter(event); }); } else{ return history.some(filter); } } }, checkGlobalHistory:function(key,filter,last){ if(!key) return _status.globalHistory[_status.globalHistory.length-1]; if(!filter) return _status.globalHistory[_status.globalHistory.length-1][key]; else{ const history=game.getGlobalHistory(key); if(last){ const lastIndex=history.indexOf(last); history.forEach((event,index)=>{ if(index>lastIndex) return false; return filter(event); }); } else{ history.forEach(filter); } } }, getGlobalHistory:function(key,filter,last){ if(!key) return _status.globalHistory[_status.globalHistory.length-1]; if(!filter) return _status.globalHistory[_status.globalHistory.length-1][key]; else{ const history=game.getGlobalHistory(key); if(last){ const lastIndex=history.indexOf(last); return history.filter((event,index)=>{ if(index>lastIndex) return false; return filter(event); }) } return history.filter(filter); } }, hasAllGlobalHistory:function(key,filter,last){ if(!key||!filter) return; const stopped=false; _status.globalHistory.forEach(value=>{ if(value[key]){ if(last&&value[key].includes(last)&&!stopped){ stopped=true; const lastIndex=value[key].indexOf(last); if(value[key].some((event,index)=>{ if(index>lastIndex) return false; return filter(event); })) return true; } else{ if(value[key].some(filter)) return true; } } }) }, checkAllGlobalHistory:function(key,filter,last){ if(!key||!filter) return; const stopped=false; _status.globalHistory.forEach(value=>{ if(value[key]){ if(last&&value[key].includes(last)&&!stopped){ stopped=true; const lastIndex=value[key].indexOf(last); value[key].forEach((event,index)=>{ if(index>lastIndex) return false; return filter(event); }); } else{ value[key].forEach(filter); } } }) }, getAllGlobalHistory:function(key,filter,last){ const history=[]; _status.globalHistory.forEach(value=>{ if(!key||!value[key]){ history.push(value); } else{ history.push(...value[key]); } }) if(filter){ if(last){ const lastIndex=history.indexOf(last); return history.filter(function(event,index){ if(index>lastIndex) return false; return filter(event); }); } return history.filter(filter); } return history; }, cardsDiscard:function(cards){ var type=get.itemtype(cards); if(type!='cards'&&type!='card') return; var next=game.createEvent('cardsDiscard'); next.cards=type=='cards'?cards.slice(0):[cards]; next.setContent('cardsDiscard'); next.getd=function(player,key,position){ return this.cards.slice(0); }; return next; }, cardsGotoOrdering:function(cards){ var type=get.itemtype(cards); if(type!='cards'&&type!='card') return; var next=game.createEvent('cardsGotoOrdering'); next.cards=type=='cards'?cards.slice(0):[cards]; next.setContent('cardsGotoOrdering'); return next; }, cardsGotoSpecial:function(cards,bool){ var type=get.itemtype(cards); if(type!='cards'&&type!='card') return; var next=game.createEvent('cardsGotoSpecial'); next.cards=type=='cards'?cards.slice(0):[cards]; if(bool=='toRenku') next.toRenku=true; else if(bool===false) next.notrigger=true; next.setContent('cardsGotoSpecial'); return next; }, cardsGotoPile:function(){ const cards=[]; const next=game.createEvent('cardsGotoPile'); next.cards=cards; for(let i=0;i<arguments.length;i++){ let arg=arguments[i],itemtype=get.itemtype(arg); if(itemtype=='cards'){ cards.addArray(arg); } else if(itemtype=='card'){ cards.add(arg); } else if(typeof arg=='function'){ next.insert_index=arg; } else if(typeof arg=='string'){ if(arg=='insert') next.insert_card=true; else if(arg=='washCard') next.washCard=true; else if(arg=='triggeronly') next._triggeronly=true; } else if(Array.isArray(arg)&&arg.length==2&&typeof arg[0]=='string'){ next.set(arg[0],arg[1]); } } if(!cards.length){ _status.event.next.remove(next); } else{ next.setContent('cardsGotoPile'); if(next._triggeronly) game.$cardsGotoPile(next); } return next; }, $cardsGotoPile:function(event){ const cards=event.cards; const pile=ui.cardPile; for(let i=0;i<cards.length;i++){ if(event.insert_index){ cards[i].fix(); pile.insertBefore(cards[i],event.insert_index(event,cards[i])); } else if(event.insert_card){ cards[i].fix(); pile.insertBefore(cards[i],pile.firstChild); } else{ cards[i].fix(); pile.appendChild(cards[i]); } } game.updateRoundNumber(); }, online:false, onlineID:null, onlineKey:null, showHistory:function(pause){ if(lib.config.show_history=='left'){ ui.window.classList.add('leftbar'); } else if(lib.config.show_history=='right'){ ui.window.classList.add('rightbar'); } if(pause!=false&&ui.pause){ ui.pause.show(); } }, createBackground:function(src,blur){ var current=document.body.querySelector('.background.upper'); if(current){ current.delete(); } var node=ui.create.div('.background.blurbg',document.body); node.setBackgroundImage(src); node.style.backgroundSize='cover'; if(blur){ node.classList.add('paused') } return node; }, changeLand:(url,player)=>{ game.addVideo('changeLand',player,url); const parsedPath=lib.path.parse(url); delete parsedPath.base; if(!parsedPath.dir) parsedPath.dir='image/card/'; if(!parsedPath.ext) parsedPath.ext='.jpg'; game.broadcastAll((formattedPath,name,skill,player)=>{ const node=ui.create.div('.background.upper.land'); node.setBackgroundImage(formattedPath); node.destroy=()=>{ if (node.skill) { game.removeGlobalSkill(node.skill); if(node.system) node.system.remove(); } node.classList.add('hidden'); setTimeout(()=>node.remove(),3000); if(ui.land==node) ui.land=null; } if(ui.land){ document.body.insertBefore(node,ui.land); ui.land.destroy(); } else{ node.classList.add('hidden'); document.body.insertBefore(node,ui.window); ui.refresh(node); node.classList.remove('hidden'); } ui.land=node; if(!name) return; node.name=name; node.skill=skill; if(player){ node.player=player; player.addTempSkill('land_used'); } lib.setPopped(node.system=ui.create.system(lib.translate[skill],null,true,true),()=>{ const uiIntro=ui.create.dialog('hidden'); uiIntro.addText(player?`来源:${get.translation(player)}`:'地图').style.margin='0'; uiIntro._place_text=uiIntro.add(ui.create.div('.text',lib.translate[`${skill}_info`])); uiIntro.add(ui.create.div('.placeholder.slim')); return uiIntro; },200); game.addGlobalSkill(skill); },lib.path.format(parsedPath),parsedPath.name,`${name}_skill`,player); }, checkFileList:function(updates,proceed){ var n=updates.length; if(!n){ proceed(n); } for(var i=0;i<updates.length;i++){ if(lib.node&&lib.node.fs){ lib.node.fs.access(__dirname+'/'+updates[i],(function(entry){ return function(err){ if(!err){ var stat=lib.node.fs.statSync(__dirname+'/'+entry); if(stat.size==0){ err=true; } } if(err){ n--; if(n==0){ proceed(); } } else{ n--; updates.remove(entry); if(n==0){ proceed(); } } } }(updates[i]))); } else{ resolveLocalFileSystemURL(lib.assetURL+updates[i],(function(name){ return function(entry){ n--; updates.remove(name); if(n==0){ proceed(); } } }(updates[i])),function(){ n--; if(n==0){ proceed(); } }); } } }, replaceHandcards:function(){ var next=game.createEvent('replaceHandcards'); if(Array.isArray(arguments[0])){ next.players=arguments[0]; } else{ next.players=[]; for(var i=0;i<arguments.length;i++){ if(get.itemtype(arguments[i])=='player'){ next.players.push(arguments[i]); } } } if(_status.connectMode){ next.setContent('replaceHandcardsOL'); } else{ next.setContent('replaceHandcards'); } }, removeCard:function(name){ for(var i=0;i<lib.card.list.length;i++){ if(lib.card.list[i][2]==name){ lib.card.list.splice(i--,1); } } var list=[]; for(var i=0;i<ui.cardPile.childElementCount;i++){ if(ui.cardPile.childNodes[i].name==name){ list.push(ui.cardPile.childNodes[i]); } } for(var i=0;i<list.length;i++){ list[i].remove(); } }, randomMapOL:function(type){ if(type=='hidden'){ ui.arena.classList.add('playerhidden'); } game.prepareArena(); if(window.isNonameServer){ game.me=ui.create.player(); } var list=[]; for(var i=0;i<game.players.length;i++){ if(game.players[i]!=game.me){ list.push(game.players[i]); } } var map=[]; for(var i=0;i<lib.node.clients.length;i++){ if(!list.length) break; var current=list.randomRemove(); current.ws=lib.node.clients[i]; current.playerid=current.ws.id; current.nickname=current.ws.nickname; current.setNickname(); } if(!window.isNonameServer){ game.me.playerid=get.id(); game.me.nickname=get.connectNickname(); game.me.setNickname(); } for(var i=0;i<game.players.length;i++){ if(!game.players[i].playerid){ game.players[i].playerid=get.id(); } map.push([game.players[i].playerid,game.players[i].nickname]); lib.playerOL[game.players[i].playerid]=game.players[i]; } game.broadcast(function(map,config,hidden){ if(hidden){ ui.arena.classList.add('playerhidden'); } lib.configOL=config; ui.create.players(); ui.create.me(); game.me.playerid=game.onlineID; game.me.nickname=get.connectNickname(); for(var i=0;i<map.length;i++){ if(map[i][0]==game.me.playerid){ map=map.concat(map.splice(0,i)); break; } } for(var i=0;i<game.players.length;i++){ game.players[i].playerid=map[i][0]; game.players[i].nickname=map[i][1]; game.players[i].setNickname(); lib.playerOL[game.players[i].playerid]=game.players[i]; } _status.mode=lib.configOL[lib.configOL.mode+'_mode']; },map,lib.configOL,type=='hidden'); _status.mode=lib.configOL[lib.configOL.mode+'_mode']; game.chooseCharacterOL(); }, closeMenu:function(){ if(ui.menuContainer&&!ui.menuContainer.classList.contains('hidden')){ ui.click.configMenu(); } }, closeConnectMenu:function(){ if(ui.connectMenuContainer&&!ui.connectMenuContainer.classList.contains('hidden')){ ui.click.connectMenu(); } }, closePopped:function(){ if(ui.currentpopped){ if(ui.currentpopped._uiintro){ ui.currentpopped._uiintro.delete(); delete ui.currentpopped._uiintro; } delete ui.currentpopped; } }, broadcast:function(){ if(!lib.node||!lib.node.clients||game.online) return; for(var i=0;i<lib.node.clients.length;i++){ if(lib.node.clients[i].inited){ lib.node.clients[i].send.apply(lib.node.clients[i],arguments); } } }, broadcastAll:function(){ if(game.online) return; var argc=arguments.length; var args=new Array(argc); for(var i=0;i<argc;i++){ args[i]=arguments[i]; } game.broadcast.apply(this,args); var func=args.shift(); if(typeof func=='string'){ func=lib.message.client[func]; } if(typeof func=='function'){ func.apply(this,args); } }, syncState:function(){ var state=null; if(game.getState){ state=game.getState(); } game.broadcast(function(state,current,number){ if(game.updateState&&state) game.updateState(state); _status.currentPhase=current; game.phaseNumber=number; },state,_status.currentPhase,game.phaseNumber); }, updateWaiting:function(){ var map=[]; for(var i=0;i<game.connectPlayers.length;i++){ var player=game.connectPlayers[i]; if(player.playerid){ if(!game.onlinezhu){ game.onlinezhu=player.playerid; game.send('server','changeAvatar',player.nickname,player.avatar); _status.onlinenickname=player.nickname; _status.onlineavatar=player.avatar; } map[i]=[player.nickname,player.avatar,player.playerid]; if(player.playerid==game.onlinezhu){ map[i].push('zhu'); } } else if(player.classList.contains('unselectable2')){ map[i]='disabled'; } else{ map[i]=null; } } game.broadcast('updateWaiting',map); }, waitForPlayer:function(func){ var next=game.createEvent('waitForPlayer',false); next.func=func; next.setContent('waitForPlayer'); }, countDown:function(time,onEnd){ time=parseInt(time); if(!time) return; if(time<=0) return; var current=time; ui.timer.set(current,1); _status.countDown=setInterval(function(){ if(--current){ ui.timer.set(current,current/time); } else{ ui.timer.set(0,0); clearInterval(_status.countDown); delete _status.countDown; if(onEnd) onEnd(); } },1000); }, countChoose:function(clear){ if(_status.imchoosing){ return; } _status.imchoosing=true; if(_status.connectMode&&!_status.countDown){ ui.timer.show(); var num; //这么一大行都是为了祢衡 if(_status.event&&_status.event.name=='chooseToUse'&&_status.event.type=='phase'&& _status.event.player&&_status.event.player.forceCountChoose&& typeof _status.event.player.forceCountChoose.phaseUse=='number'){ num=_status.event.player.forceCountChoose.phaseUse; } else if(_status.connectMode){ num=lib.configOL.choose_timeout; } else{ num=get.config('choose_timeout'); } game.countDown(parseInt(num),function(){ ui.click.auto(); ui.timer.hide(); }); if(!game.online&&game.me){ if(_status.event.getParent().skillHidden){ for(var i=0;i<game.players.length;i++){ game.players[i].showTimer(); } game.me._hide_all_timer=true; } else if(!_status.event._global_waiting){ game.me.showTimer(); } } } else if(_status.event.player.forceCountChoose&&_status.event.isMine()&&!_status.countDown){ var info=_status.event.player.forceCountChoose; var num; if(_status.event.name=='chooseToUse'&&_status.event.type=='phase'&&typeof info.phaseUse=='number'){ num=info.phaseUse; } else if(typeof info[_status.event.name]=='number'){ num=info[_status.event.name] } else if(info.default){ num=info.default; } else return; var finish=function(){ if(_status.event.endButton){ if(_status.event.skill){ ui.click.cancel(); } ui.click.cancel(); } else{ if(ui.confirm&&ui.confirm.str){ if(ui.confirm.str.includes('c')){ ui.click.cancel(); } else if(ui.confirm.str.includes('o')){ ui.click.ok(); } } else if(['chooseControl','chooseBool'].contains(_status.event.name)&&_status.paused){ _status.event.result='ai'; game.resume(); } else{ ui.click.auto('forced'); setTimeout(function(){ ui.click.auto('forced'); },200); } } ui.timer.hide(); }; if(!num){ ui.timer.hide(); game.uncheck(); setTimeout(finish,200); } else{ ui.timer.show(); game.countDown(num,finish); } } }, stopCountChoose:function(){ if(_status.countDown){ clearInterval(_status.countDown); delete _status.countDown; ui.timer.hide(); } if(_status.connectMode&&!game.online&&game.me){ if(game.me._hide_all_timer){ delete game.me._hide_all_timer; for(var i=0;i<game.players.length;i++){ game.players[i].hideTimer(); } } else if(!_status.event._global_waiting){ game.me.hideTimer(); } } }, connect:function(ip,callback){ if(game.online) return; var withport=false; var index=ip.lastIndexOf(':'); if(index!=-1){ index=parseFloat(ip.slice(index+1)); if(index&&Math.floor(index)==index){ withport=true; } } if(!withport){ ip=ip+':8080'; } _status.connectCallback=callback; try{ if(game.ws){ game.ws._nocallback=true; game.ws.close(); delete game.ws; } var str=''; if(!ip.startsWith('wss://')&&!ip.startsWith('ws://')) str=(get.config('wss_mode','connect')?'wss://':'ws://'); game.ws=new WebSocket(str+ip+''); } catch(e){ alert('错误:无效联机地址'); if(callback){ callback(false); } return; } game.ws.onopen=lib.element.ws.onopen; game.ws.onmessage=lib.element.ws.onmessage; game.ws.onerror=lib.element.ws.onerror; game.ws.onclose=lib.element.ws.onclose; _status.ip=ip; }, send:function(){ if(game.observe&&arguments[0]!='reinited') return; if(game.ws){ var args=Array.from(arguments); if(typeof args[0]=='function'){ args.unshift('exec'); } game.ws.send(JSON.stringify(get.stringifiedResult(args))); } }, sendTo:function(id,message){ var ws={wsid:id}; for(var i in lib.element.nodews){ ws[i]=lib.element.nodews[i]; } var client={ ws:ws, id:ws.wsid, closed:false }; for(var i in lib.element.client){ client[i]=lib.element.client[i]; } client.send(message); }, createServer:function(){ lib.node.clients=[]; lib.node.banned=[]; lib.node.observing=[]; lib.node.torespond={}; lib.node.torespondtimeout={}; lib.playerOL={}; lib.cardOL={}; lib.wsOL={}; ui.create.roomInfo(); ui.create.chat(); if(game.onlineroom){ } else{ var WebSocketServer=require('ws').Server; var wss=new WebSocketServer({port:8080}); game.ip=get.ip(); wss.on('connection',lib.init.connection); } }, playAudio:function(){ if(_status.video&&arguments[1]!='video') return; let path='',emptyPath=true,notCheckDBPath=true,onError=null; for(const argument of arguments){ if(typeof argument==='string'||typeof argument=='number'){ if(emptyPath) emptyPath=false; else if(notCheckDBPath){ notCheckDBPath=false; if(/^db:extension-[^:]*$/.test(path)) path+=':'; else path+='/'; } else path+='/'; path+=argument; } else if(typeof argument=='function') onError=argument; if(_status.video) break; } if(path.startsWith('ext:')) path=path.replace(/^ext:/,'extension/'); else if(!path.startsWith('db:')) path=`audio/${path}`; if(!lib.config.repeat_audio&&_status.skillaudio.contains(path)) return; _status.skillaudio.add(path); game.addVideo('playAudio',null,path); setTimeout(()=>_status.skillaudio.remove(path),1000); const audio=document.createElement('audio'); audio.autoplay=true; audio.volume=lib.config.volumn_audio/8; audio.addEventListener('ended',()=>audio.remove()); audio.onerror=event=>{ audio.remove(); if(onError) onError(event); }; //Some browsers do not support "autoplay", so "oncanplay" listening has been added audio.oncanplay=()=>Promise.resolve(audio.play()).catch(()=>void 0); new Promise((resolve,reject)=>{ if(path.startsWith('db:')) game.getDB('image',path.slice(3)).then(octetStream=>resolve(get.objectURL(octetStream)),reject); else if(lib.path.extname(path)) resolve(`${lib.assetURL}${path}`); else resolve(`${lib.assetURL}${path}.mp3`); }).then(resolvedPath=>{ audio.src=resolvedPath; ui.window.appendChild(audio); }); return audio; }, trySkillAudio:function(skill,player,directaudio){ game.broadcast(game.trySkillAudio,skill,player,directaudio); var info=get.info(skill); if(!info) return; if(!lib.config.background_speak) return; if(typeof player=='string') player={name:player}; else{ if(info.direct&&!directaudio) return; if(lib.skill.global.includes(skill)&&!lib.skill[skill].forceaudio) return; } var audioName=skill; var audioInfo=info.audio; var fixedNum; if(info.audioname2){ if(info.audioname2[player.name]){ audioName+='_'+player.name; audioInfo=info.audioname2[player.name]; } else if(info.audioname2[player.name1]){ audioName+='_'+player.name1; audioInfo=info.audioname2[player.name1]; } else if(info.audioname2[player.name2]){ audioName+='_'+player.name2; audioInfo=info.audioname2[player.name2]; } } var history=[]; while(true){//可以嵌套引用了 if(history.includes(audioName)) break; history.push(audioName); if(typeof audioInfo=='string'&&lib.skill[audioInfo]){ audioName=audioInfo; audioInfo=lib.skill[audioName].audio; continue; } if(Array.isArray(audioInfo)){ audioName=audioInfo[0]; if(!fixedNum) fixedNum=audioInfo[1];//数组会取第一个指定语音数 // TODO: 判断不完整,但现在无合适的方法,先放着 @kuangshen04 if(audioName in lib.skill) audioInfo=lib.skill[audioName].audio; else audioInfo=parseInt(fixedNum); continue; } break; } if(Array.isArray(info.audioname)&&player){ if(info.audioname.includes(player.name)&&(!info.audioname2||!info.audioname2[player.name])) audioName+='_'+player.name; else if(info.audioname.includes(player.name1)&&(!info.audioname2||!info.audioname2[player.name1])) audioName+='_'+player.name1; else if(info.audioname.includes(player.name2)&&(!info.audioname2||!info.audioname2[player.name2])) audioName+='_'+player.name2; } if(typeof audioInfo=='string'){ if(audioInfo.startsWith('db:')){ audioInfo=audioInfo.split(':'); if(audioInfo.length<4) return; if(audioInfo[3]=='true') game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,audioInfo[2],`${audioName}.${audioInfo[4]||'mp3'}`); else{ audioInfo[3]=fixedNum?Math.min(parseInt(audioInfo[3]),fixedNum):parseInt(audioInfo[3]); if(!audioInfo[3]) return; game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,audioInfo[2],`${audioName}${Math.floor(audioInfo[3]*Math.random())+1}.${audioInfo[4]||'mp3'}`); } } else if(audioInfo.startsWith('ext:')){ audioInfo=audioInfo.split(':'); if(audioInfo.length<3) return; if(audioInfo[2]=='true') game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${audioName}.${audioInfo[3]||'mp3'}`); else{ audioInfo[2]=fixedNum?Math.min(parseInt(audioInfo[2]),fixedNum):parseInt(audioInfo[2]); if(!audioInfo[2]) return; game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${audioName}${Math.floor(audioInfo[2]*Math.random())+1}.${audioInfo[3]||'mp3'}`); } } } else if(typeof audioInfo=='number'){ if(fixedNum) audioInfo=Math.min(audioInfo, fixedNum); game.playAudio('skill',`${audioName}${Math.floor(audioInfo*Math.random())+1}`); } //直接指定配音文件名的新格式 else if(typeof audioInfo=="object"){ if(!("type" in audioInfo&&audioInfo.type=="direct"&&"files" in audioInfo)) return; let audioFiles=audioInfo.files; if(typeof audioFiles!="object") return; if(!Array.isArray(audioFiles)){ if(!player) return; if(player.name&&player.name in audioFiles&&(!info.audioname2||!info.audioname2[player.name]))audioFiles=audioFiles[player.name]; else if(player.name1&&player.name1 in audioFiles&&(!info.audioname2||!info.audioname2[player.name1]))audioFiles=audioFiles[player.name1]; else if(player.name2&&player.name2 in audioFiles&&(!info.audioname2||!info.audioname2[player.name2]))audioFiles=audioFiles[player.name2]; } if(!Array.isArray(audioFiles)) return; let length=audioFiles.length; if(fixedNum)length=Math.min(length,fixedNum); //game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${audioName}${+1}.${audioInfo[3]||'mp3'}`); game.playAudio(audioFiles[Math.floor(length*Math.random())]); } else if(audioInfo) game.playAudio('skill',audioName); else if(info.audio!==false) game.playSkillAudio(audioName); }, playSkillAudio:function(name,index){ if(_status.video&&arguments[1]!='video') return; if(!lib.config.repeat_audio&&_status.skillaudio.includes(name)) return; game.addVideo('playSkillAudio',null,name); if(name.indexOf('|')<name.lastIndexOf('|')){ name=name.slice(name.lastIndexOf('|')+1); } _status.skillaudio.add(name); setTimeout(function(){ _status.skillaudio.remove(name); },1000); var str='audio/skill/'; var audio=document.createElement('audio'); audio.autoplay=true; audio.volume=lib.config.volumn_audio/8; audio.src=lib.assetURL+str+name+'.mp3'; audio.addEventListener('ended',function(){ this.remove(); }); if(typeof index!='number'){ index=Math.ceil(Math.random()*2); } audio._changed=1; audio.onerror=function(){ switch(this._changed){ case 1:{ audio.src=lib.assetURL+str+name+'.ogg'; this._changed=2; break; } case 2:{ audio.src=lib.assetURL+str+name+index+'.mp3'; this._changed=3; break; } case 3:{ audio.src=lib.assetURL+str+name+index+'.ogg'; this._changed=4; break; } default:{ this.remove(); } } }; //Some browsers do not support "autoplay", so "oncanplay" listening has been added audio.oncanplay=function(){ Promise.resolve(this.play()).catch(()=>void 0); }; ui.window.appendChild(audio); }, playBackgroundMusic:()=>{ if(lib.config.background_music=='music_off'){ ui.backgroundMusic.src=''; return; } if(_status._aozhan){ const aozhanBGMConfiguration=lib.config.mode_config.guozhan.aozhan_bgm; if(aozhanBGMConfiguration=='disabled') return; let aozhan=_status.tempAozhan||aozhanBGMConfiguration; if(Array.isArray(aozhan)) aozhan=aozhan.randomGet('disabled',_status.currentAozhan)||aozhanBGMConfiguration; if(aozhan=='random') aozhan=Object.keys(lib.mode.guozhan.config.aozhan_bgm.item).randomGet('disabled','random',_status.currentAozhan); _status.currentAozhan=aozhan; if(aozhan.startsWith('db:')) game.getDB('image',aozhan.slice(3)).then(result=>ui.backgroundMusic.src=result); else if(aozhan.startsWith('ext:')) ui.backgroundMusic.src=`${lib.assetURL}extension/${aozhan.slice(4)}`; else ui.backgroundMusic.src=`${lib.assetURL}audio/background/aozhan_${aozhan}.mp3`; return; } let music=_status.tempMusic||lib.config.background_music; if(Array.isArray(music)) music=music.randomGet('music_off',_status.currentMusic)||lib.config.background_music; if(music=='music_random') music=lib.config.all.background_music.randomGet('music_off','music_random',_status.currentMusic); _status.currentMusic=music; if(music=='music_custom'){ const backgroundMusicSourceConfiguration=lib.config.background_music_src; if(backgroundMusicSourceConfiguration) ui.backgroundMusic.src=backgroundMusicSourceConfiguration; return; } if(music.startsWith('db:')) game.getDB('image',music.slice(3)).then(result=>ui.backgroundMusic.src=result); else if(music.startsWith('ext:')) ui.backgroundMusic.src=`${lib.assetURL}extension/${music.slice(4)}`; else ui.backgroundMusic.src=`${lib.assetURL}audio/background/${music}.mp3`; }, import:function(type,content,url){ if(type=='extension'){ const promise=game.loadExtension(content); if(typeof _status.extensionLoading=="undefined")_status.extensionLoading=[]; _status.extensionLoading.add(promise); return promise; } else{ if(!lib.imported[type])lib.imported[type]={}; const promise=Promise.resolve((gnc.is.generator(content)?gnc.of(content):content)(lib,game,ui,get,ai,_status)).then(content2=>{ if(content2.name){ lib.imported[type][content2.name]=content2; delete content2.name; } }); if(typeof _status.importing=="undefined")_status.importing={}; if(!_status.importing[type])_status.importing[type]=[]; _status.importing[type].add(promise); return promise; } }, loadExtension:gnc.of(function*(object){ let noEval=false; if(typeof object=='function'){ object=yield (gnc.is.generatorFunc(object)?gnc.of(object):object)(lib,game,ui,get,ai,_status); noEval=true; } const name=object.name,extensionName=`extension_${name}`,extensionMenu=lib.extensionMenu[extensionName]={ enable:{ name:'开启', init:true } },objectPackage=object.package; if(objectPackage){ const author=Object.getOwnPropertyDescriptor(objectPackage,'author'); if(author) Object.defineProperty(extensionMenu.author={ get name(){ return `作者:${this.author}`; }, clear:true, nopointer:true, },'author',author); const intro=Object.getOwnPropertyDescriptor(objectPackage,'intro'); if(intro) Object.defineProperty(extensionMenu.intro={ clear:true, nopointer:true, },'name',intro); } const objectConfig=object.config; if(objectConfig) Object.defineProperties(extensionMenu,Object.keys(objectConfig).reduce((propertyDescriptorMap,key)=>{ propertyDescriptorMap[key]=Object.getOwnPropertyDescriptor(objectConfig,key); return propertyDescriptorMap; },{})); const help=object.help; if(help) Object.defineProperties(lib.help,Object.keys(help).reduce((propertyDescriptorMap,key)=>{ propertyDescriptorMap[key]=Object.getOwnPropertyDescriptor(help,key); return propertyDescriptorMap; },{})); if(object.editable!==false&&lib.config.show_extensionmaker) extensionMenu.edit={ name:'编辑此扩展', clear:true, onclick:()=>{ if(game.editExtension&&lib.extensionPack&&lib.extensionPack[name]) game.editExtension(name); else alert('无法编辑未启用的扩展,请启用此扩展并重启后重试'); } }; extensionMenu.delete={ name:'删除此扩展', clear:true, onclick:function(){ if(this.innerHTML!='<span>确认删除</span>'){ this.innerHTML='<span>确认删除</span>'; new Promise(resolve=>setTimeout(resolve,1000)).then(()=>this.innerHTML='<span>删除此扩展</span>'); return; } const page=this.parentNode,start=page.parentNode.previousSibling; page.remove(); if(start){ const pageInStart=Array.from(start.childNodes).find(childNode=>childNode.link==page); if(pageInStart){ let active=false; if(pageInStart.classList.contains('active')) active=true; pageInStart.remove(); if(active){ start.firstChild.classList.add('active'); start.nextSibling.appendChild(start.firstChild.link); } } } game.removeExtension(name); if(typeof object.onremove=='function') object.onremove(); } } if(_status.importingExtension){ game.importedPack=object; return; } const libConfig=lib.config; if(!object||!libConfig[`${extensionName}_enable`]) return; if(!noEval) lib.init.eval(object); const config=Object.keys(libConfig).reduce((constructingConfig,key)=>{ if(key!=extensionName&&key.startsWith(extensionName)) constructingConfig[key.slice(11+name.length)]=libConfig[key]; return constructingConfig; },{}); try{ let extensionPack=lib.extensionPack[name]; if(objectPackage){ extensionPack=lib.extensionPack[name]=objectPackage; objectPackage.files=object.files||{}; const extensionPackFiles=objectPackage.files; if(!extensionPackFiles.character) extensionPackFiles.character=[]; if(!extensionPackFiles.card) extensionPackFiles.card=[]; if(!extensionPackFiles.skill) extensionPackFiles.skill=[]; } else extensionPack=lib.extensionPack[name]={}; const content=object.content,precontent=object.precontent; extensionPack.code={ content:content, precontent:precontent, help:help, config:objectConfig } if(precontent){ _status.extension=name; yield (gnc.is.generatorFunc(precontent)?gnc.of(precontent):precontent).call(object,config); delete _status.extension; } if(content) lib.extensions.push([name,content,config,_status.evaluatingExtension,objectPackage||{}]); } catch(e){ console.log(e); } }), createDir:(directory,successCallback,errorCallback)=>{ const paths=directory.split('/').reverse(); if(window.resolveLocalFileSystemURL) return new Promise((resolve,reject)=>window.resolveLocalFileSystemURL(lib.assetURL,resolve,reject)).then(directoryEntry=>{ const redo=entry=>new Promise((resolve,reject)=>entry.getDirectory(paths.pop(),{ create:true },resolve,reject)).then(resolvedDirectoryEntry=>{ if(paths.length) return redo(resolvedDirectoryEntry); if(typeof successCallback=='function') successCallback(); }); return redo(directoryEntry); },reason=>{ if(typeof errorCallback!='function') return Promise.reject(reason); errorCallback(reason); }); const fs=require("fs"); let path=__dirname; const redo=()=>{ path+=`/${paths.pop()}`; return new Promise(resolve=>fs.exists(path,resolve)).then(exists=>{ //不存在此目录 if(!exists) return new Promise(resolve=>fs.mkdir(path,resolve)); }).then(()=>{ if(paths.length) return redo(); if(typeof successCallback=='function') successCallback(); }); }; return redo(); }, importExtension:gnc.of(function*(data,finishLoad,exportExtension,extensionPackage){ //by 来瓶可乐加冰、Rintim、Tipx-L if(!window.JSZip) yield new Promise((resolve,reject)=>lib.init.js(`${lib.assetURL}game`,"jszip",resolve,reject)); const zip=new JSZip(); if(get.objtype(data)=='object'){ //导出 const _filelist=data._filelist,filelist2=_filelist||[]; if(_filelist) delete data._filelist; const filelist=Object.keys(data); filelist.forEach(value=>zip.file(value,data[value])); game.print(filelist); game.print(filelist2); const generate=zip.generate({ type:'arraybuffer' }); if(!exportExtension){ game.importExtension.apply(this,[generate,finishLoad]); return; } if(extensionPackage){ extensionPackage.files=filelist.concat(filelist2).filter(value=>value!='extension.js'); const size=generate.byteLength; if(size<1000) extensionPackage.size=`${size}B`; else if(size<1000000) extensionPackage.size=`${Math.round(size/1000)}KB`; else extensionPackage.size=`${Math.round(size/100000)/10}MB`; zip.file('package.js',Object.keys(extensionPackage).reduce((constructingData,key,currentIndex,keys)=>`${constructingData}\t${key}:${JSON.stringify(extensionPackage[key])}${currentIndex<keys.length-1?',\n':'\n};'}`,`extension["${exportExtension}"]={\n`)); } const blob=zip.generate({ type:'blob' }),fileNameToSaveAs=`${exportExtension.replace(/\\|\/|\:|\?|\"|\*|<|>|\|/g,'-')}.zip`; if(lib.device){ const directory=lib.device=='android'?cordova.file.externalDataDirectory:cordova.file.documentsDirectory; new Promise((resolve,reject)=>window.resolveLocalFileSystemURL(directory,resolve,reject)).then(directoryEntry=>new Promise((resolve,reject)=>directoryEntry.getFile(fileNameToSaveAs,{ create:true },resolve,reject))).then(fileEntry=>new Promise((resolve,reject)=>fileEntry.createWriter(resolve,reject))).then(fileWriter=>new Promise((resolve,reject)=>{ fileWriter.onerror=reject; fileWriter.onwriteend=resolve; fileWriter.write(blob); })).then(()=>alert(`文件已导出至${directory}${fileNameToSaveAs}`)); } else{ const downloadLink=document.createElement('a'); downloadLink.download=fileNameToSaveAs; downloadLink.innerHTML='Download File'; downloadLink.href=window.URL.createObjectURL(blob); downloadLink.click(); } if(typeof finishLoad=='function') finishLoad(); return; } //导入 const UHP=error=>alert(`导入失败:\n${JSON.stringify(error,null,'\t')}`); try{ zip.load(data); // alert(zip.file('文件夹/加扩展.js').asText()) const str=zip.file('extension.js').asText(); if(str===""||undefined) throw('你导入的不是扩展!请选择正确的文件'); _status.importingExtension=true; eval(str); yield Promise.allSettled(_status.extensionLoading); delete _status.extensionLoading; _status.importingExtension=false; if(!game.importedPack) throw('err'); const extensionName=game.importedPack.name; if(lib.config.all.plays.contains(extensionName)) throw('禁止安装游戏原生扩展'); const extensions=lib.config.extensions; if(extensions.contains(extensionName)) game.removeExtension(extensionName,true); extensions.add(extensionName); game.saveConfigValue('extensions'); game.saveConfig(`extension_${extensionName}_enable`,true); const config=game.importedPack.config; Object.keys(config).forEach(value=>{ const configObject=config[value]; if(configObject&&configObject.hasOwnProperty('init')) game.saveConfig(`extension_${extensionName}_${value}`,configObject.init); }); if(game.download){ const files=zip.files,hiddenFileFlags=['.','_'],fileList=Object.keys(files).filter(key=>!files[key].dir&&!hiddenFileFlags.includes(key[0])).reverse(); //alert(filelist) //电脑端 //具备nodeJS环境 if(lib.node&&lib.node.fs){ const writeFile=errnoException=>{ if(errnoException){ finishLoad(); UHP(errnoException); return; } if(fileList.length){ //filename 数组 ...dir+/+file //这里需要个创文件夹的函数 const zipDir=fileList.pop(),fileName=zipDir.split('/'),name=fileName.pop(),letGo=name=>new Promise(resolve=>lib.node.fs.writeFile(`${__dirname}/extension/${extensionName}/${name}`,zip.file(zipDir).asNodeBuffer(),null,resolve)).then(writeFile); return (fileName.length?game.createDir(`extension/${extensionName}/${fileName.join("/")}`).then(()=>letGo(`${fileName.join('/')}/${name}`)):letGo(name)); } finishLoad(); } game.ensureDirectory(`extension/${extensionName}`).then(writeFile).catch(UHP); } else new Promise((resolve,reject)=>window.resolveLocalFileSystemURL(lib.assetURL,resolve,reject)).then(directoryEntry=>new Promise((resolve,reject)=>directoryEntry.getDirectory(`extension/${extensionName}`,{ create:true },resolve,reject))).then(directoryEntry=>{ //扩展文件夹 const writeFile=()=>{ if(!fileList.length){ finishLoad(); return; } //filename 数组 ...dir+/+file const zipDirectory=fileList.shift(),fileName=zipDirectory.split("/"),name=fileName.pop(),letGo=name=>new Promise((resolve,reject)=>directoryEntry.getFile(name,{ create:true },resolve,reject)).then(fileEntry=>new Promise((resolve,reject)=>fileEntry.createWriter(resolve,reject))).then(fileWriter=>new Promise((resolve,reject)=>{ fileWriter.onerror=reject; fileWriter.onwriteend=resolve; fileWriter.write(zip.file(zipDirectory).asArrayBuffer()); })).then(writeFile); return (fileName.length?game.createDir(`extension/${extensionName}/${fileName.join('/')}`).then(()=>letGo(`${fileName.join('/')}/${name}`)):letGo(name)); }; return writeFile(); }).catch(UHP); } else{ localStorage.setItem(`${lib.configprefix}extension_${extensionName}`,str); const hiddenFileFlags=['.','_'],fileList=Object.keys(zip.files).filter(filePath=>!hiddenFileFlags.includes(filePath[0])&&filePath[filePath.length-1]!='/'); if(fileList.length&&lib.db){ lib.config.extensionInfo[extensionName]={ file:fileList }; game.saveConfigValue('extensionInfo'); fileList.forEach(filePath=>{ const arrayBuffer=zip.file(filePath).asArrayBuffer(); if(!arrayBuffer) return; const blob=new Blob([arrayBuffer]); new Promise((resolve,reject)=>{ const fileReader=new FileReader(); fileReader.onerror=reject; fileReader.onload=resolve; fileReader.readAsDataURL(blob,'UTF-8'); }).then(fileLoadedEvent=>game.putDB('image',`extension-${extensionName}:${filePath}`,fileLoadedEvent.target.result)); }); } finishLoad(); } delete game.importedPack; } catch(error){ UHP(error); return false; } }), export:function(textToWrite,name){ var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'}); var fileNameToSaveAs = name||'noname'; fileNameToSaveAs=fileNameToSaveAs.replace(/\\|\/|\:|\?|\"|\*|<|>|\|/g,'.'); if(lib.device){ var directory; if(lib.device=='android'){ directory=cordova.file.externalDataDirectory; } else{ directory=cordova.file.documentsDirectory; } window.resolveLocalFileSystemURL(directory,function(entry){ entry.getFile(fileNameToSaveAs,{create:true},function(fileEntry){ fileEntry.createWriter(function(fileWriter){ fileWriter.onwriteend=function(){ alert('文件已导出至'+directory+fileNameToSaveAs); } fileWriter.write(textFileAsBlob) }); }); }); } else{ var downloadLink = document.createElement("a"); downloadLink.download = fileNameToSaveAs; downloadLink.innerHTML = "Download File"; downloadLink.href = window.URL.createObjectURL(textFileAsBlob); downloadLink.click(); } }, multiDownload2:function(list,onsuccess,onerror,onfinish,process,dev){ list=list.slice(0); var download=function(){ if(list.length){ var current=list.shift(); var current2; if(typeof process=='function'){ current2=process(current); } else{ current2=current; } if(current.startsWith('theme')){ game.print(current.slice(6)); } else if(current.startsWith('image/skin')){ game.print(current.slice(11)); } else{ game.print(current.slice(current.lastIndexOf('/')+1)); } game.download(current,current2,function(){ if(onsuccess) onsuccess(list.length); download(); },function(){ if(onerror) onerror(list.length); download(); },dev); } else{ if(onfinish) onfinish(); } } download(); }, multiDownload:function(list,onsuccess,onerror,onfinish,process,dev){ if(lib.config.dev) game.print(get.url()); var args=Array.from(arguments); if(list.length<=3){ game.multiDownload2.apply(this,args); } else{ var num=Math.round(list.length/3); var left=3; args[3]=function(){ left--; if(left==0){ onfinish(); } }; setTimeout(function(){ args[0]=list.slice(0,num);game.multiDownload2.apply(game,args); }); setTimeout(function(){ args[0]=list.slice(num,2*num);game.multiDownload2.apply(this,args); },200); setTimeout(function(){ args[0]=list.slice(2*num);game.multiDownload2.apply(this,args); },400); } }, fetch:function(url,onload,onerror,onprogress){ var tmpName='~tmp'+get.id(); game.download(encodeURI(url),tmpName,function(){ game.readFile(tmpName,function(data){ onload(data); game.removeFile(tmpName); },onerror); },onerror,null,onprogress); }, playVideo:function(time,mode){ if(!_status.replayvideo){ localStorage.setItem(lib.configprefix+'playbackmode',lib.config.mode); } game.saveConfig('mode',mode); localStorage.setItem(lib.configprefix+'playback',time); game.reload(); }, playVideoContent:function(video){ var next=game.createEvent('video',false); next.video=video; ui.system.style.display='none'; ui.system.hide(); ui.arena.style.display='none'; ui.arena.hide(); ui.window.classList.remove('leftbar'); ui.window.classList.remove('rightbar'); ui.historybar.style.display='none'; _status.event=next; _status.paused=false; _status.paused2=false; _status.over=false; _status.video=true; clearTimeout(_status.timeout); for(var i in lib.characterPack){ for(var j in lib.characterPack[i]){ lib.character[j]=lib.character[j]||lib.characterPack[i][j]; } } next.setContent('playVideoContent'); game.loop(); }, videoContent:{ arrangeLib:function(content){ for(var i in content){ for(var j in content[i]){ lib[i][j]=content[i][j]; } } }, $syncDisable:function(player,map){ player.disabledSlots=map; player.$syncDisable(map) }, $syncExpand:function(player,map){ player.expandedSlots=map; player.$syncExpand(map) }, $disableJudge:function(player,map){ player.$disableJudge() }, $enableJudge:function(player,map){ player.$enableJudge() }, jiuNode:function(player,bool){ //Powered by 升麻 if(bool){ if(!player.node.jiu&&lib.config.jiu_effect){ player.node.jiu=ui.create.div('.playerjiu',player.node.avatar); player.node.jiu2=ui.create.div('.playerjiu',player.node.avatar2); } } else{ if(player.node.jiu){ player.node.jiu.delete(); player.node.jiu2.delete(); delete player.node.jiu; delete player.node.jiu2; } } }, init:function(players){ if(game.chess) return; if(lib.config.mode=='versus'){ players.bool=players.pop(); } ui.arena.setNumber(players.length); ui.arena.classList.add('video'); game.players.length=0; game.dead.length=0; ui.create.players(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); if(lib.config.mode=='versus'){ if(players.bool){ ui.arena.setNumber(parseInt(ui.arena.dataset.number)+1); for(var i=0;i<game.players.length;i++){ game.players[i].dataset.position=parseInt(game.players[i].dataset.position)+1; } game.singleHandcard=true; ui.arena.classList.add('single-handcard'); ui.window.classList.add('single-handcard'); ui.fakeme=ui.create.div('.fakeme.avatar',ui.me); } ui.arena.style.display=''; ui.refresh(ui.arena); ui.arena.show(); } else if(lib.config.mode=='boss'){ if(!players.boss){ game.singleHandcard=true; ui.arena.classList.add('single-handcard'); ui.window.classList.add('single-handcard'); ui.fakeme=ui.create.div('.fakeme.avatar',ui.me); } ui.arena.setNumber(8); } ui.updatehl(); for(var i=0;i<players.length;i++){ if(lib.config.mode=='identity'){ game.players[i].init(players[i].name,players[i].name2); game.players[i].setIdentity(players[i].identity); } else if(lib.config.mode=='doudizhu'||lib.config.mode=='single'){ game.players[i].init(players[i].name,players[i].name2); game.players[i].setIdentity(players[i].identity); } else if(lib.config.mode=='stone'){ game.players[i].init(players[i].name,players[i].name2); game.players[i].classList.add('noidentity'); game.players[i].updateActCount(null,players[i].count,0); } else if(lib.config.mode=='boss'){ game.players[i].init(players[i].name,players[i].name2); game.players[i].setIdentity(players[i].identity); game.players[i].dataset.position=players[i].position; game.players[i].node.action.innerHTML='行动'; } else if(lib.config.mode=='versus'){ game.players[i].init(players[i].name,players[i].name2); game.players[i].node.identity.firstChild.innerHTML=players[i].identity; game.players[i].node.identity.dataset.color=players[i].color; game.players[i].node.action.innerHTML='行动'; } else if(lib.config.mode=='guozhan'){ game.players[i].name=players[i].name; game.players[i].name1=players[i].name1; game.players[i].name2=players[i].name2; game.players[i].sex='unknown'; game.players[i].identity='unknown'; lib.translate[game.players[i].name]=players[i].translate; game.players[i].init(players[i].name1,players[i].name2); game.players[i].classList.add('unseen_v'); game.players[i].classList.add('unseen2_v'); if(game.players[i]!=game.me){ game.players[i].node.identity.firstChild.innerHTML='猜'; game.players[i].node.identity.dataset.color='unknown'; } else{ game.players[i].setIdentity(game.players[i].group); } } } for(var i=0;i<game.players.length;i++){ game.playerMap[game.players[i].dataset.position]=game.players[i]; } if(lib.config.mode=='versus'){ if(players.bool){ game.onSwapControl(); } } else if(lib.config.mode=='boss'){ if(!players.boss){ game.onSwapControl(); } ui.arena.style.display=''; ui.refresh(ui.arena); ui.arena.show(); ui.updatehl(); } }, newcard:function(content){ if(content){ lib.translate[content.name]=content.translate; lib.translate[content.name+'_info']=content.info; lib.card[content.name]={}; lib.card[content.name].cardimage=content.card for(var i in lib.card[content.card]){ lib.card[content.name][i]=lib.card[content.card][i]; } if(content.legend){ lib.card[content.name].legend=true; } else if(content.epic){ lib.card[content.name].epic=true; } else if(content.unique){ lib.card[content.name].unique=true; } } }, changeLand:function(player,url){ game.changeLand(url,player); }, destroyLand:function(){ if(ui.land){ ui.land.destroy(); } }, playAudio:function(str){ game.playAudio(str,'video'); }, playSkillAudio:function(name){ game.playSkillAudio(name,'video'); }, phaseChange:function(player){ if(player){ var glowing=document.querySelector('.glow_phase'); if(glowing){ glowing.classList.remove('glow_phase'); } if(lib.config.glow_phase){ player.classList.add('glow_phase'); // player.dataset.glow_phase=lib.config.glow_phase; } } else{ console.log(player); } }, playerfocus:function(player,time){ if(player&&player.playerfocus){ player.playerfocus(time); } else{ console.log(player); } }, playerfocus2:function(){ ui.arena.classList.add('playerfocus'); setTimeout(function(){ ui.arena.classList.remove('playerfocus'); },1500) }, identityText:function(player,str){ if(player&&str){ player.node.identity.firstChild.innerHTML=str; } else{ console.log(player); } }, identityColor:function(player,str){ if(player&&str){ player.node.identity.dataset.color=str; } else{ console.log(player); } }, chessSwap:function(content){ var me=game.playerMap[content[0]]; var player=game.playerMap[content[1]]; if(me){ me.classList.remove('current_action'); } if(player){ player.classList.add('current_action'); } }, chessgainmod:function(player,num){ if(Array.isArray(num)){ num=get.infoCards(num); } if(player&&player.$gainmod){ player.$gainmod(num); } else{ console.log(player); } }, moveTo:function(player,pos){ if(player&&player.moveTo&&pos){ player.moveTo(pos[0],pos[1]); } else{ console.log(player) } }, addObstacle:function(pos){ if(pos){ game.addObstacle(pos[0],pos[1]); } }, removeObstacle:function(pos){ game.removeObstacle(pos); }, moveObstacle:function(pos){ if(pos){ game.moveObstacle(pos[0],pos[1],pos[2]); } }, colorObstacle:function(pos){ if(pos){ game.colorObstacle(pos[0],pos[1]); } }, thrownhighlight1:function(){ ui.arena.classList.add('thrownhighlight'); }, thrownhighlight2:function(){ ui.arena.classList.remove('thrownhighlight'); }, chessFocus:function(player){ if(player){ player.chessFocus(); } else{ console.log('chessFocus'); } }, removeTreasure:function(pos){ if(game.playerMap[pos]){ game.playerMap[pos].delete(); delete game.playerMap[pos]; } else{ console.log(pos); } }, initobs:function(obs){ if(obs){ for(var i=0;i<obs.length;i++){ game.addObstacle(obs[i]); } } else{ console.log(obs); } }, stonePosition:function(content){ var player=game.playerMap[content[0]]; if(player){ delete game.playerMap[content[0]]; player.dataset.position=content[1]; game.playerMap[content[1]]=player; } else{ console.log(content); } }, bossSwap:function(player,name){ if(player&&name){ player.delete(); var noboss=false; if(name[0]=='_'){ name=name.slice(1); noboss=true; } var boss=ui.create.player().init(name); boss.dataset.position=player.dataset.position; game.playerMap[player.dataset.position]=boss; if(game.me==player){ game.me=boss; } game.players.push(boss); game.arrangePlayers(); if(!noboss){ game.boss=boss; boss.setIdentity('zhu'); boss.identity='zhu'; } else{ boss.setIdentity('zhong'); boss.identity='zhong'; } ui.arena.appendChild(boss.animate('zoominanim')); } }, stoneSwap:function(info){ var player=ui.create.player(); player.classList.add('noidentity'); player.dataset.position=info.position; player.animate(info.me?'replaceme':'replaceenemy'); player.actcount=info.actcount; player.init(info.name,info.name2); game.players.push(player); player.updateActCount(null,info.actcount,0); ui.arena.appendChild(player); game.playerMap[player.dataset.position]=player; game.arrangePlayers(); }, chess_tongshuai:function(player,content){ if(player&&player.storage){ player.storage.tongshuai.owned=content; } else{ console.log(player); } }, chess_tongshuai_skill:function(player,content){ if(player&&content){ if(player.marks.tongshuai.firstChild){ player.marks.tongshuai.firstChild.remove(); } player.marks.tongshuai.setBackground(content[0],'character'); player.additionalSkills.tongshuai=content[1]; } else{ console.log(player); } }, smoothAvatar:function(player,vice){ if(player&&player.node){ if(vice){ if(player.node.avatar2){ player.smoothAvatar(vice); } } else{ if(player.node.avatar){ player.smoothAvatar(vice); } } } }, setAvatar:function(player,content){ if(player&&content&&content.length==2){ player.setAvatar(content[0],content[1]) } }, setAvatarQueue:function(player,content){ if(player&&content&&content.length==2){ player.setAvatarQueue(content[0],content[1]) } }, addSubPlayer:function(player,content){ if(player&&content&&content[0]&&content[1]&& content[2]&&content[3]&&content[4]){ var skill=content[0]; lib.skill[skill]=content[1]; lib.character[skill]=content[2]; lib.translate[skill]=content[3]; player.storage[skill]=content[4]; } }, arenaNumber:function(content){ ui.arena.dataset.number=content; }, reinit:function(source,content){ if(source&&content){ source.uninit(); source.init(content[0]); source.node.identity.dataset.color=content[1]; } else{ console.log(source); } }, reinit2:function(source,name){ if(source&&name){ source.init(name); } else{ console.log(source); } }, reinit3:function(source,content){ if(source&&content){ var info1=lib.character[content.from]; var info2=lib.character[content.to]; if(content.avatar2){ source.name2=content.to; if(source.isUnseen(0)){ source.sex=info2[0]; } source.node.avatar2.setBackground(content.to,'character'); source.node.name2.innerHTML=get.slimName(content.to); } else{ source.name=content.to; source.sex=info2[0]; source.node.avatar.setBackground(content.to,'character'); source.node.name.innerHTML=get.slimName(content.to); } source.maxHp=content.hp; this.update(); for(var i=0;i<info1[3].length;i++){ source.removeSkill(info1[3][i]); } for(var i=0;i<info2[3].length;i++){ source.addSkill(info2[3][i]); } } }, skill:function(player,content){ if(typeof content=='string'){ if(lib.skill[content]) lib.skill[content].video(player); } else if(Array.isArray(content)){ if(lib.skill[content[0]]) lib.skill[content[0]].video(player,content[1]); } else{ console.log(player,content) } }, addFellow:function(content){ var player=game.addFellow(content[0],content[1],content[2]); game.playerMap[player.dataset.position]=player; }, windowzoom1:function(){ ui.window.style.transition='all 0.5s'; ui.window.classList.add('zoomout3'); ui.window.hide(); }, windowzoom2:function(){ ui.window.style.transition='all 0s'; ui.refresh(ui.window); }, windowzoom3:function(){ ui.window.classList.remove('zoomout3'); ui.window.classList.add('zoomin3'); }, windowzoom4:function(){ ui.window.style.transition='all 0.5s'; ui.refresh(ui.window); ui.window.show(); ui.window.classList.remove('zoomin3'); }, windowzoom5:function(){ ui.window.style.transition=''; }, updateActCount:function(player,content){ if(player&&content){ player.updateActCount(content[0],content[1],content[2]); } else{ console.log(player); } }, setIdentity:function(player,identity){ if(player&&identity){ player.setIdentity(identity); } else{ console.log(num); } }, showCharacter:function(player,num){ if(player&&player.classList){ switch(num){ case 0: player.classList.remove('unseen_v'); break; case 1: player.classList.remove('unseen2_v'); break; case 2: player.classList.remove('unseen_v'); player.classList.remove('unseen2_v'); break; } if(!player.classList.contains('unseen_v')&&(!player.name2||!player.classList.contains('unseen2_v'))&&player.storage.nohp){ delete player.storage.nohp; player.node.hp.show(); player.update(); } } else{ console.log(num); } }, hidePlayer:function(player){ if(player){ player.hide(); } }, deleteHandcards:function(player){ if(player){ player.node.handcards1.delete(); player.node.handcards2.delete(); } }, hideCharacter:function(player,num){ if(player&&player.classList){ switch(num){ case 0: player.classList.add('unseen_v'); break; case 1: player.classList.add('unseen2_v'); break; case 2: player.classList.add('unseen_v'); player.classList.add('unseen2_v'); break; } } else{ console.log(num); } }, popup:function(player,info){ if(player&&info){ player.popup(info[0],info[1]); } else{ console.log(player); } }, log:function(str){ game.log(str); }, draw:function(player,info){ if(player&&player.$draw){ player.$draw(info); } else{ console.log(player); } }, drawCard:function(player,info){ if(player&&info){ player.$draw(get.infoCards(info)); } else{ console.log(player); } }, throw:function(player,info){ if(player&&info){ player.$throw(get.infoCards(info[0]),info[1],null,info[2]); } else{ console.log(player); } }, compare:function(player,info){ if(player&&info){ player.$compare(get.infoCard(info[0]),game.playerMap[info[1]],get.infoCard(info[2])); } else{ console.log(player); } }, compareMultiple:function(player,info){ if(player&&info){ player.$compareMultiple(get.infoCard(info[0]),get.infoTargets(info[1]),get.infoCards(info[2])); } else{ console.log(player); } }, give:function(player,info){ if(player&&info){ player.$give(info[0],game.playerMap[info[1]]); } else{ console.log(player); } }, giveCard:function(player,info){ if(player&&info){ player.$give(get.infoCards(info[0]),game.playerMap[info[1]]); } else{ console.log(player); } }, gain:function(player,info){ if(player&&player.$gain){ player.$gain(info); } else{ console.log(player); } }, gainCard:function(player,info){ if(player&&info){ player.$gain(get.infoCards(info)); } else{ console.log(player); } }, gain2:function(player,cards){ if(player&&player.$draw){ var nodeList=document.querySelectorAll('#arena>.card,#chess>.card'); var nodes=[]; for(var i=0;i<nodeList.length;i++){ nodes.push(nodeList[i]); } for(var i=0;i<cards.length;i++){ for(var j=0;j<nodes.length;j++){ if(cards[i][2]==nodes[j].name&&cards[i][0]==nodes[j].suit&&cards[i][1]==nodes[j].number){ nodes[j].moveDelete(player); cards.splice(i--,1); nodes.splice(j--,1); break; } } } if(cards.length){ player.$draw(get.infoCards(cards)); } } else{ console.log(player); } }, deletenode:function(player,cards,method){ if(cards){ var nodeList=document.querySelectorAll('#arena>.card,#chess>.card'); var nodes=[]; for(var i=0;i<nodeList.length;i++){ nodes.push(nodeList[i]); } for(var i=0;i<cards.length;i++){ for(var j=0;j<nodes.length;j++){ if(cards[i][2]==nodes[j].name&&cards[i][0]==nodes[j].suit&&cards[i][1]==nodes[j].number){ nodes[j].delete(); if(method=='zoom'){ nodes[j].style.transform='scale(0)'; } cards.splice(i--,1); nodes.splice(j--,1); break; } } } } else{ console.log(player,cards); } }, highlightnode:function(player,card){ if(card){ var nodeList=document.querySelectorAll('#arena>.card,#chess>.card'); var nodes=[]; for(var i=0;i<nodeList.length;i++){ nodes.push(nodeList[i]); } for(var j=nodes.length-1;j>=0;j--){ if(card[2]==nodes[j].name&&card[0]==nodes[j].suit&&card[1]==nodes[j].number){ nodes[j].classList.add('thrownhighlight'); break; } } } else{ console.log(player,cards); } }, uiClear:function(){ ui.clear(); }, judge1:function(player,content){ if(player&&content){ var judging=get.infoCard(content[0]); if(game.chess){ judging.copy('thrown','center','thrownhighlight',ui.arena).animate('start'); } else{ player.$throwordered(judging.copy('thrownhighlight'),true); } ui.create.dialog(content[1]).videoId=content[2]; ui.arena.classList.add('thrownhighlight'); } else{ console.log(player); } }, centernode:function(content){ get.infoCard(content).copy('thrown','center','thrownhighlight',ui.arena).animate('start'); }, judge2:function(videoId){ for(var i=0;i<ui.dialogs.length;i++){ if(ui.dialogs[i].videoId==videoId){ ui.dialogs[i].close(); } } ui.arena.classList.remove('thrownhighlight'); }, unmarkname:function(player,name){ if(player&&player.unmark){ player.unmark(name); } else{ console.log(player); } }, unmark:function(player,name){ if(player&&player.marks&&player.marks[name]){ player.marks[name].delete(); player.marks[name].style.transform+=' scale(0.2)'; delete player.marks[name]; ui.updatem(this); } }, flame:function(player,type){ if(player&&type){ player['$'+type](); } else{ console.log(player); } }, throwEmotion:function(player,content){ if(player&&content){ player.$throwEmotion(game.playerMap[content[0]],content[1]); } else{ console.log(player); } }, addGaintag:function(player,content){ if(player&&content){ var checkMatch=function(l1,l2){ for(var i=0;i<l1.length;i++){ for(var j=0;j<l2.length;j++){ if(l2[j].suit==l1[i][0]&&l2[j].number==l1[i][1]&&l2[j].name==l1[i][2]){ l2[j].addGaintag(content[1]); l2.splice(j--,1); break; } } } } checkMatch(content[0],player.getCards('h')); } else{ console.log(player); } }, removeGaintag:function(player,content){ if(player&&content){ if(Array.isArray(content)) player.removeGaintag.apply(player,content) else player.removeGaintag(content); } else{ console.log(player); } }, line:function(player,content){ if(player&&content){ player.line(game.playerMap[content[0]],content[1]); } else{ console.log(player); } }, fullscreenpop:function(player,content){ if(player&&content){ player.$fullscreenpop(content[0],content[1],content[2]); } else{ console.log(player); } }, damagepop:function(player,content){ if(player&&content){ player.$damagepop(content[0],content[1],content[2]); } else{ console.log(player); } }, damage:function(player,source){ if(player&&player.$damage){ player.$damage(game.playerMap[source]); } else{ console.log(player); } }, diex:function(player){ if(!player){ console.log('diex'); return; } var cards=player.getCards('hej'); for(var i=0;i<cards.length;i++){ cards[i].discard(); } while(player.node.marks.childNodes.length>1){ player.node.marks.lastChild.remove(); } player.classList.add('dead'); 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); if(lib.config.mode=='stone'){ setTimeout(function(){ player.delete(); },500); } }, tafangMe:function(player){ if(player){ game.me=player; ui.me.lastChild.show(); ui.create.fakeme(); ui.handcards1=player.node.handcards1.animate('start').fix(); ui.handcards2=player.node.handcards2.animate('start').fix(); ui.handcards1Container.appendChild(ui.handcards1); ui.handcards2Container.appendChild(ui.handcards2); ui.updatehl(); game.setChessInfo(); } }, deleteChessPlayer:function(player){ if(player){ player.delete(); delete game.playerMap[player.dataset.position]; game.players.remove(player); for(var i=0;i<ui.phasequeue.length;i++){ if(ui.phasequeue[i].link==player){ ui.phasequeue[i].remove(); ui.phasequeue.splice(i,1); break; } } } }, addChessPlayer:function(content){ game.addChessPlayer.apply(this,content); }, die:function(player){ if(!player){ console.log('die'); return; } player.$die(); if(game.chess){ delete lib.posmap[player.dataset.position]; setTimeout(function(){ player.delete(); },500); for(var i=0;i<ui.phasequeue.length;i++){ if(ui.phasequeue[i].link==player){ ui.phasequeue[i].remove(); ui.phasequeue.splice(i,1); break; } } } }, revive:function(player){ if(!player){ console.log('revive'); return; } player.classList.remove('dead'); player.node.hp.show(); player.node.equips.show(); player.node.count.show(); player.node.avatar.style.transform=''; player.node.avatar2.style.transform=''; player.removeAttribute('style'); }, update:function(player,info){ if(player&&info){ player.hp=info[1]; player.maxHp=info[2]; player.hujia=info[3]; player.update(info[0]); } else{ console.log(player); } }, phaseJudge:function(player,card){ if(player&&card){ // player.$phaseJudge(get.infoCard(card)); } else{ console.log(player); } }, directgain:function(player,cards){ if(player&&cards){ player.directgain(get.infoCards(cards)); } else{ console.log(player); } }, directgains:function(player,cards){ if(player&&cards){ player.directgains(get.infoCards(cards)); } else{ console.log(player); } }, directequip:function(player,cards){ if(player&&cards){ player.directequip(get.infoCards(cards)); } else{ console.log(player); } }, gain12:function(player,cards12){ if(player&&cards12){ var cards1=get.infoCards(cards12[0]); var cards2=get.infoCards(cards12[1]); for(var i=0;i<cards1.length;i++){ cards1[i].classList.add('drawinghidden'); cards1[i].addGaintag(cards12[2]); player.node.handcards1.insertBefore(cards1[i],player.node.handcards1.firstChild); } for(var i=0;i<cards2.length;i++){ cards2[i].classList.add('drawinghidden'); cards2[i].addGaintag(cards12[2]); player.node.handcards2.insertBefore(cards2[i],player.node.handcards2.firstChild); } ui.updatehl(); } else{ console.log(player); } }, equip:function(player,card){ if(player&&card){ player.$equip(get.infoCard(card)); } else{ console.log(player); } }, addJudge:function(player,content){ if(player&&content){ var card=get.infoCard(content[0]); card.viewAs=content[1]; if(card.viewAs&&card.viewAs!=card.name&&(card.classList.contains('fullskin')||card.classList.contains('fullborder'))){ card.classList.add('fakejudge'); card.node.background.innerHTML=lib.translate[card.viewAs+'_bg']||get.translation(card.viewAs)[0] } card.classList.add('drawinghidden'); player.node.judges.insertBefore(card,player.node.judges.firstChild); ui.updatej(player); } else{ console.log(player); } }, markCharacter:function(player,content){ if(player&&content){ if(game.playerMap[content.target]){ content.target=game.playerMap[content.target]; } var mark=player.markCharacter(content.target,content); if(content.id){ player.marks[content.id]=mark; } } else{ console.log(player); } }, changeMarkCharacter:function(player,content){ if(player&&content&&player.marks[content.id]){ player.marks[content.id].info={ name:content.name, content:content.content }; player.marks[content.id].setBackground(content.target,'character'); } }, mark:function(player,content){ if(player&&content){ var mark=player.mark(content.id,content); } else{ console.log(player); } }, markSkill:function(player,content){ if(player&&content){ if(content[1]){ player.markSkill(content[0],null,get.infoCard(content[1])); } else{ player.markSkill(content[0]); } } else{ console.log(player); } }, unmarkSkill:function(player,name){ if(player&&player.unmarkSkill){ player.unmarkSkill(name); } else{ console.log(player); } }, storage:function(player,content){ if(player&&content){ if(content[2]){ switch(content[2]){ case 'cards':content[1]=get.infoCards(content[1]);break; case 'card':content[1]=get.infoCard(content[1]);break; } } player.storage[content[0]]=content[1]; } else{ console.log(player); } }, markId:function(player,content){ if(player&&content){ player.mark(get.infoCard(content[0]),content[1]); } else{ console.log(player); } }, unmarkId:function(player,content){ if(player&&content){ player.unmark(get.infoCard(content[0]),content[1]); } else{ console.log(player); } }, lose:function(player,info){ if(player&&info){ var hs=info[0]||[],es=info[1]||[],js=info[2]||[],ss=info[3]||[]; var phs=player.getCards('h'),pes=player.getCards('e'),pjs=player.getCards('j'),pss=player.getCards('s'); var checkMatch=function(l1,l2){ for(var i=0;i<l1.length;i++){ for(var j=0;j<l2.length;j++){ if(l2[j].suit==l1[i][0]&&l2[j].number==l1[i][1]&&l2[j].name==l1[i][2]){ l2[j].remove(); l2.splice(j--,1); break; } } } } checkMatch(hs,phs); checkMatch(es,pes); checkMatch(js,pjs); checkMatch(ss,pss); ui.updatehl(); } else{ console.log(player); } }, loseAfter:function(player){ if(!player){ console.log('loseAfter'); return; } }, link:function(player,bool){ if(player&&player.classList){ if(bool){ player.addLink(); } else{ player.removeLink(); } } else{ console.log(player); } }, turnOver:function(player,bool){ if(player&&player.classList){ if(bool){ player.classList.add('turnedover'); } else{ player.classList.remove('turnedover'); } } else{ console.log(player); } }, showCards:function(player,info){ if(info){ var dialog=ui.create.dialog(info[0],get.infoCards(info[1])); setTimeout(function(){ dialog.close(); },1000); } else{ console.log(player); } }, cardDialog:function(content){ if(Array.isArray(content)){ ui.create.dialog(content[0],get.infoCards(content[1])).videoId=content[2]; } else if(typeof content=='number'){ for(var i=0;i<ui.dialogs.length;i++){ if(ui.dialogs[i].videoId==content){ ui.dialogs[i].close(); return; } } } }, changeSeat:function(player,info){ if(player&&player.getBoundingClientRect&&player.changeSeat){ player.changeSeat(info); game.playerMap={}; var players=game.players.concat(game.dead); for(var i=0;i<players.length;i++){ game.playerMap[players[i].dataset.position]=players[i]; } } }, dialogCapt:function(content){ for(var i=0;i<ui.dialogs.length;i++){ if(ui.dialogs[i].videoId==content[0]){ ui.dialogs[i].content.firstChild.innerHTML=content[1]; return; } } }, swapSeat:function(content){ var player1=game.playerMap[content[0]]; var player2=game.playerMap[content[1]]; if(!player1||!player2){ console.log(content); return; } var temp1,pos,i,num; temp1=player1.dataset.position; player1.dataset.position=player2.dataset.position; player2.dataset.position=temp1; game.arrangePlayers(); if(player1.dataset.position=='0'||player2.dataset.position=='0'){ pos=parseInt(player1.dataset.position); if(pos==0) pos=parseInt(player2.dataset.position); num=game.players.length+game.dead.length; for(i=0;i<game.players.length;i++){ temp1=parseInt(game.players[i].dataset.position)-pos; if(temp1<0) temp1+=num; game.players[i].dataset.position=temp1; } for(i=0;i<game.dead.length;i++){ temp1=parseInt(game.dead[i].dataset.position)-pos; if(temp1<0) temp1+=num; game.dead[i].dataset.position=temp1; } } game.playerMap={}; var players=game.players.concat(game.dead); for(var i=0;i<players.length;i++){ game.playerMap[players[i].dataset.position]=players[i]; } }, removeTafangPlayer:function(){ ui.fakeme.hide(); ui.handcards1Container.innerHTML=''; ui.handcards2Container.innerHTML=''; game.me=ui.create.player(); }, swapControl:function(player,hs){ if(player&&player.node){ var cards=get.infoCards(hs); player.node.handcards1.innerHTML=''; player.node.handcards2.innerHTML=''; player.directgain(cards,false); game.me.node.handcards1.remove(); game.me.node.handcards2.remove(); ui.handcards1=player.node.handcards1.animate('start').fix(); ui.handcards2=player.node.handcards2.animate('start').fix(); ui.handcards1Container.insertBefore(ui.handcards1,ui.handcards1Container.firstChild); ui.handcards2Container.insertBefore(ui.handcards2,ui.handcards2Container.firstChild); game.me=player; ui.updatehl(); if(game.chess){ ui.create.fakeme(); } } else{ console.log(player); } }, onSwapControl:function(){ game.onSwapControl(); }, swapPlayer:function(player,hs){ if(player&&player.node){ var cards=get.infoCards(hs); player.node.handcards1.innerHTML=''; player.node.handcards2.innerHTML=''; player.directgain(cards,false); var pos=parseInt(player.dataset.position); var num=game.players.length+game.dead.length; var players=game.players.concat(game.dead); var temp; for(var i=0;i<players.length;i++){ temp=parseInt(players[i].dataset.position)-pos; if(temp<0) temp+=num; players[i].dataset.position=temp; } game.me.node.handcards1.remove(); game.me.node.handcards2.remove(); game.me=player; ui.handcards1=player.node.handcards1.animate('start').fix(); ui.handcards2=player.node.handcards2.animate('start').fix(); ui.handcards1Container.appendChild(ui.handcards1); ui.handcards2Container.appendChild(ui.handcards2); ui.updatehl(); game.playerMap={}; var players=game.players.concat(game.dead); for(var i=0;i<players.length;i++){ game.playerMap[players[i].dataset.position]=players[i]; } } else{ console.log(player); } }, over:function(str){ var dialog=ui.create.dialog('hidden'); dialog.noforcebutton=true; dialog.content.innerHTML=str; dialog.forcebutton=true; dialog.open(); if(game.chess){ dialog.classList.add('center'); } if((game.layout=='long2'||game.layout=='nova')&&!game.chess){ ui.arena.classList.add('choose-character'); if(ui.me) ui.me.hide(); if(ui.mebg) ui.mebg.hide() if(ui.autonode) ui.autonode.hide(); if(lib.config.radius_size!='off'){ if(ui.historybar) ui.historybar.style.borderRadius='0 0 0 4px'; } } } }, reload:function(){ if(_status){ if(_status.reloading) return; _status.reloading=true; } if(_status.video&&!_status.replayvideo){ localStorage.removeItem(lib.configprefix+'playbackmode'); } localStorage.setItem('show_splash_off',true); if(lib.status.reload){ _status.waitingToReload=true; } else{ window.location.reload(); } }, reload2:()=>{ lib.status.reload--; if(lib.status.reload==0&&lib.ondb2.length){ const command=lib.ondb2.shift(); game[command[0]](...command[1]); } if(lib.status.reload==0&&lib.ondb.length){ const command=lib.ondb.shift(); game[command[0]](...command[1]); } if(lib.status.reload||!_status.waitingToReload) return; window.location.reload(); delete _status.waitingToReload; }, exit:function(){ var ua=navigator.userAgent.toLowerCase(); var ios=ua.includes('iphone')||ua.includes('ipad')||ua.includes('macintosh'); //electron if(typeof window.process=='object'&&typeof window.require=='function'){ var versions=window.process.versions; var electronVersion=parseFloat(versions.electron); var remote; if(electronVersion>=14){ remote=require('@electron/remote'); }else{ remote=require('electron').remote; } var thisWindow=remote.getCurrentWindow(); thisWindow.destroy(); window.process.exit(); } // android-cordova环境 else if(lib.device==='android'){ if(navigator.app&&navigator.app.exitApp){ navigator.app.exitApp(); } } //ios-cordova环境或ios浏览器环境 else if(lib.device==='ios'||!lib.device&&ios){ game.saveConfig('mode'); if(_status){ if(_status.reloading)return; _status.reloading=true; } if(_status.video&&!_status.replayvideo) { localStorage.removeItem(lib.configprefix+'playbackmode'); } window.location.reload(); } //非ios的网页版 else if(!ios){ window.onbeforeunload = null; window.close(); } }, open:function(url){ if(lib.device){ if(cordova.InAppBrowser){ cordova.InAppBrowser.open(url,'_system'); } else{ ui.create.iframe(url); } } else{ window.open(url); } }, reloadCurrent:function(){ game.saveConfig('continue_name',[game.me.name1||game.me.name,game.me.name2]); game.saveConfig('mode',lib.config.mode); localStorage.setItem(lib.configprefix+'directstart',true); game.reload(); }, update:function(func){ lib.updates.push(func); if(lib.updates.length===1){ game.run(); } return func; }, unupdate:function(func){ lib.updates.remove(func); }, stop:function(){ cancelAnimationFrame(lib.status.frameId); }, run:function(){ if(lib.updates.length){ cancelAnimationFrame(lib.status.frameId); lib.status.frameId=requestAnimationFrame(function(time){ if(lib.status.time!==0){ lib.status.delayed+=time-lib.status.time; } lib.status.frameId=requestAnimationFrame(lib.run); }); } }, addVideo:function(type,player,content){ if(_status.video||game.online) return; if(!_status.videoInited){ if(type=='arrangeLib'){ lib.video.push({ type:type, player:player, content:content, delay:0 }); } return; } if(type=='storage'&&player&&player.updateMarks){ player.updateMarks(); } if(game.getVideoName){ var time=get.time(); if(!_status.lastVideoLog){ _status.lastVideoLog=time; } if(get.itemtype(player)=='player'){ player=player.dataset.position; } lib.video.push({ type:type, player:player, content:content, delay:time-_status.lastVideoLog }); _status.lastVideoLog=time; } }, draw:function(func){ lib.canvasUpdates.push(func); if(!lib.status.canvas){ lib.status.canvas=true; game.update(lib.updateCanvas); } }, vibrate:function(time){ if(typeof navigator.vibrate=='function'){ navigator.vibrate(time||500); } }, prompt:function(){ var str,forced,callback,noinput=false,str2=''; for(var i=0;i<arguments.length;i++){ if(arguments[i]=='alert'){ forced=true; callback=function(){}; noinput=true; } else if(typeof arguments[i]=='string'){ if(arguments[i].startsWith('###')){ var list=arguments[i].slice(3).split('###'); str=list[0]; str2=list[1]; } else str=arguments[i]; } else if(typeof arguments[i]=='boolean'){ forced=arguments[i]; } else if(typeof arguments[i]=='function'){ callback=arguments[i]; } } if(!callback){ return; } //try{ // if(noinput){ // throw('e'); // } // var result=prompt(str); // callback(result); //} //catch(e){ var promptContainer=ui.create.div('.popup-container',ui.window,function(){ if(this.clicked){ this.clicked=false; } else{ clickCancel(); } }); var dialogContainer=ui.create.div('.prompt-container',promptContainer); var dialog=ui.create.div('.menubg',ui.create.div(dialogContainer),function(){ promptContainer.clicked=true; }); var strnode=ui.create.div('',str||'',dialog); var input=ui.create.node('input',ui.create.div(dialog)); input.value=str2; if(noinput){ input.style.display='none'; } var controls=ui.create.div(dialog); var clickConfirm=function(){ if(noinput){ promptContainer.remove(); } else if(input.value){ callback(input.value); promptContainer.remove(); } } var clickCancel=function(){ if(!forced){ callback(false); promptContainer.remove(); } } var confirmNode=ui.create.div('.menubutton.large.disabled','确定',controls,clickConfirm); if(!forced){ ui.create.div('.menubutton.large','取消',controls,clickCancel); } if(noinput){ confirmNode.classList.remove('disabled'); } else{ input.onkeydown=function(e){ if(e.keyCode==13){ clickConfirm(); } else if(e.keyCode==27){ clickCancel(); } } input.onkeyup=function(){ if(input.value){ confirmNode.classList.remove('disabled'); } else{ confirmNode.classList.remove('disabled'); } } input.focus(); } //} }, alert:function(str){ game.prompt(str,'alert'); }, print:function(){ if(!_status.toprint){ _status.toprint=[]; } _status.toprint.push(Array.from(arguments)); }, animate:{ window:function(num){ switch(num){ case 1:{ ui.window.style.transition='all 0.5s'; ui.window.classList.add('zoomout3'); ui.window.hide(); game.addVideo('windowzoom1'); game.delay(0,500); break; } case 2:{ ui.window.style.transition='all 0s'; ui.refresh(ui.window); game.addVideo('windowzoom2'); game.pause(); setTimeout(function(){ ui.window.classList.remove('zoomout3'); ui.window.classList.add('zoomin3'); game.addVideo('windowzoom3'); setTimeout(function(){ ui.window.style.transition='all 0.5s'; ui.refresh(ui.window); ui.window.show(); ui.window.classList.remove('zoomin3'); game.addVideo('windowzoom4'); setTimeout(function(){ ui.window.style.transition=''; game.addVideo('windowzoom5'); game.resume(); },500); },100); },100); break; } } }, flame:function(x,y,duration,type){ var particles=[]; var particle_count=50; if(type=='thunder'||type=='recover'){ particle_count=30; } else if(type=='coin'||type=='dust'){ particle_count=50; } else if(type=='legend'){ particle_count=120; } else if(type=='epic'){ particle_count=80; } else if(type=='rare'){ particle_count=50; } for(var i = 0; i < particle_count; i++) { particles.push(new particle()); } function particle() { this.speed = {x: -1+Math.random()*2, y: -5+Math.random()*5}; if(type=='thunder'||type=='coin'||type=='dust'){ this.speed.y=-3+Math.random()*5; this.speed.x=-2+Math.random()*4; } if(type=='legend'||type=='rare'||type=='epic'){ this.speed.x*=3; this.speed.y*=1.5; } this.location = {x: x, y: y}; this.radius = 0.5+Math.random()*1; this.life = 10+Math.random()*10; this.death = this.life; switch(type){ case 'thunder':{ this.b = 255; this.r = Math.round(Math.random()*255); this.g = Math.round(Math.random()*255); this.x+=Math.random()*20-10; this.y+=Math.random()*20-10; break; } case 'fire':{ this.r = 255; this.g = Math.round(Math.random()*155); this.b = 0; break; } case 'coin':{ this.r = 255; this.g = Math.round(Math.random()*25+230); this.b = Math.round(Math.random()*100+50); this.location.x+=Math.round(Math.random()*60)-30; this.location.y+=Math.round(Math.random()*40)-20; if(this.location.x<x){ this.speed.x=-Math.abs(this.speed.x); } else if(this.location.x>x){ this.speed.x=Math.abs(this.speed.x); } this.life*=1.3; this.death*=1.3; break; } case 'dust':{ this.r = Math.round(Math.random()*55)+105; this.g = Math.round(Math.random()*55)+150; this.b = 255; this.location.x+=Math.round(Math.random()*60)-30; this.location.y+=Math.round(Math.random()*40)-20; if(this.location.x<x){ this.speed.x=-Math.abs(this.speed.x); } else if(this.location.x>x){ this.speed.x=Math.abs(this.speed.x); } this.life*=1.3; this.death*=1.3; break; } case 'legend':{ this.r = 255; this.g = Math.round(Math.random()*100+155); this.b = Math.round(Math.random()*100+50); this.location.x+=Math.round(Math.random()*60)-30; this.location.y+=Math.round(Math.random()*40)-20; if(this.location.x<x){ this.speed.x=-Math.abs(this.speed.x); } else if(this.location.x>x){ this.speed.x=Math.abs(this.speed.x); } this.speed.x/=2; this.speed.y/=2; this.life*=2; this.death*=2; break; } case 'epic':{ this.r = Math.round(Math.random()*55)+200; this.g = Math.round(Math.random()*100)+55; this.b = 255; this.location.x+=Math.round(Math.random()*60)-30; this.location.y+=Math.round(Math.random()*40)-20; if(this.location.x<x){ this.speed.x=-Math.abs(this.speed.x); } else if(this.location.x>x){ this.speed.x=Math.abs(this.speed.x); } this.speed.x/=2; this.speed.y/=2; this.life*=2; this.death*=2; break; } case 'rare':{ this.r = Math.round(Math.random()*55)+105; this.g = Math.round(Math.random()*55)+150; this.b = 255; this.location.x+=Math.round(Math.random()*60)-30; this.location.y+=Math.round(Math.random()*40)-20; if(this.location.x<x){ this.speed.x=-Math.abs(this.speed.x); } else if(this.location.x>x){ this.speed.x=Math.abs(this.speed.x); } this.speed.x/=2; this.speed.y/=2; this.life*=2; this.death*=2; break; } case 'recover':{ this.g = 255; this.r = Math.round(Math.random()*200+55); this.b = Math.round(Math.random()*155+55); this.location.x+=Math.round(Math.random()*60)-30; this.location.y+=Math.round(Math.random()*40)-20; if(this.location.x<x){ this.speed.x=-Math.abs(this.speed.x); } else if(this.location.x>x){ this.speed.x=Math.abs(this.speed.x); } this.speed.x/=2; this.speed.y/=2; this.life*=2; this.death*=2; break; } default:{ this.r = 255; this.g = Math.round(Math.random()*155); this.b = 0; } } } game.draw(function(time,surface){ surface.globalCompositeOperation = "source-over"; surface.globalCompositeOperation = "lighter"; for(var i = 0; i < particles.length; i++) { var p = particles[i]; surface.beginPath(); var middle=0.5; var radius=p.radius; if(type=='recover'||type=='legend'||type=='rare'|| type=='epic'||type=='coin'||type=='dust'){ middle=0.7; radius/=3; } p.opacity = Math.round(p.death/p.life*100)/100 var gradient = surface.createRadialGradient(p.location.x, p.location.y, 0, p.location.x, p.location.y, p.radius); gradient.addColorStop(0, "rgba("+p.r+", "+p.g+", "+p.b+", "+p.opacity+")"); gradient.addColorStop(middle, "rgba("+p.r+", "+p.g+", "+p.b+", "+p.opacity+")"); gradient.addColorStop(1, "rgba("+p.r+", "+p.g+", "+p.b+", 0)"); surface.fillStyle = gradient; surface.arc(p.location.x, p.location.y, radius, Math.PI*2, false); surface.fill(); p.death--; if(type=='recover'){ p.radius+=0.5; } else if(type=='coin'||type=='dust'){ p.radius+=0.7; } else if(type=='legend'||type=='rare'||type=='epic'){ p.radius+=0.5; } else { p.radius++; } p.location.x += (p.speed.x); p.location.y += (p.speed.y); if(p.death < 0 || p.radius < 0){ if(typeof duration=='number'&&time+500>=duration){ particles.splice(i--,1); } else{ particles[i] = new particle(); } } } if(particles.length==0){ return false; } }); } }, linexy:function(path){ const from=[path[0],path[1]],to=[path[2],path[3]]; let total=typeof arguments[1]==='number'?arguments[1]:lib.config.duration*2,opacity=1,color=[255,255,255],dashed=false,drag=false; if(arguments[1]&&typeof arguments[1]=='object') Object.keys(arguments[1]).forEach(value=>{ switch(value){ case 'opacity': opacity=arguments[1][value]; break; case 'color': color=arguments[1][value]; break; case 'dashed': dashed=arguments[1][value]; break; case 'duration':total=arguments[1][value]; } }); else if(typeof arguments[1]=='string') color=arguments[1]; if(typeof color=='string') color=lib.lineColor.get(color)||[255,255,255]; let node; if(arguments[1]=='drag'){ color=[236,201,71]; drag=true; if(arguments[2]) node=arguments[2]; else{ node=ui.create.div('.linexy.drag'); node.style.left=`${from[0]}px`; node.style.top=`${from[1]}px`; node.style.background=`linear-gradient(transparent,rgba(${color.toString()},${opacity}),rgba(${color.toString()},${opacity}))`; if(game.chess) ui.chess.appendChild(node); else ui.arena.appendChild(node); } } else{ node=ui.create.div('.linexy.hidden'); node.style.left=`${from[0]}px`; node.style.top=`${from[1]}px`; node.style.background=`linear-gradient(transparent,rgba(${color.toString()},${opacity}),rgba(${color.toString()},${opacity}))`; node.style.transitionDuration=`${total/3000}s`; } const dy=to[1]-from[1],dx=to[0]-from[0]; let 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; if(drag){ node.style.transform=`rotate(${(-deg)}deg)`; node.style.height=`${get.xyDistance(from,to)}px`; } else{ node.style.transform=`rotate(${(-deg)}deg) scaleY(0)`; node.style.height=`${get.xyDistance(from,to)}px`; if(get.objtype(arguments[1])=='div') arguments[1].appendChild(node); else 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)`; node.listenTransition(()=>setTimeout(()=>{ if(!node.classList.contains('removing')) node.delete(); },total/3)); } return node; }, _linexy:function(path){ var from=[path[0],path[1]]; var to=[path[2],path[3]]; var total=typeof arguments[1]==='number'?arguments[1]:lib.config.duration*2; var opacity=1; var color=[255,255,255]; var dashed=false; if(typeof arguments[1]=='object'){ for(var i in arguments[1]){ switch(i){ case 'opacity':opacity=arguments[1][i];break; case 'color':color=arguments[1][i];break; case 'dashed':dashed=arguments[1][i];break; case 'duration':total=arguments[1][i];break; } } } else if(arguments[1]=='fire'||arguments[1]=='thunder'||arguments[1]=='green'){ color=arguments[1]; } if(color=='fire'){ color=[255, 146, 68]; } else if(color=='thunder'){ color=[141, 216, 255]; } else if(color=='green'){ color=[141, 255, 216]; } var drawfunc=function(time,ctx){ var current; if(time<total/3){ ctx.strokeStyle='rgba('+color.toString()+','+opacity*(time/(total/3))+')'; current=[from[0]+(to[0]-from[0])*time/(total/3), from[1]+(to[1]-from[1])*time/(total/3)]; } else if(time<=total){ current=to; if(time>total/1.5){ ctx.strokeStyle='rgba('+color.toString()+','+opacity*(1-(time-total/1.5)/(total-total/1.5))+')'; } else{ ctx.strokeStyle='rgba('+color.toString()+','+opacity+')'; } } else{ return false; } ctx.beginPath(); if(dashed){ ctx.lineCap='butt'; ctx.setLineDash([8,2]); } else{ ctx.lineCap='round'; } ctx.moveTo(from[0],from[1]); ctx.lineTo(current[0],current[1]); ctx.stroke(); }; if(arguments[2]&&game.chess){ game.draw2(drawfunc); } else{ game.draw(drawfunc); } }, createTrigger:function(name,skill,player,event){ var info=get.info(skill); if(!info) return false; if((player.isOut()||player.removed)&&!info.forceOut) return; if(player.isDead()&&!info.forceDie) return; var next=game.createEvent('trigger',false); next.skill=skill; next.player=player; next.triggername=name; next.forceDie=true; next.includeOut=true; next._trigger=event; next.setContent('createTrigger'); }, createEvent:function(name,trigger,triggerevent){ var next={ name:name, step:0, finished:false, next:[], after:[], custom:{ add:{}, replace:{} }, _aiexclude:[], _notrigger:[], _result:{}, _set:[], } if(trigger!==false&&!game.online) next._triggered=0; for(var i in lib.element.event){ next[i]=lib.element.event[i]; } (triggerevent||_status.event).next.push(next); return next; }, addCharacter:(name,information)=>{ const extensionName=_status.extension||information.extension,character=[ information.sex, information.group, information.hp, information.skills||[], [ _status.evaluatingExtension?`db:extension-${extensionName}:${name}.jpg`:`ext:${extensionName}/${name}.jpg`, `die:ext:${extensionName}/${name}.mp3` ] ]; if(information.tags) character[4]=character[4].concat(information.tags); lib.character[name]=character; const packName=`mode_extension_${extensionName}`; if(!lib.characterPack[packName]) lib.characterPack[packName]={}; lib.translate[name]=information.translate; lib.characterPack[packName][name]=character; lib.translate[`${packName}_character_config`]=extensionName; }, addCharacterPack:(pack,packagename)=>{ var extname=_status.extension||'扩展'; let gzFlag=false; packagename=packagename||extname; for(var i in pack){ if(i=='mode'){ if(pack[i]=="guozhan") gzFlag=true; continue; } if(i=='forbid') continue; for(var j in pack[i]){ if(i=='character'){ if(!pack[i][j][4]){ pack[i][j][4]=[]; } var imgsrc; if(_status.evaluatingExtension){ imgsrc='db:extension-'+extname+':'+j+'.jpg'; } else{ imgsrc='ext:'+extname+'/'+j+'.jpg'; } const audiosrc='die:ext:'+extname+'/'+j+'.mp3'; if(!pack[i][j][4].some(str=>typeof str=="string"&&/^(?:db:extension-|ext:):(?:.+)/.test(str))) pack[i][j][4].add(imgsrc); if(!pack[i][j][4].some(str=>typeof str=="string"&&/^die:(?:.+)/.test(str))) pack[i][j][4].add(audiosrc); if(pack[i][j][4].contains('boss')|| pack[i][j][4].contains('hiddenboss')){ lib.config.forbidai.add(j); } if(lib.config.forbidai_user&&lib.config.forbidai_user.contains(j)){ lib.config.forbidai.add(j); } for(var l=0;l<pack[i][j][3].length;l++){ lib.skilllist.add(pack[i][j][3][l]); } } else if(i=='skill'){ if(typeof pack[i][j].audio=='number'||typeof pack[i][j].audio=='boolean'){ pack[i][j].audio='ext:'+extname+':'+pack[i][j].audio; } } if(lib[i][j]==undefined){ lib[i][j]=pack[i][j]; } } } var packname='mode_extension_'+packagename; lib.characterPack[packname]=pack.character; lib.translate[packname+'_character_config']=packagename; if(gzFlag) lib.characterGuozhanFilter.add(packname); }, addCard:function(name,info,info2){ var extname=(_status.extension||info2.extension); if(info.audio==true){ info.audio='ext:'+extname; } if(info.fullskin){ if(_status.evaluatingExtension){ info.image='db:extension-'+extname+':'+name+'.png'; } else{ info.image='ext:'+extname+'/'+name+'.png'; } } else if(info.fullimage){ if(_status.evaluatingExtension){ info.image='db:extension-'+extname+':'+name+'.jpg'; } else{ info.image='ext:'+extname+'/'+name+'.jpg'; } } lib.card[name]=info; lib.translate[name]=info2.translate; lib.translate[name+'_info']=info2.description; if(typeof info2.number=='number'){ var suits=['heart','spade','diamond','club']; if(info2.color=='red'){ suits=['heart','diamond']; } else if(info2.color=='black'){ suits=['club','spade']; } for(var i=0;i<info2.number;i++){ lib.card.list.push([suits[Math.floor(Math.random()*suits.length)],Math.ceil(Math.random()*13),name]); } } var packname='mode_extension_'+extname; if(!lib.cardPack[packname]){ lib.cardPack[packname]=[]; lib.translate[packname+'_card_config']=extname; } lib.cardPack[packname].push(name); }, addCardPack:function(pack,packagename){ var extname=_status.extension||'扩展'; packagename=packagename||extname; var packname='mode_extension_'+packagename; lib.cardPack[packname]=[]; lib.translate[packname+'_card_config']=packagename; for(var i in pack){ if(i=='mode'||i=='forbid') continue; if(i=='list'){ for(var j=0;j<pack[i].length;j++){ lib.card.list.push(pack[i][j]); } continue; } for(var j in pack[i]){ if(i=='card'){ if(pack[i][j].audio==true){ pack[i][j].audio='ext:'+extname; } if(pack[i][j].fullskin){ if(_status.evaluatingExtension){ pack[i][j].image='db:extension-'+extname+':'+j+'.png'; } else{ pack[i][j].image='ext:'+extname+'/'+j+'.png'; } } else if(pack[i][j].fullimage){ if(_status.evaluatingExtension){ pack[i][j].image='db:extension-'+extname+':'+j+'.jpg'; } else{ pack[i][j].image='ext:'+extname+'/'+j+'.jpg'; } } lib.cardPack[packname].push(j); } else if(i=='skill'){ if(typeof pack[i][j].audio=='number'||typeof pack[i][j].audio=='boolean'){ pack[i][j].audio='ext:'+extname+':'+pack[i][j].audio; } } if(lib[i][j]==undefined) lib[i][j]=pack[i][j]; } } }, addSkill:function(name,info,translate,description,appendInfo){ if(lib.skill[name]){ return false; } if(typeof info.audio=='number'||typeof info.audio=='boolean'){ info.audio='ext:'+_status.extension+':'+info.audio; } lib.skill[name]=info; lib.translate[name]=translate; lib.translate[name+'_info']=description; lib.translate[name+'_append']=appendInfo; return true; }, addMode:function(name,info,info2){ lib.config.all.mode.push(name); lib.translate[name]=info2.translate; var imgsrc; var extname=_status.extension||info2.extension; if(_status.evaluatingExtension){ imgsrc='extension-'+extname+':'+name+'.jpg'; } else{ imgsrc='ext:'+extname+'/'+name+'.jpg'; } lib.mode[name]={ name:info2.translate, config:info2.config, splash:imgsrc, fromextension:true } lib.init['setMode_'+name]=gnc.of(function*(){ yield game.import('mode',function(lib,game,ui,get,ai,_status){ info.name=name; return info; }); }); if(!lib.config.extensionInfo[extname]){ lib.config.extensionInfo[extname]={}; } if(!lib.config.extensionInfo[extname].mode){ lib.config.extensionInfo[extname].mode=[]; } if(lib.config.extensionInfo[extname].mode.indexOf(name)==-1){ lib.config.extensionInfo[extname].mode.push(name); } game.saveConfig('extensionMode',lib.config.extensionInfo); }, addGlobalSkill:function(skill,player){ var info=lib.skill[skill]; if(!info) return false; lib.skill.global.add(skill); if(player){ if(!lib.skill.globalmap[skill]){ lib.skill.globalmap[skill]=[]; } lib.skill.globalmap[skill].add(player); } if(info.trigger){ var setTrigger=function(i,evt){ var name=i+'_'+evt; if(!lib.hook.globalskill[name]){ lib.hook.globalskill[name]=[]; } lib.hook.globalskill[name].add(skill); lib.hookmap[evt]=true; } for(var i in info.trigger){ if(typeof info.trigger[i]=='string'){ setTrigger(i,info.trigger[i]); } else if(Array.isArray(info.trigger[i])){ for(var j=0;j<info.trigger[i].length;j++){ setTrigger(i,info.trigger[i][j]); } } } } return true; }, removeGlobalSkill:function(skill){ lib.skill.global.remove(skill); delete lib.skill.globalmap[skill]; for(var i in lib.hook.globalskill){ lib.hook.globalskill[i].remove(skill); } }, resetSkills:function(){ for(var i=0;i<game.players.length;i++){ for(var j in game.players[i].tempSkills){ game.players[i].removeSkill(j); } var skills=game.players[i].getSkills(); for(var j=0;j<skills.length;j++){ if(lib.skill[skills[j]].vanish){ game.players[i].removeSkill(skills[j]); } } game.players[i].in(true); } ui.clear(); }, removeExtension:(extensionName,keepFile)=>{ const prefix=`extension_${extensionName}`; Object.keys(lib.config).forEach(key=>{ if(key.startsWith(prefix)) game.saveConfig(key); }); localStorage.removeItem(`${lib.configprefix}${prefix}`); game.deleteDB('data',prefix); lib.config.extensions.remove(extensionName); game.saveConfig('extensions',lib.config.extensions); const modeList=lib.config.extensionInfo[extensionName]; if(modeList){ if(modeList.file) Object.values(modeList.file).forEach(filePath=>game.deleteDB('image',`extension-${extensionName}:${filePath}`)); if(modeList.mode) Object.values(modeList.mode).forEach(game.clearModeConfig); delete lib.config.extensionInfo[extensionName]; game.saveConfigValue('extensionInfo'); } if(!game.download||keepFile) return; if(lib.node&&lib.node.fs) try{ const deleteFolderRecursive=path=>{ if(!lib.node.fs.existsSync(path)) return; lib.node.fs.readdirSync(path).forEach((file,index)=>{ const currentPath = `${path}/${file}`; if (lib.node.fs.lstatSync(currentPath).isDirectory()) deleteFolderRecursive(currentPath); else lib.node.fs.unlinkSync(currentPath); }); lib.node.fs.rmdirSync(path); }; deleteFolderRecursive(`${__dirname}/extension/${extensionName}`); } catch(error){ console.log(error); } else new Promise((resolve,reject)=>window.resolveLocalFileSystemURL(`${lib.assetURL}extension/${extensionName}`,resolve,reject)).then(directoryEntry=>directoryEntry.removeRecursively()); }, addRecentCharacter:function(){ var list=get.config('recentCharacter')||[]; for(var i=0;i<arguments.length;i++){ if(lib.character[arguments[i]]){ list.remove(arguments[i]); list.unshift(arguments[i]); } } var num=parseInt(lib.config.recent_character_number); if(list.length>num){ list.splice(num); } game.saveConfig('recentCharacter',list,true); }, createCard:function(name,suit,number,nature){ if(typeof name=='object'){ nature=name.nature; number=name.number; suit=name.suit; name=name.name; } if(typeof name!='string'){ name='sha'; } var noclick=false; if(suit=='noclick'){ noclick=true; suit=null; } if(!suit&&lib.card[name].cardcolor){ suit=lib.card[name].cardcolor; } if(!nature&&lib.card[name].cardnature){ nature=lib.card[name].cardnature; } if(typeof suit!='string'){ suit=['heart','diamond','club','spade'].randomGet(); } else if(suit=='black'){ suit=Math.random()<0.5?'club':'spade'; } else if(suit=='red'){ suit=Math.random()<0.5?'diamond':'heart'; } if(typeof number!='number'&&typeof number!='string'){ number=Math.ceil(Math.random()*13); } var card; if(noclick){ card=ui.create.card(ui.special,'noclick',true); } else{ card=ui.create.card(ui.special); } card.storage.vanish=true; return card.init([suit,number,name,nature]); }, createCard2:function(){ var card=game.createCard.apply(this,arguments); delete card.storage.vanish; return card; }, forceOver:function(bool,callback){ _status.event.next.length=0; var next=game.createEvent('finish_game'); next.bool=bool; next.callback=callback; next.setContent('forceOver'); if(_status.paused){ game.uncheck(); game.resume(); } }, over:function(result){ if(_status.over) return; if(game.me._trueMe) game.swapPlayer(game.me._trueMe); var i,j,k,num,table,tr,td,dialog; _status.over=true; ui.control.show(); ui.clear(); game.stopCountChoose(); if(ui.time3){ clearInterval(ui.time3.interval); } if((game.layout=='long2'||game.layout=='nova')&&!game.chess){ ui.arena.classList.add('choose-character'); ui.me.hide(); ui.mebg.hide() ui.autonode.hide(); if(lib.config.radius_size!='off'){ ui.historybar.style.borderRadius='0 0 0 4px'; } } if(game.online){ var dialog=ui.create.dialog(); dialog.noforcebutton=true; dialog.content.innerHTML=result; dialog.forcebutton=true; var result2=arguments[1]; if(result2==true){ dialog.content.firstChild.innerHTML='战斗胜利'; } else if(result2==false){ dialog.content.firstChild.innerHTML='战斗失败'; } ui.update(); dialog.add(ui.create.div('.placeholder')); for(var i=0;i<game.players.length;i++){ var hs=game.players[i].getCards('h'); if(hs.length){ dialog.add('<div class="text center">'+get.translation(game.players[i])+'</div>'); dialog.addSmall(hs); } } for(var j=0;j<game.dead.length;j++){ var hs=game.dead[j].getCards('h'); if(hs.length){ dialog.add('<div class="text center">'+get.translation(game.dead[j])+'</div>'); dialog.addSmall(hs); } } dialog.add(ui.create.div('.placeholder.slim')); if(lib.config.background_audio){ if(result2===true){ game.playAudio('effect','win'); } else if(result2===false){ game.playAudio('effect','lose'); } else{ game.playAudio('effect','tie'); } } if(!ui.exit){ ui.create.exit(); } if(ui.giveup){ ui.giveup.remove(); delete ui.giveup; } if(game.servermode){ ui.exit.firstChild.innerHTML='返回房间'; setTimeout(function(){ ui.exit.firstChild.innerHTML='退出房间'; _status.roomtimeout=true; lib.config.reconnect_info[2]=null; game.saveConfig('reconnect_info',lib.config.reconnect_info); },10000); } if(ui.tempnowuxie){ ui.tempnowuxie.close(); delete ui.tempnowuxie; } if(ui.auto) ui.auto.hide(); if(ui.wuxie) ui.wuxie.hide(); if(game.getIdentityList){ for(var i=0;i<game.players.length;i++){ game.players[i].setIdentity(); } } return; } if(lib.config.background_audio){ if(result===true){ game.playAudio('effect','win'); } else if(result===false){ game.playAudio('effect','lose'); } else{ game.playAudio('effect','tie'); } } var resultbool=result; if(typeof resultbool!=='boolean'){ resultbool=null; } if(result===true) result='战斗胜利'; if(result===false) result='战斗失败'; if(result==undefined) result='战斗结束'; dialog=ui.create.dialog(result); dialog.noforcebutton=true; dialog.forcebutton=true; if(game.addOverDialog){ game.addOverDialog(dialog,result); } if(typeof _status.coin=='number'&&!_status.connectMode){ var coeff=Math.random()*0.4+0.8; var added=0; var betWin=false; if(result=='战斗胜利'){ if(_status.betWin){ betWin=true; _status.coin+=10; } _status.coin+=20; if(_status.additionalReward){ _status.coin+=_status.additionalReward(); } switch(lib.config.mode){ case 'identity':{ switch(game.me.identity){ case 'zhu':case 'zhong':case 'mingzhong': if(get.config('enhance_zhu')){ added=10; } else{ added=20; } break; case 'fan': if(get.config('enhance_zhu')){ added=16; } else{ added=8; } break; case 'nei': added=40; break; } added=added*(game.players.length+game.dead.length)/8; break; } case 'guozhan': if(game.me.identity=='ye'){ added=8; } else{ added=5/get.totalPopulation(game.me.identity); } added=added*(game.players.length+game.dead.length); break; case 'versus': if(_status.friend){ added=5*(game.players.length+_status.friend.length); } break; default: added=10; } } else{ added=10; } if(lib.config.mode=='chess'&&_status.mode=='combat'&&get.config('additional_player')){ added=2; } _status.coin+=added*coeff; if(_status.coinCoeff){ _status.coin*=_status.coinCoeff; } _status.coin=Math.ceil(_status.coin); dialog.add(ui.create.div('','获得'+_status.coin+'金')); if(betWin){ game.changeCoin(20); dialog.content.appendChild(document.createElement('br')); dialog.add(ui.create.div('','(下注赢得10金)')); } game.changeCoin(_status.coin); } if(get.mode()=='versus'&&_status.ladder){ var mmr=_status.ladder_mmr; mmr+=10-get.rank(game.me.name,true)*2; if(result=='战斗胜利'){ mmr=20+Math.round(mmr); if(mmr>40){ mmr=40; } else if(mmr<10){ mmr=10; } dialog.add(ui.create.div('','获得 '+mmr+' 积分')); } else{ mmr=-30+Math.round(mmr/2); if(mmr>-20){ mmr=-20; } else if(mmr<-35){ mmr=-35; } if(lib.storage.ladder.current<900){ mmr=Math.round(mmr/4); } else if(lib.storage.ladder.current<1400){ mmr=Math.round(mmr/2); } else if(lib.storage.ladder.current<2000){ mmr=Math.round(mmr/1.5); } else if(lib.storage.ladder.current>2500){ mmr=Math.round(mmr*1.5); } dialog.add(ui.create.div('','失去 '+(-mmr)+' 积分')); } if(_status.ladder_tmp){ lib.storage.ladder.current+=40; delete _status.ladder_tmp; } lib.storage.ladder.current+=mmr; if(lib.storage.ladder.top<lib.storage.ladder.current){ lib.storage.ladder.top=lib.storage.ladder.current; } game.save('ladder',lib.storage.ladder); if(ui.ladder&&game.getLadderName){ ui.ladder.innerHTML=game.getLadderName(lib.storage.ladder.current); } } // if(true){ if(game.players.length){ table=document.createElement('table'); tr=document.createElement('tr'); tr.appendChild(document.createElement('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); td=document.createElement('td'); td.innerHTML='出牌'; tr.appendChild(td); td=document.createElement('td'); td.innerHTML='杀敌'; tr.appendChild(td); table.appendChild(tr); for(i=0;i<game.players.length;i++){ tr=document.createElement('tr'); td=document.createElement('td'); td.innerHTML=get.translation(game.players[i]); tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.players[i].stat.length;j++){ if(game.players[i].stat[j].damage!=undefined) num+=game.players[i].stat[j].damage; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.players[i].stat.length;j++){ if(game.players[i].stat[j].damaged!=undefined) num+=game.players[i].stat[j].damaged; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.players[i].stat.length;j++){ if(game.players[i].stat[j].gain!=undefined) num+=game.players[i].stat[j].gain; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.players[i].stat.length;j++){ for(k in game.players[i].stat[j].card){ num+=game.players[i].stat[j].card[k]; } } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.players[i].stat.length;j++){ if(game.players[i].stat[j].kill!=undefined) num+=game.players[i].stat[j].kill; } td.innerHTML=num; tr.appendChild(td); table.appendChild(tr); } dialog.add(ui.create.div('.placeholder')); dialog.content.appendChild(table); } if(game.dead.length){ table=document.createElement('table'); table.style.opacity='0.5'; if(game.players.length==0){ tr=document.createElement('tr'); tr.appendChild(document.createElement('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); td=document.createElement('td'); td.innerHTML='出牌'; tr.appendChild(td); td=document.createElement('td'); td.innerHTML='杀敌'; tr.appendChild(td); table.appendChild(tr); } for(i=0;i<game.dead.length;i++){ tr=document.createElement('tr'); td=document.createElement('td'); td.innerHTML=get.translation(game.dead[i]); tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.dead[i].stat.length;j++){ if(game.dead[i].stat[j].damage!=undefined) num+=game.dead[i].stat[j].damage; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.dead[i].stat.length;j++){ if(game.dead[i].stat[j].damaged!=undefined) num+=game.dead[i].stat[j].damaged; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.dead[i].stat.length;j++){ if(game.dead[i].stat[j].gain!=undefined) num+=game.dead[i].stat[j].gain; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.dead[i].stat.length;j++){ for(k in game.dead[i].stat[j].card){ num+=game.dead[i].stat[j].card[k]; } } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.dead[i].stat.length;j++){ if(game.dead[i].stat[j].kill!=undefined) num+=game.dead[i].stat[j].kill; } td.innerHTML=num; tr.appendChild(td); table.appendChild(tr); } dialog.add(ui.create.div('.placeholder')); dialog.content.appendChild(table); } if(game.additionaldead&&game.additionaldead.length){ table=document.createElement('table'); table.style.opacity='0.5'; for(i=0;i<game.additionaldead.length;i++){ tr=document.createElement('tr'); td=document.createElement('td'); td.innerHTML=get.translation(game.additionaldead[i]); tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.additionaldead[i].stat.length;j++){ if(game.additionaldead[i].stat[j].damage!=undefined) num+=game.additionaldead[i].stat[j].damage; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.additionaldead[i].stat.length;j++){ if(game.additionaldead[i].stat[j].damaged!=undefined) num+=game.additionaldead[i].stat[j].damaged; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.additionaldead[i].stat.length;j++){ if(game.additionaldead[i].stat[j].gain!=undefined) num+=game.additionaldead[i].stat[j].gain; } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.additionaldead[i].stat.length;j++){ for(k in game.additionaldead[i].stat[j].card){ num+=game.additionaldead[i].stat[j].card[k]; } } td.innerHTML=num; tr.appendChild(td); td=document.createElement('td'); num=0; for(j=0;j<game.additionaldead[i].stat.length;j++){ if(game.additionaldead[i].stat[j].kill!=undefined) num+=game.additionaldead[i].stat[j].kill; } td.innerHTML=num; tr.appendChild(td); table.appendChild(tr); } dialog.add(ui.create.div('.placeholder')); dialog.content.appendChild(table); } // } dialog.add(ui.create.div('.placeholder')); var clients=game.players.concat(game.dead); for(var i=0;i<clients.length;i++){ if(clients[i].isOnline2()){ clients[i].send(game.over,dialog.content.innerHTML,game.checkOnlineResult(clients[i])); } } dialog.add(ui.create.div('.placeholder')); for(var i=0;i<game.players.length;i++){ if(!_status.connectMode&&game.players[i].isUnderControl(true)&&game.layout!='long2') continue; var hs=game.players[i].getCards('h'); if(hs.length){ dialog.add('<div class="text center">'+get.translation(game.players[i])+'</div>'); dialog.addSmall(hs); } } for(var i=0;i<game.dead.length;i++){ if(!_status.connectMode&&game.dead[i].isUnderControl(true)&&game.layout!='long2') continue; var hs=game.dead[i].getCards('h'); if(hs.length){ dialog.add('<div class="text center">'+get.translation(game.dead[i])+'</div>'); dialog.addSmall(hs); } } dialog.add(ui.create.div('.placeholder.slim')); game.addVideo('over',null,dialog.content.innerHTML); var vinum=parseInt(lib.config.video); if(!_status.video&&vinum&&game.getVideoName&&window.indexedDB&&_status.videoInited){ 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>=vinum){ var toremove=videos.pop(); lib.videos.remove(toremove); store.delete(toremove.time); } else{ break; } } var me=game.me||game.players[0]; if(!me) return; var newvid={ name:game.getVideoName(), mode:lib.config.mode, video:lib.video, win:result=='战斗胜利', name1:me.name1||me.name, name2:me.name2, time:lib.getUTC(new Date()) }; var modecharacters=lib.characterPack['mode_'+get.mode()]; if(modecharacters){ if(get.mode()=='guozhan'){ if(modecharacters[newvid.name1]){ if(newvid.name1.startsWith('gz_shibing')){ newvid.name1=newvid.name1.slice(3,11); } else{ newvid.name1=newvid.name1.slice(3); } } if(modecharacters[newvid.name2]){ if(newvid.name2.startsWith('gz_shibing')){ newvid.name2=newvid.name2.slice(3,11); } else{ newvid.name2=newvid.name2.slice(3); } } } else{ if(modecharacters[newvid.name1]){ newvid.name1=get.mode()+'::'+newvid.name1; } if(modecharacters[newvid.name2]){ newvid.name2=get.mode()+'::'+newvid.name2; } } } if(newvid.name1&&newvid.name1.startsWith('subplayer_')){ newvid.name1=newvid.name1.slice(10,newvid.name1.lastIndexOf('_')); } if(newvid.name2&&newvid.name2.startsWith('subplayer_')){ newvid.name1=newvid.name2.slice(10,newvid.name1.lastIndexOf('_')); } lib.videos.unshift(newvid); store.put(newvid); ui.create.videoNode(newvid,true); } // _status.auto=false; if(ui.auto){ // ui.auto.classList.remove('glow'); ui.auto.hide(); } if(ui.wuxie) ui.wuxie.hide(); if(ui.giveup){ ui.giveup.remove(); delete ui.giveup; } if(lib.config.test_game&&!_status.connectMode){ if(typeof lib.config.test_game!=='string'){ switch(lib.config.mode){ case 'identity':game.saveConfig('mode','guozhan');break; case 'guozhan':game.saveConfig('mode','versus');break; case 'versus':game.saveConfig('mode','boss');break; case 'boss':game.saveConfig('mode','chess');break; case 'chess':game.saveConfig('mode','stone');break; case 'stone':game.saveConfig('mode','identity');break; } } setTimeout(game.reload,500); } if(game.controlOver){ game.controlOver();return; } if(!_status.brawl){ if(lib.config.mode=='boss'){ ui.create.control('再战',function(){ var pointer=game.boss; var map={boss:game.me==game.boss,links:[]}; for(var iwhile=0;iwhile<10;iwhile++){ pointer=pointer.nextSeat; if(pointer==game.boss){ break; } if(!pointer.side){ map.links.push(pointer.name); } } game.saveConfig('continue_name_boss',map); game.saveConfig('mode',lib.config.mode); localStorage.setItem(lib.configprefix+'directstart',true); game.reload(); }); } else if(lib.config.mode=='versus'){ if(_status.mode=='standard'||_status.mode=='three'){ ui.create.control('再战',function(){ game.saveConfig('continue_name_versus'+(_status.mode=='three'?'_three':''),{ friend:_status.friendBackup, enemy:_status.enemyBackup, color:_status.color }); game.saveConfig('mode',lib.config.mode); localStorage.setItem(lib.configprefix+'directstart',true); game.reload(); }); } } else if(!_status.connectMode&&get.config('continue_game')&&!ui.continue_game&&!_status.brawl&&!game.no_continue_game){ ui.continue_game=ui.create.control('再战',game.reloadCurrent); } } if(!ui.restart){ if(game.onlineroom&&typeof game.roomId=='string'){ ui.restart=ui.create.control('restart',function(){ game.broadcastAll(function(){ if(ui.exit){ ui.exit.stay=true; ui.exit.firstChild.innerHTML='返回房间'; } }); game.saveConfig('tmp_owner_roomId',game.roomId); setTimeout(game.reload,100); }); } else{ ui.restart=ui.create.control('restart',game.reload); } } if(ui.tempnowuxie){ ui.tempnowuxie.close(); delete ui.tempnowuxie; } if(ui.revive){ ui.revive.close(); delete ui.revive; } if(ui.swap){ ui.swap.close(); delete ui.swap; } for(var i=0;i<lib.onover.length;i++){ lib.onover[i](resultbool); } if(game.addRecord){ game.addRecord(resultbool); } if(window.isNonameServer){ lib.configOL.gameStarted=false; game.saveConfig('pagecfg'+window.isNonameServer,[lib.configOL,game.roomId,_status.onlinenickname,_status.onlineavatar]); game.reload(); } else if(_status.connectMode&&!game.online){ setTimeout(game.reload,15000) } }, loop:function(){ while(true){ var event=_status.event; var step=event.step; var source=event.source; var player=event.player; var target=event.target; var targets=event.targets; var card=event.card; var cards=event.cards; var skill=event.skill; var forced=event.forced; var num=event.num; var trigger=event._trigger; var result=event._result; if(_status.paused2||_status.imchoosing){ if(!lib.status.dateDelaying){ lib.status.dateDelaying=new Date(); } } if(_status.paused||_status.paused2||_status.over){ return; } if(_status.paused3){ _status.paused3='paused'; return; } if(lib.status.dateDelaying){ lib.status.dateDelayed+=lib.getUTC(new Date())-lib.getUTC(lib.status.dateDelaying); delete lib.status.dateDelaying; } if(event.next.length>0){ var next=event.next.shift(); if(next.player&&next.player.skipList.contains(next.name)){ event.trigger(next.name+'Skipped'); next.player.skipList.remove(next.name); if(lib.phaseName.contains(next.name)) next.player.getHistory('skipped').add(next.name); } else{ next.parent=event; _status.event=next; game.getGlobalHistory('everything').push(next); } } else if(event.finished){ if(event._triggered==1){ if(event.type=='card') event.trigger('useCardToOmitted'); event.trigger(event.name+'Omitted'); event._triggered=4; } else if(event._triggered==2){ if(event.type=='card') event.trigger('useCardToEnd'); event.trigger(event.name+'End'); event._triggered=3; } else if(event._triggered==3){ if(event.type=='card') event.trigger('useCardToAfter'); event.trigger(event.name+'After'); event._triggered++; } else if(event.after&&event.after.length){ var next=event.after.shift(); if(next.player&&next.player.skipList.contains(next.name)){ event.trigger(next.name+'Skipped'); next.player.skipList.remove(next.name); if(lib.phaseName.contains(next.name)) next.player.getHistory('skipped').add(next.name) } else{ next.parent=event; _status.event=next; } } else{ if(event.parent){ if(event.result){ event.parent._result=event.result; } _status.event=event.parent; } else{ return; } } } else{ if(event._triggered==0){ if(event.type=='card') event.trigger('useCardToBefore'); event.trigger(event.name+'Before'); event._triggered++; } else if(event._triggered==1){ if(event.type=='card') event.trigger('useCardToBegin'); event.trigger(event.name+'Begin'); event._triggered++; /*if(event.name=='phase'&&!event._begun){ var next=game.createEvent('phasing',false,event); next.player=event.player; next.skill=event.skill; next.setContent('phasing'); event._begun=true; } else{ event.trigger(event.name+'Begin'); event._triggered++; }*/ } else{ if(player&&player.classList.contains('dead')&&!event.forceDie&&event.name!='phaseLoop'){ game.broadcastAll(function(){ while(_status.dieClose.length){ _status.dieClose.shift().close(); } }); if(event._oncancel){ event._oncancel(); } event.finish(); } else if(player&&player.removed&&event.name!='phaseLoop'){ event.finish(); } else if(player&&player.isOut()&&event.name!='phaseLoop'&&!event.includeOut){ if(event.name=='phase'&&player==_status.roundStart&&!event.skill){ _status.roundSkipped=true; } event.finish(); } else{ if(_status.withError||lib.config.compatiblemode||(_status.connectMode&&!lib.config.debug)){ try{ event.content(event,step,source,player,target,targets, card,cards,skill,forced,num,trigger,result, _status,lib,game,ui,get,ai); } catch(e){ game.print('游戏出错:'+event.name); game.print(e.toString()); console.log(e); } } else{ event.content(event,step,source,player,target,targets, card,cards,skill,forced,num,trigger,result, _status,lib,game,ui,get,ai); } } event.clearStepCache(); event.step++; } } } }, pause:function(){ clearTimeout(_status.timeout); _status.paused=true; }, pause2:function(){ if(_status.connectMode) return; _status.paused2=true; }, resume:function(){ if(_status.paused){ if(!_status.noclearcountdown){ game.stopCountChoose(); } _status.paused=false; delete _status.waitingForTransition; game.loop(); } }, resume2:function(){ if(_status.connectMode) return; if(_status.paused2){ _status.paused2=false; game.loop(); } }, delaye:function(){ var next=game.createEvent('delay',false); next.setContent('delay'); next._args=Array.from(arguments); return next; }, delayex:function(){ var next=game.createEvent('delayx',false); next.setContent('delay'); next._args=Array.from(arguments); return next; }, delay:function(time,time2){ if(_status.paused) return; game.pause(); if(typeof time!='number') time=1; if(typeof time2!='number') time2=0; time=time*lib.config.duration+time2; if(lib.config.speed=='vvfast') time/=3; _status.timeout=setTimeout(game.resume,time); }, delayx:function(time,time2){ if(typeof time!='number') time=1; switch(lib.config.game_speed){ case 'vslow':time*=2.5;break; case 'slow':time*=1.5;break; case 'fast':time*=0.7;break; case 'vfast':time*=0.4;break; case 'vvfast':time*=0.2;break; } return game.delay(time,time2); }, check:function(event){ var i,j,range; if(event==undefined) event=_status.event; event._checked=true; var custom=event.custom||{}; var ok=true,auto=true; var player=event.player; var auto_confirm=lib.config.auto_confirm; var players=game.players.slice(0); if(event.deadTarget) players.addArray(game.dead); if(!event.filterButton&&!event.filterCard&&!event.filterTarget&&(!event.skill||!event._backup)){ if(event.choosing){ _status.imchoosing=true; } return; } player.node.equips.classList.remove('popequip'); if(event.filterButton){ var dialog=event.dialog; range=get.select(event.selectButton); var selectableButtons=false; if(event.forceAuto&&ui.selected.buttons.length==range[1]) auto=true; else if(range[0]!=range[1]||range[0]>1) auto=false; for(i=0;i<dialog.buttons.length;i++){ if(dialog.buttons[i].classList.contains('unselectable')) continue; if(event.filterButton(dialog.buttons[i],player)&&lib.filter.buttonIncluded(dialog.buttons[i])){ if(ui.selected.buttons.length<range[1]){ dialog.buttons[i].classList.add('selectable'); } else if(range[1]<=-1){ dialog.buttons[i].classList.add('selected'); ui.selected.buttons.add(dialog.buttons[i]); } else{ dialog.buttons[i].classList.remove('selectable'); } } else{ dialog.buttons[i].classList.remove('selectable'); if(range[1]<=-1){ dialog.buttons[i].classList.remove('selected'); ui.selected.buttons.remove(dialog.buttons[i]); } } if(dialog.buttons[i].classList.contains('selected')){ dialog.buttons[i].classList.add('selectable'); } else if(!selectableButtons&&dialog.buttons[i].classList.contains('selectable')){ selectableButtons=true; } } if(ui.selected.buttons.length<range[0]){ if(!event.forced||selectableButtons){ ok=false; } if(event.complexSelect||event.getParent().name=='chooseCharacter'||event.getParent().name=='chooseButtonOL'){ ok=false; } } if(custom.add.button){ custom.add.button(); } } if(event.filterCard){ if(ok==false){ game.uncheck('card'); } else{ var cards=player.getCards(event.position); var firstCheck=false; range=get.select(event.selectCard); if(!event._cardChoice&&typeof event.selectCard!='function'&& !event.complexCard&&range[1]>-1&&!lib.config.compatiblemode){ event._cardChoice=[]; firstCheck=true; } if(event.isMine()&&event.name=='chooseToUse'&&event.parent.name=='phaseUse'&&!event.skill&& !event._targetChoice&&!firstCheck&&window.Map&&!lib.config.compatiblemode){ event._targetChoice=new Map(); for(var i=0;i<event._cardChoice.length;i++){ if(!lib.card[event._cardChoice[i].name].complexTarget){ var targets=[]; for(var j=0;j<players.length;j++){ if(event.filterTarget(event._cardChoice[i],player,players[j])){ targets.push(players[j]); } } event._targetChoice.set(event._cardChoice[i],targets); } } } var selectableCards=false; if(range[0]!=range[1]||range[0]>1) auto=false; for(i=0;i<cards.length;i++){ if(lib.config.cardtempname!='off'){ var cardname=get.name(cards[i]); if(cards[i].name!=cardname||!get.is.sameNature(get.nature(cards[i]),cards[i].nature,true)){ var node=ui.create.cardTempName(cards[i]); var cardtempnameConfig=lib.config.cardtempname; if(cardtempnameConfig!=='default') node.classList.remove('vertical'); } } var nochess=true; if(!lib.filter.cardAiIncluded(cards[i])){ nochess=false; } else if(event._cardChoice&&!firstCheck){ if(!event._cardChoice.contains(cards[i])){ nochess=false; } } else{ if(player.isOut()||!lib.filter.cardRespondable(cards[i],player)|| cards[i].classList.contains('uncheck')|| !event.filterCard(cards[i],player)){ nochess=false; } } if(nochess){ if(ui.selected.cards.length<range[1]){ cards[i].classList.add('selectable'); if(event._cardChoice&&firstCheck){ event._cardChoice.push(cards[i]); } } else if(range[1]<=-1){ cards[i].classList.add('selected'); cards[i].updateTransform(true); ui.selected.cards.add(cards[i]); } else{ cards[i].classList.remove('selectable'); } } else{ cards[i].classList.remove('selectable'); if(range[1]<=-1){ cards[i].classList.remove('selected'); cards[i].updateTransform(); ui.selected.cards.remove(cards[i]); } } if(cards[i].classList.contains('selected')){ cards[i].classList.add('selectable'); } else if(!selectableCards&&cards[i].classList.contains('selectable')){ selectableCards=true; } } if(ui.selected.cards.length<range[0]){ if(!event.forced||selectableCards||event.complexSelect){ ok=false; } } if(lib.config.popequip&&get.is.phoneLayout()&& typeof event.position=='string'&&event.position.includes('e')&& player.node.equips.querySelector('.card.selectable')){ player.node.equips.classList.add('popequip'); auto_confirm=false; } } if(custom.add.card){ custom.add.card(); } } if(event.filterTarget){ if(ok==false){ game.uncheck('target'); } else{ var card=get.card(); var firstCheck=false; range=get.select(event.selectTarget); var selectableTargets=false; if(range[0]!=range[1]||range[0]>1) auto=false; for(i=0;i<players.length;i++){ var nochess=true; if(game.chess&&!event.chessForceAll&&player&&get.distance(player,players[i],'pure')>7){ nochess=false; } else if(players[i].isOut()){ nochess=false; } else if(event._targetChoice&&event._targetChoice.has(card)){ var targetChoice=event._targetChoice.get(card); if(!Array.isArray(targetChoice)||!targetChoice.contains(players[i])){ nochess=false; } } else if(!event.filterTarget(card,player,players[i])){ nochess=false; } if(nochess){ if(ui.selected.targets.length<range[1]){ players[i].classList.add('selectable'); if(Array.isArray(event._targetChoice)){ event._targetChoice.push(players[i]); } } else if(range[1]<=-1){ players[i].classList.add('selected'); ui.selected.targets.add(players[i]); } else{ players[i].classList.remove('selectable'); } } else{ players[i].classList.remove('selectable'); if(range[1]<=-1){ players[i].classList.remove('selected'); ui.selected.targets.remove(players[i]); } } if(players[i].classList.contains('selected')){ players[i].classList.add('selectable'); } else if(!selectableTargets&&players[i].classList.contains('selectable')){ selectableTargets=true; } if(players[i].instance){ if(players[i].classList.contains('selected')){ players[i].instance.classList.add('selected'); } else{ players[i].instance.classList.remove('selected'); } if(players[i].classList.contains('selectable')){ players[i].instance.classList.add('selectable'); } else{ players[i].instance.classList.remove('selectable'); } } } if(ui.selected.targets.length<range[0]){ if(!event.forced||selectableTargets||event.complexSelect){ ok=false; } } if(range[1]<=-1&&ui.selected.targets.length==0&&event.targetRequired){ ok=false; } } if(custom.add.target){ custom.add.target(); } } if(!event.skill&&get.noSelected()&&!_status.noconfirm){ var skills=[],enable,info; var skills2; if(event._skillChoice){ skills2=event._skillChoice; for(var i=0;i<skills2.length;i++){ if(event.isMine()||!event._aiexclude.contains(skills2[i])){ skills.push(skills2[i]); } } } else{ var skills2; if(get.mode()=='guozhan'&&player.hasSkillTag('nomingzhi',false,null,true)){ skills2=player.getSkills(false,true,false); } else{ skills2=player.getSkills('invisible',true,false); } skills2=game.filterSkills(skills2.concat(lib.skill.global),player,player.getSkills('e').concat(lib.skill.global)); event._skillChoice=[]; game.expandSkills(skills2); for(i=0;i<skills2.length;i++){ info=get.info(skills2[i]); enable=false; if(typeof info.enable=='function') enable=info.enable(event); else if(Array.isArray(info.enable)) enable=info.enable.contains(event.name); else if(info.enable=='phaseUse') enable=(event.type=='phase'); else if(typeof info.enable=='string') enable=(info.enable==event.name); if(enable){ if(!game.expandSkills(player.getSkills(false).concat(lib.skill.global)).contains(skills2[i])&&(info.noHidden||get.mode()!='guozhan'||player.hasSkillTag('nomingzhi',false,null,true))) enable=false; if(info.filter&&!info.filter(event,player)) enable=false; if(info.viewAs&&typeof info.viewAs!='function'&&event.filterCard&&!event.filterCard(info.viewAs,player,event)) enable=false; if(info.viewAs&&typeof info.viewAs!='function'&&info.viewAsFilter&&info.viewAsFilter(player)==false) enable=false; if(info.usable&&get.skillCount(skills2[i])>=info.usable) enable=false; if(info.chooseButton&&_status.event.noButton) enable=false; if(info.round&&(info.round-(game.roundNumber-player.storage[skills2[i]+'_roundcount'])>0)) enable=false; } if(enable){ if(event.isMine()||!event._aiexclude.contains(skills2[i])){ skills.add(skills2[i]); } event._skillChoice.add(skills2[i]); } } } var globalskills=[]; var globallist=lib.skill.global.slice(0); game.expandSkills(globallist); for(var i=0;i<skills.length;i++){ if(globallist.contains(skills[i])){ globalskills.push(skills.splice(i--,1)[0]); } } var equipskills=[]; var ownedskills=player.getSkills('invisible',false); game.expandSkills(ownedskills); for(var i=0;i<skills.length;i++){ if(!ownedskills.contains(skills[i])){ equipskills.push(skills.splice(i--,1)[0]); } } if(equipskills.length){ ui.create.skills3(equipskills); } else if(ui.skills3){ ui.skills3.close(); } if(skills.length){ ui.create.skills(skills); } else if(ui.skills){ ui.skills.close(); } if(globalskills.length){ ui.create.skills2(globalskills); } else if(ui.skills2){ ui.skills2.close(); } } else{ if(ui.skills){ ui.skills.close() } if(ui.skills2){ ui.skills2.close() } if(ui.skills3){ ui.skills3.close() } } _status.multitarget=false; var skillinfo=get.info(_status.event.skill); if(_status.event.name=='chooseToUse'){ if(skillinfo&&skillinfo.multitarget&&!skillinfo.multiline){ _status.multitarget=true; } if((skillinfo&&skillinfo.viewAs&&typeof skillinfo.viewAs!='function')||!_status.event.skill){ var cardinfo=get.info(get.card()); if(cardinfo&&(cardinfo.multitarget||cardinfo.complexSelect)&&!cardinfo.multiline){ _status.multitarget=true; } } } else if(_status.event.multitarget){ _status.multitarget=true; } if(event.isMine()){ if(game.chess&&game.me&&get.config('show_distance')){ for(var i=0;i<players.length;i++){ if(players[i]==game.me){ players[i].node.action.hide(); } else{ players[i].node.action.show(); var dist=get.distance(game.me,players[i],'pure'); var dist2=get.distance(game.me,players[i]); players[i].node.action.innerHTML='距离:'+dist2+'/'+dist; if(dist>7){ players[i].node.action.classList.add('thunder'); } else{ players[i].node.action.classList.remove('thunder'); } } } } if(ok&&(!event.filterOk||event.filterOk())&&auto&&(auto_confirm||(skillinfo&&skillinfo.direct))&&(!_status.mousedragging||!_status.mouseleft)&& !_status.mousedown&&!_status.touchnocheck){ if(ui.confirm){ if(!skillinfo||!skillinfo.preservecancel){ ui.confirm.close(); } } if(skillinfo&&skillinfo.preservecancel&&!ui.confirm){ ui.create.confirm('c'); } if(event.skillDialog==true) event.skillDialog=false; ui.click.ok(); _status.mousedragging=null; } else{ ui.arena.classList.add('selecting'); if(event.filterTarget&&(!event.filterCard||!event.position||(typeof event.position=='string'&&event.position.indexOf('e')==-1))){ ui.arena.classList.add('tempnoe'); } game.countChoose(); if(!_status.noconfirm&&!_status.event.noconfirm){ if(!_status.mousedown||_status.mouseleft){ var str=''; if(ok&&(!event.filterOk||event.filterOk())) str+='o'; if(!event.forced&&!event.fakeforce&&get.noSelected()) str+='c'; ui.create.confirm(str); } } } if(ui.confirm&&ui.confirm.lastChild.link=='cancel'){ if(_status.event.type=='phase'&&!_status.event.skill){ ui.confirm.lastChild.innerHTML='结束'; } else{ ui.confirm.lastChild.innerHTML='取消'; } } } return ok; }, uncheck:function(){ var i,j; if(game.chess){ var shadows=ui.chessContainer.getElementsByClassName('playergrid temp'); while(shadows.length){ shadows[0].remove(); } } var argc=arguments.length; var args=new Array(argc); for(var i=0;i<argc;i++){ args[i]=arguments[i]; } if((args.length==0||args.contains('card'))&&_status.event.player){ var cards=_status.event.player.getCards('hejsx'); for(j=0;j<cards.length;j++){ cards[j].classList.remove('selected'); cards[j].classList.remove('selectable'); if(cards[j]._tempName){ cards[j]._tempName.delete(); delete cards[j]._tempName; } cards[j].updateTransform(); } ui.selected.cards.length=0; _status.event.player.node.equips.classList.remove('popequip'); } var players=game.players.slice(0); if(_status.event.deadTarget) players.addArray(game.dead); if((args.length==0||args.contains('target'))){ for(j=0;j<players.length;j++){ players[j].classList.remove('selected'); players[j].classList.remove('selectable'); if(players[j].instance){ players[j].instance.classList.remove('selected'); players[j].instance.classList.remove('selectable'); } } ui.selected.targets.length=0; } if((args.length==0||args.contains('button'))&&_status.event.dialog&&_status.event.dialog.buttons){ for(var j=0;j<_status.event.dialog.buttons.length;j++){ _status.event.dialog.buttons[j].classList.remove('selectable'); _status.event.dialog.buttons[j].classList.remove('selected'); } ui.selected.buttons.length=0; } if(args.length==0){ ui.arena.classList.remove('selecting'); ui.arena.classList.remove('tempnoe'); _status.imchoosing=false; _status.lastdragchange.length=0; _status.mousedragging=null; _status.mousedragorigin=null; while(ui.touchlines.length){ ui.touchlines.shift().delete(); } } ui.canvas.width=ui.arena.offsetWidth; ui.canvas.height=ui.arena.offsetHeight; for(var i=0;i<players.length;i++){ players[i].unprompt(); } for(var i=0;i<_status.dragline.length;i++){ if(_status.dragline[i]) _status.dragline[i].remove(); } ui.arena.classList.remove('dragging'); _status.dragline.length=0; }, swapSeat:function(player1,player2,prompt,behind,noanimate){ if(noanimate){ player1.style.transition='all 0s'; player2.style.transition='all 0s'; ui.refresh(player1); ui.refresh(player2); } if(behind){ var totalPopulation=game.players.length+game.dead.length+1; for(var iwhile=0;iwhile<totalPopulation;iwhile++){ if(player1.next!=player2){ game.swapSeat(player1,player1.next,false,false); } else{ break; } } if(prompt!=false){ game.log(player1,'将座位移至',player2,'后'); } } else{ game.addVideo('swapSeat',null,[player1.dataset.position,player2.dataset.position]); var seat1=player1.seatNum; var seat2=player2.seatNum; player2.seatNum=seat1; player1.seatNum=seat2; var temp1,pos,i,num; temp1=player1.dataset.position; player1.dataset.position=player2.dataset.position; player2.dataset.position=temp1; game.arrangePlayers(); if(!game.chess){ if(player1.dataset.position=='0'||player2.dataset.position=='0'){ pos=parseInt(player1.dataset.position); if(pos==0) pos=parseInt(player2.dataset.position); num=game.players.length+game.dead.length; for(i=0;i<game.players.length;i++){ temp1=parseInt(game.players[i].dataset.position)-pos; if(temp1<0) temp1+=num; game.players[i].dataset.position=temp1; } for(i=0;i<game.dead.length;i++){ temp1=parseInt(game.dead[i].dataset.position)-pos; if(temp1<0) temp1+=num; game.dead[i].dataset.position=temp1; } } } if(prompt!=false){ game.log(player1,'和',player2,'交换了座位'); } } if(noanimate){ setTimeout(function(){ player1.style.transition=''; player2.style.transition=''; },200); } }, swapPlayer:function(player,player2){ if(player2){ if(player==game.me) game.swapPlayer(player2); else if(player2==game.me) game.swapPlayer(player); } else{ if(player==game.me) return; var players=game.players.concat(game.dead); for(var i=0;i<players.length;i++){ players[i].style.transition='all 0s'; } game.addVideo('swapPlayer',player,get.cardsInfo(player.getCards('h'))); if(!game.chess){ var pos=parseInt(player.dataset.position); var num=game.players.length+game.dead.length; var players=game.players.concat(game.dead); var temp; for(var i=0;i<players.length;i++){ temp=parseInt(players[i].dataset.position)-pos; if(temp<0) temp+=num; players[i].dataset.position=temp; } } game.me.node.handcards1.remove(); game.me.node.handcards2.remove(); var current=game.me; game.me=player; if(current.isDead()){ current.$die(); } ui.handcards1=player.node.handcards1.animate('start').fix(); ui.handcards2=player.node.handcards2.animate('start').fix(); ui.handcards1Container.appendChild(ui.handcards1); ui.handcards2Container.appendChild(ui.handcards2); ui.updatehl(); } if(game.me.isAlive()){ if(ui.auto) ui.auto.show(); if(ui.wuxie) ui.wuxie.show(); if(ui.revive){ ui.revive.close(); delete ui.revive; } if(ui.swap){ ui.swap.close(); delete ui.swap; } if(ui.restart){ ui.restart.close(); delete ui.restart; } if(ui.continue_game){ ui.continue_game.close(); delete ui.continue_game; } } if(lib.config.mode=='identity'){ game.me.setIdentity(game.me.identity); } setTimeout(function(){ for(var i=0;i<players.length;i++){ players[i].style.transition=''; } },100); }, swapControl:function(player){ if(player==game.me) return; game.me.node.handcards1.remove(); game.me.node.handcards2.remove(); game.me=player; ui.handcards1=player.node.handcards1.animate('start').fix(); ui.handcards2=player.node.handcards2.animate('start').fix(); ui.handcards1Container.insertBefore(ui.handcards1,ui.handcards1Container.firstChild); ui.handcards2Container.insertBefore(ui.handcards2,ui.handcards2Container.firstChild); ui.updatehl(); game.addVideo('swapControl',player,get.cardsInfo(player.getCards('h'))); if(game.me.isAlive()){ if(ui.auto) ui.auto.show(); if(ui.wuxie) ui.wuxie.show(); if(ui.revive){ ui.revive.close(); delete ui.revive; } if(ui.swap){ ui.swap.close(); delete ui.swap; } if(ui.restart){ ui.restart.close(); delete ui.restart; } if(ui.continue_game){ ui.continue_game.close(); delete ui.continue_game; } } }, swapPlayerAuto:function(player){ if(game.modeSwapPlayer){ game.modeSwapPlayer(player); } else{ game.swapPlayer(player); } }, findNext:function(player){ var players=get.players(lib.sort.position); var position=parseInt(player.dataset.position); for(var i=0;i<players.length;i++){ if(parseInt(players[i].dataset.position)>=position){ return players[i]; } } return players[0]; }, loadModeAsync:function(name,callback){ window.game=game; var script=lib.init.js(lib.assetURL+'mode',name,gnc.of(function*(){ yield Promise.allSettled(_status.importing.mode); if(!lib.config.dev) delete window.game; script.remove(); var content=lib.imported.mode[name]; delete lib.imported.mode[name]; if(get.is.empty(lib.imported.mode)){ delete lib.imported.mode; } callback(content); })); }, switchMode:function(name,configx){ if(!lib.layoutfixed.contains(name)){ if(lib.config.layout!=game.layout){ lib.init.layout(lib.config.layout); } else if(lib.config.mode=='brawl'){ if(lib.config.player_border=='normal'&&(game.layout=='long'||game.layout=='long2')){ ui.arena.classList.add('lslim_player'); } } } window.game=game; var script=lib.init.js(lib.assetURL+'mode',name,gnc.of(function*(){ yield Promise.allSettled(_status.importing.mode); if(!lib.config.dev) delete window.game; script.remove(); var mode=lib.imported.mode; _status.sourcemode=lib.config.mode; lib.config.mode=name; var i,j,k; for(i in mode[lib.config.mode].element){ if(!lib.element[i]) lib.element[i]=[]; for(j in mode[lib.config.mode].element[i]){ if(j=='init'){ if(!lib.element[i].inits) lib.element[i].inits=[]; lib.element[i].inits.push(mode[lib.config.mode].element[i][j]); } else{ lib.element[i][j]=mode[lib.config.mode].element[i][j]; } } } for(i in mode[lib.config.mode].ai){ if(typeof mode[lib.config.mode].ai[i]=='object'){ if(ai[i]==undefined) ai[i]={}; for(j in mode[lib.config.mode].ai[i]){ ai[i][j]=mode[lib.config.mode].ai[i][j]; } } else{ ai[i]=mode[lib.config.mode].ai[i]; } } for(i in mode[lib.config.mode].ui){ if(typeof mode[lib.config.mode].ui[i]=='object'){ if(ui[i]==undefined) ui[i]={}; for(j in mode[lib.config.mode].ui[i]){ ui[i][j]=mode[lib.config.mode].ui[i][j]; } } else{ ui[i]=mode[lib.config.mode].ui[i]; } } for(i in mode[lib.config.mode].game){ game[i]=mode[lib.config.mode].game[i]; } for(i in mode[lib.config.mode].get){ get[i]=mode[lib.config.mode].get[i]; } if(game.onwash){ lib.onwash.push(game.onwash); delete game.onwash; } if(game.onover){ lib.onover.push(game.onover); delete game.onover; } lib.config.banned=lib.config[lib.config.mode+'_banned']||[]; lib.config.bannedcards=lib.config[lib.config.mode+'_bannedcards']||[]; for(i in mode[lib.config.mode]){ if(i=='element') continue; if(i=='game') continue; if(i=='ai') continue; if(i=='ui') continue; if(i=='get') continue; if(i=='config') continue; if(i=='start') continue; if(i=='startBefore') continue; if(lib[i]==undefined) lib[i]=(Array.isArray(mode[lib.config.mode][i]))?[]:{}; for(j in mode[lib.config.mode][i]){ lib[i][j]=mode[lib.config.mode][i][j]; } } // var pilecfg=lib.config.customcardpile[get.config('cardpilename')]; // if(pilecfg){ // lib.config.bannedpile=pilecfg[0]||{}; // lib.config.addedpile=pilecfg[1]||{}; // } _status.event={ finished:true, next:[], after:[] }; _status.paused=false; if(_status.connectMode&&lib.mode[name].connect){ game.saveConfig('connect_mode',name); game.clearConnect(); lib.configOL.mode=name; if(configx){ for(var i in configx){ lib.configOL[i]=configx[i]; } } else{ for(var i in lib.mode[name].connect){ if(i=='update') continue; lib.configOL[i.slice(8)]=get.config(i); } lib.configOL.zhinang_tricks=lib.config.connect_zhinang_tricks; lib.configOL.characterPack=lib.connectCharacterPack.slice(0); lib.configOL.cardPack=lib.connectCardPack.slice(0); for(var i=0;i<lib.config.connect_characters.length;i++){ lib.configOL.characterPack.remove(lib.config.connect_characters[i]); } for(var i=0;i<lib.config.connect_cards.length;i++){ lib.configOL.cardPack.remove(lib.config.connect_cards[i]); } lib.configOL.banned=lib.config['connect_'+name+'_banned']; lib.configOL.bannedcards=lib.config['connect_'+name+'_bannedcards']; } lib.configOL.version=lib.versionOL; for(var i in lib.cardPackList){ if(lib.configOL.cardPack.contains(i)){ lib.card.list=lib.card.list.concat(lib.cardPackList[i]); } } for(i=0;i<lib.card.list.length;i++){ if(lib.card.list[i][2]=='huosha'){ lib.card.list[i]=lib.card.list[i].slice(0); lib.card.list[i][2]='sha'; lib.card.list[i][3]='fire'; } else if(lib.card.list[i][2]=='leisha'){ lib.card.list[i]=lib.card.list[i].slice(0); lib.card.list[i][2]='sha'; lib.card.list[i][3]='thunder'; } if(!lib.card[lib.card.list[i][2]]){ lib.card.list.splice(i,1);i--; } else if(lib.card[lib.card.list[i][2]].mode&& lib.card[lib.card.list[i][2]].mode.contains(lib.config.mode)==false){ lib.card.list.splice(i,1);i--; } } } if(!lib.config.show_playerids||!game.showIdentity){ ui.playerids.style.display='none'; } else{ ui.playerids.style.display=''; } if(mode[lib.config.mode].startBefore) mode[lib.config.mode].startBefore(); game.createEvent('game',false).setContent(mode[lib.config.mode].start); if(lib.mode[lib.config.mode]&&lib.mode[lib.config.mode].fromextension){ var startstr=mode[lib.config.mode].start.toString(); if(startstr.indexOf('onfree')==-1){ setTimeout(lib.init.onfree,500); } } delete lib.imported.mode[name]; if(!lib.db){ try{ lib.storage=JSON.parse(localStorage.getItem(lib.configprefix+lib.config.mode)); if(typeof lib.storage!='object') throw('err'); if(lib.storage==null) throw('err'); } catch(err){ lib.storage={}; localStorage.setItem(lib.configprefix+lib.config.mode,"{}"); } game.loop(); } else{ game.getDB('data',lib.config.mode,function(obj){ lib.storage=obj||{}; game.loop(); }); } })); }, loadMode:function(mode){ var next=game.createEvent('loadMode',false); next.mode=mode; next.setContent('loadMode'); }, loadPackage:function(){ var next=game.createEvent('loadPackage'); next.packages=[]; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='string'){ next.packages.push(arguments[i]); } } next.setContent('loadPackage'); }, phaseLoop:function(player){ var next=game.createEvent('phaseLoop'); next.player=player; next._isStandardLoop=true; next.setContent('phaseLoop'); }, gameDraw:function(player,num){ var next=game.createEvent('gameDraw'); next.player=player||game.me; if(num==undefined) next.num=4; else next.num=num; next.setContent('gameDraw'); return next; }, chooseCharacterDouble:function(){ var next=game.createEvent('chooseCharacter'); var config,width,num,ratio,func,update,list,first; for(var i=0;i<arguments.length;i++){ if(typeof arguments[i]=='number'){ if(!width){ width=arguments[i]; } else if(!num){ num=arguments[i]; } else{ ratio=arguments[i]; } } else if(typeof arguments[i]=='function'){ if(!func){ func=arguments[i]; } else{ update=arguments[i]; } } else if(Array.isArray(arguments[i])){ list=arguments[i]; } else if(get.objtype(arguments[i])=='object'){ config=arguments[i]; } } if(!config){ list=config; config={}; } config.width=config.width||width||8; config.height=4; config.size=config.width*config.height; config.num=config.num||num||3; config.ratio=config.ratio||ratio||1.2; config.update=config.update||update; if(!config.hasOwnProperty('first')){ if(typeof first=='boolean'){ config.first=first; } else{ config.first='rand'; } } if(!list){ list=[]; for(var i in lib.character){ if(typeof func=='function'){ if(!func(i)) continue; } else{ if(lib.filter.characterDisabled(i)) continue; } list.push(i); } } next.config=config; next.list=list; next.setContent(function(){ 'step 0' event.nodes=[]; event.avatars=[]; event.friend=[]; event.enemy=[]; event.blank=[]; for(var i=0;i<event.config.size;i++){ event.nodes.push(ui.create.div('.shadowed.reduce_radius.choosedouble')); } event.moveAvatar=function(node,i){ if(!node.classList.contains('moved')){ event.blank.push(node.index); } event.nodes[node.index].style.display=''; event.nodes[node.index].show(); clearTimeout(event.nodes[node.index].choosetimeout); event.moveNode(node,i); var nodex=event.nodes[node.index]; nodex.choosetimeout=setTimeout(function(){ nodex.hide(); nodex.choosetimeout=setTimeout(function(){ nodex.show(); nodex.style.display='none'; },300); },400); }; event.aiMove=function(friend){ var list=[]; for(var i=0;i<event.avatars.length;i++){ if(!event.avatars[i].classList.contains('moved')){ list.push(event.avatars[i]); } } for(var i=0;i<list.length;i++){ if(Math.random()<0.7||i==list.length-1){ if(friend){ event.moveAvatar(list[i],event.friend.length+event.config.width*(event.config.height-1)); event.friend.push(list[i]); } else{ event.moveAvatar(list[i],event.enemy.length); event.enemy.push(list[i]); } list[i].classList.add('moved'); break; } } }; event.promptbar=ui.create.div('.hidden',ui.window); event.promptbar.style.width='100%'; event.promptbar.style.left=0; if(get.is.phoneLayout()){ event.promptbar.style.top='20px'; } else{ event.promptbar.style.top='58px'; } event.promptbar.style.pointerEvents='none'; event.promptbar.style.textAlign='center'; event.promptbar.style.zIndex='2'; ui.create.div('.shadowed.reduce_radius',event.promptbar); event.promptbar.firstChild.style.fontSize='18px'; event.promptbar.firstChild.style.padding='6px 10px'; event.promptbar.firstChild.style.position='relative'; event.prompt=function(str){ event.promptbar.firstChild.innerHTML=str; event.promptbar.show(); }; event.moveNode=function(node,i){ var width=event.width,height=event.height,margin=event.margin; var left=-(width+10)*event.config.width/2+5+(i%event.config.width)*(width+10); var top=-(height+10)*event.config.height/2+5+Math.floor(i/event.config.width)*(height+10)+margin/2; node.style.transform='translate('+left+'px,'+top+'px)'; node.index=i; }; event.resize=function(){ var margin=0; if(!get.is.phoneLayout()){ margin=38; } var height=(ui.window.offsetHeight-10*(event.config.height+1)-margin)/event.config.height; var width=(ui.window.offsetWidth-10*(event.config.width+1))/event.config.width; if(width*event.config.ratio<height){ height=width*event.config.ratio; } else{ width=height/event.config.ratio; } event.width=width; event.height=height; event.margin=margin; for(var i=0;i<event.config.size;i++){ event.moveNode(event.nodes[i],i); event.nodes[i].style.width=width+'px'; event.nodes[i].style.height=height+'px'; if(event.avatars[i]){ event.moveNode(event.avatars[i],event.avatars[i].index); event.avatars[i].style.width=width+'px'; event.avatars[i].style.height=height+'px'; event.avatars[i].nodename.style.fontSize=Math.max(14,Math.round(width/5.6))+'px'; } } if(event.deciding){ var str='px,'+(event.margin/2-event.height*0.5)+'px)'; for(var i=0;i<event.friendlist.length;i++){ event.friendlist[i].style.transform='scale(1.2) translate('+(-(event.width+14)*event.friendlist.length/2+7+i*(event.width+14))+str; } } }; lib.onresize.push(event.resize); event.clickAvatar=function(){ if(event.deciding){ if(this.index<event.config.width) return; if(event.friendlist.contains(this)){ event.friendlist.remove(this); event.moveNode(this,this.index); this.nodename.innerHTML=get.slimName(this.link); } else{ event.friendlist.push(this); } if(event.friendlist.length==event.config.num){ event.deciding=false; event.prompt('比赛即将开始'); setTimeout(game.resume,1000); } if(event.config.update){ for(var i=0;i<event.friendlist.length;i++){ event.friendlist[i].nodename.innerHTML=event.config.update(i,event.friendlist.length)||event.friendlist[i].nodename.innerHTML; } } var str='px,'+(event.margin/2-event.height*0.5)+'px)'; for(var i=0;i<event.friendlist.length;i++){ event.friendlist[i].style.transform='scale(1.2) translate('+(-(event.width+14)*event.friendlist.length/2+7+i*(event.width+14))+str; } } else{ if(!event.imchoosing) return; if(event.replacing){ this.link=event.replacing; this.setBackground(event.replacing,'character'); this.nodename.innerHTML=get.slimName(event.replacing); this.nodename.dataset.nature=get.groupnature(lib.character[event.replacing][1]); delete event.replacing; if(this.classList.contains('moved')){ event.custom.add.window(); } } if(this.classList.contains('moved')) return; event.moveAvatar(this,event.friend.length+event.config.width*(event.config.height-1)); event.friend.push(this.link); this.classList.add('moved'); game.resume(); } }; event.skipnode=ui.create.system('跳过',function(){ this.remove(); event._skiprest=true; if(event.imchoosing){ game.resume(); } }); if(get.config('change_choice')){ event.replacenode=ui.create.system('换将',function(){ event.promptbar.hide(); while(event.avatars.length){ event.avatars.shift().remove(); } for(var i=0;i<event.config.size;i++){ event.nodes[i].show(); event.nodes[i].style.display=''; clearTimeout(event.nodes[i].choosetimeout); } delete event.list2; event.friend.length=0; event.enemy.length=0; event.blank.length=0; event.redoing=true; if(event.imchoosing){ game.resume(); } },true); } if(get.config('change_choice')){ event.reselectnode=ui.create.system('重选',function(){ event.promptbar.hide(); event.list2=event.list2.concat(event.friend).concat(event.enemy); event.friend.length=0; event.enemy.length=0; for(var i=0;i<event.avatars.length;i++){ if(event.avatars[i].classList.contains('moved')){ event.moveAvatar(event.avatars[i],event.blank.randomRemove()); event.avatars[i].classList.remove('moved'); } } event.redoing=true; if(event.imchoosing){ game.resume(); } },true); } if(get.config('free_choose')){ var createCharacterDialog=function(){ event.freechoosedialog=ui.create.characterDialog(); event.freechoosedialog.style.height='80%'; event.freechoosedialog.style.top='10%'; event.freechoosedialog.style.transform='scale(0.8)'; event.freechoosedialog.style.transition='all 0.3s'; event.freechoosedialog.listen(function(e){ if(!event.replacing){ event.dialoglayer.clicked=true; } }); event.freechoosedialog.classList.add('pointerdialog'); event.dialoglayer=ui.create.div('.popup-container.hidden',function(e){ if(this.classList.contains('removing')) return; if(this.clicked){ this.clicked=false; return; } ui.window.classList.remove('modepaused'); this.delete(); e.stopPropagation(); event.freechoosedialog.style.transform='scale(0.8)'; if(event.replacing){ event.prompt('用'+get.translation(event.replacing)+'替换一名武将'); } else{ if(event.side==0){ event.prompt('请选择两名武将'); } else{ event.prompt('请选择一名武将'); } } }); event.dialoglayer.classList.add('modenopause'); event.dialoglayer.appendChild(event.freechoosedialog); event.freechoosenode.classList.remove('hidden'); } event.custom.replace.button=function(button){ event.replacing=button.link; }; event.custom.add.window=function(){ if(event.replacing){ delete event.replacing; if(event.side==0){ event.prompt('请选择两名武将'); } else{ event.prompt('请选择一名武将'); } } }; event.freechoosenode=ui.create.system('自由选将',function(){ if(this.classList.contains('hidden')) return; if(!event.imchoosing){ event.prompt('请等待敌方选将'); return; } delete event.replacing; ui.window.classList.add('modepaused'); ui.window.appendChild(event.dialoglayer); ui.refresh(event.dialoglayer); event.dialoglayer.show(); event.freechoosedialog.style.transform='scale(1)'; event.promptbar.hide(); },true); if(lib.onfree){ event.freechoosenode.classList.add('hidden'); lib.onfree.push(createCharacterDialog); } else{ createCharacterDialog(); } } event.checkredo=function(){ if(event.redoing){ event.goto(1); delete event.redoing; return true; } }; // if(ui.cardPileButton) ui.cardPileButton.style.display='none'; ui.auto.hide(); ui.wuxie.hide(); event.resize(); for(var i=0;i<event.config.size;i++){ ui.window.appendChild(event.nodes[i]); } 'step 1' var rand=event.config.first; if(rand=='rand'){ rand=(Math.random()<0.5); } if(rand){ _status.color=true; event.side=1; } else{ _status.color=false; event.side=3; } if(!event.list2){ event.list2=event.list.randomGets(event.config.width*2); for(var i=0;i<event.config.width*2;i++){ event.avatars.push(ui.create.div('.shadowed.shadowed2.reduce_radius.character.choosedouble',event.clickAvatar)); var name=event.list2[i]; event.avatars[i].setBackground(name,'character'); event.avatars[i].link=name; event.avatars[i].nodename=ui.create.div('.name',event.avatars[i],get.slimName(name)); event.avatars[i].nodename.style.fontFamily=lib.config.name_font; event.avatars[i].index=i+event.config.width; event.avatars[i].animate('start'); event.nodes[event.avatars[i].index].style.display='none'; event.avatars[i].nodename.dataset.nature=get.groupnature(lib.character[name][1]); lib.setIntro(event.avatars[i]); } event.resize(); for(var i=0;i<event.avatars.length;i++){ ui.window.appendChild(event.avatars[i]); } event.avatars.sort(function(a,b){ return get.rank(b.link,true)-get.rank(a.link,true); }) } game.delay(); lib.init.onfree(); 'step 2' if(event.checkredo()) return; if(event._skiprest) return; if(event.side<2){ event.imchoosing=true; if(event.side==0){ event.prompt('请选择两名武将'); } else{ event.prompt('请选择一名武将'); event.fast=get.time(); } game.pause(); } else{ event.aiMove(); game.delay(); } 'step 3' if(typeof event.fast=='number'&&get.time()-event.fast<=1000){ event.fast=true; } else{ event.fast=false; } delete event.imchoosing; if(event.checkredo()) return; if(event._skiprest){ while(event.enemy.length<event.config.width){ event.aiMove(); } while(event.friend.length<event.config.width){ event.aiMove(true); } } else if(event.friend.length+event.enemy.length<event.config.width*2-1){ if(event.side==1){ game.delay(event.fast?1:2); event.promptbar.hide(); } event.side++; if(event.side>3){ event.side=0; } event.goto(2); } else{ event.promptbar.hide(); event.side++; if(event.side>3){ event.side=0; } if(event.side>=2){ game.delay() } } 'step 4' if(event.checkredo()) return; if(event.skipnode) event.skipnode.delete(); if(event.replacenode) event.replacenode.delete(); if(event.reselectnode) event.reselectnode.delete(); if(event.freechoosenode) event.freechoosenode.delete(); for(var i=0;i<event.avatars.length;i++){ if(!event.avatars[i].classList.contains('moved')){ if(event.side<2){ event.moveAvatar(event.avatars[i],event.friend.length+event.config.width*(event.config.height-1)); event.friend.push(event.avatars[i]); } else{ event.moveAvatar(event.avatars[i],event.enemy.length); event.enemy.push(event.avatars[i]); } event.avatars[i].classList.add('moved'); } } game.delay(); 'step 5' event.prompt('选择'+get.cnNumber(event.config.num)+'名出场武将'); event.enemylist=[]; for(var i=0;i<event.avatars.length;i++){ if(event.avatars[i].index>event.config.width){ event.avatars[i].classList.add('selecting'); } } var rand=[]; for(var i=0;i<event.config.width;i++){ for(var j=0;j<event.config.width-i;j++){ rand.push(i); } } for(var i=0;i<event.config.num;i++){ var rand2=rand.randomGet(); for(var j=0;j<rand.length;j++){ if(rand[j]==rand2){ rand.splice(j--,1); } } event.enemylist.push(event.enemy[rand2]); } event.enemylist.randomSort(); event.friendlist=[]; event.deciding=true; for(var i=0;i<event.config.size;i++){ event.nodes[i].hide(); } game.pause(); 'step 6' event.promptbar.delete(); if(ui.cardPileButton) ui.cardPileButton.style.display=''; lib.onresize.remove(event.resize); ui.wuxie.show(); ui.auto.show(); for(var i=0;i<event.avatars.length;i++){ event.avatars[i].delete(); } for(var i=0;i<event.nodes.length;i++){ event.nodes[i].delete(); } event.result={friend:[],enemy:[]}; for(var i=0;i<event.config.num;i++){ event.result.friend[i]=event.friendlist[i].link; event.result.enemy[i]=event.enemylist[i].link; } }); }, updateRoundNumber:()=>game.broadcastAll((num1,num2,top)=>{ if(ui.cardPileNumber) ui.cardPileNumber.innerHTML=`${num1}轮 剩余牌: ${num2}`; _status.pileTop=top; },game.roundNumber,ui.cardPile.childNodes.length,ui.cardPile.firstChild), asyncDraw:(players,num,drawDeck,bottom)=>players.forEach((value,index)=>{ let num2=1; if(typeof num=='number') num2=num; else if(Array.isArray(num)) num2=num[index]; else if(typeof num=='function') num2=num(value); if(drawDeck&&drawDeck.drawDeck) value.draw(num2,false,drawDeck); else if(bottom) value.draw(num2,'nodelay','bottom'); else value.draw(num2,'nodelay'); }), asyncDrawAuto:function(players,num,drawDeck){ if(players.length>1){ game.asyncDraw.apply(this,arguments); return; } let num2=1; if(typeof num=='number') num2=num; else if(Array.isArray(num)) num2=num[0]; else if(typeof num=='function') num2=num(players[0]); if(drawDeck&&drawDeck.drawDeck) players[0].draw(num2,drawDeck); else players[0].draw(num2); }, finishSkill:(i,sub)=>{ const mode=get.mode(),info=lib.skill[i],iInfo=`${i}_info`; if(info.alter){ lib.translate[`${iInfo}_origin`]=lib.translate[iInfo]; if(!lib.config.vintageSkills.contains(i)) lib.translate[iInfo]=lib.translate[`${iInfo}_alter`]; } else if(lib.translate[`${iInfo}_${mode}`]) lib.translate[iInfo]=lib.translate[`${iInfo}_${mode}`]; else if(lib.translate[`${iInfo}_zhu`]&&(mode=='identity'||mode=='guozhan'&&_status.mode=='four')) lib.translate[iInfo]=lib.translate[`${iInfo}_zhu`]; else if(lib.translate[`${iInfo}_combat`]&&get.is.versus()) lib.translate[iInfo]=lib.translate[`${iInfo}_combat`]; if(info.forbid&&info.forbid.contains(mode)){ lib.skill[i]={}; if(lib.translate[iInfo]) lib.translate[iInfo]='此模式下不可用'; return; } if(info.mode&&info.mode.contains(mode)==false){ lib.skill[i]={}; if(lib.translate[iInfo]) lib.translate[iInfo]='此模式下不可用'; return; } if(info.available&&info.available(mode)==false){ lib.skill[i]={}; if(lib.translate[iInfo]) lib.translate[iInfo]='此模式下不可用'; return; } if(info.viewAs&&typeof info.viewAs!='function'){ if(typeof info.viewAs=='string') info.viewAs={ name:info.viewAs }; if(!lib.card[info.viewAs.name]){ lib.skill[i]={}; lib.translate[iInfo]='技能不可用'; return; } if(info.ai==undefined) info.ai={}; const skill=info.ai,card=lib.card[info.viewAs.name].ai; if(card) Object.keys(card).forEach(value=>{ if(skill[value]==undefined) skill[value]=card[value]; else if(typeof skill[value]=='object') Object.keys(card[value]).forEach(element=>{ if(skill[value][element]==undefined) skill[value][element]=card[value][element]; }); }); } if(info.inherit){ const skill=lib.skill[info.inherit]; if(skill) Object.keys(skill).forEach(value=>{ if(info[value]!=undefined) return; if(value=='audio'&&(typeof info[value]=='number'||typeof info[value]=='boolean')) info[value]=info.inherit; else info[value]=skill[value]; }); if(lib.translate[i]==undefined) lib.translate[i]=lib.translate[info.inherit]; if(lib.translate[iInfo]==undefined) lib.translate[iInfo]=lib.translate[`${info.inherit}_info`]; } if(info.limited){ if(info.mark===undefined) info.mark=true; if(!info.intro) info.intro={}; if(info.intro.content===undefined) info.intro.content='limited'; if(info.skillAnimation===undefined) info.skillAnimation=true; if(info.init===undefined) info.init=(player,skill)=>player.storage[skill]=false; } if(info.subSkill&&!sub) Object.keys(info.subSkill).forEach(value=>{ const iValue=`${i}_${value}`; lib.skill[iValue]=info.subSkill[value]; lib.skill[iValue].sub=true; if(info.subSkill[value].name) lib.translate[iValue]=info.subSkill[value].name; else lib.translate[iValue]=lib.translate[iValue]||lib.translate[i]; if(info.subSkill[value].description) lib.translate[`${iValue}_info`]=info.subSkill[value].description; if(info.subSkill[value].marktext) lib.translate[`${iValue}_bg`]=info.subSkill[value].marktext; game.finishSkill(iValue,true); }); if(info.round){ const k=`${i}_roundcount`; if(typeof info.group=='string') info.group=[info.group,k]; else if(Array.isArray(info.group)) info.group.add(k); else info.group=[k]; lib.skill[k]=((round,name)=>({ init:player=>{ if(typeof player.storage[name]!=='number') player.storage[name]=1-round; }, intro:{ content:(storage,player)=>{ let str=''; const info=get.info(name.slice(0,name.indexOf('_roundcount'))); if(info&&info.addintro) str+=info.addintro(storage,player); const num=round-(game.roundNumber-storage); if(num>0) str+=`${get.cnNumber(num)}轮后${info.roundtext||'技能重置'}`; else str+='技能可发动'; return str; }, markcount:(storage,player)=>Math.max(round-(game.roundNumber-storage),0) }, trigger:{global:'roundStart'}, forced:true, popup:false, silent:true, content:()=>{ if(lib.skill[event.name.slice(0,event.name.indexOf('_roundcount'))].round-(game.roundNumber-player.storage[event.name])>0) player.updateMarks(); else player.unmarkSkill(event.name); } }))(info.round,k); lib.translate[k]=lib.translate[i]||''; lib.translate[`${k}_bg`]=lib.translate[`${i}_bg`]||lib.translate[k][0]; } if(info.marktext) lib.translate[`${i}_bg`]=info.marktext; if(info.silent){ if(!info.hasOwnProperty('forced')) info.forced=true; if(!info.hasOwnProperty('popup')) info.popup=false; } if(!info.hasOwnProperty('_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; } if(i[0]=='_') game.addGlobalSkill(i); }, finishCards:()=>{ _status.cardsFinished=true; const mode=get.mode(),filterTarget=(card,player,target)=>player==target&&target.canEquip(card,true),aiBasicOrder=(card,player)=>{ const equipValue=get.equipValue(card,player)/20; return player&&player.hasSkillTag('reverseEquip')?8.5-equipValue:8+equipValue; },aiBasicValue=(card,player,index,method)=>{ if(!player.getCards('e').contains(card)&&!player.canEquip(card,true)) return 0.01; const info=get.info(card),current=player.getEquip(info.subtype),value=current&&card!=current&&get.value(current,player); let equipValue=info.ai.equipValue||info.ai.basic.equipValue; if(typeof equipValue=='function'){ if(method=='raw')return equipValue(card,player); if(method=='raw2')return equipValue(card,player)-value; return Math.max(0.1,equipValue(card,player)-value); } if(typeof equipValue!='number') equipValue=0; if(method=='raw') return equipValue; if(method=='raw2') return equipValue-value; return Math.max(0.1,equipValue-value); },aiResultTarget=(player,target,card)=>get.equipResult(player,target,card.name); Object.keys(lib.card).forEach(libCardKey=>{ const info = `${libCardKey}_info`; if(lib.translate[`${info}_${mode}`]) lib.translate[info]=lib.translate[`${info}_${mode}`]; else if(lib.translate[`${info}_zhu`]&&(mode=='identity'||mode=='guozhan'&&_status.mode=='four')) lib.translate[info]=lib.translate[`${info}_zhu`]; else if(lib.translate[`${info}_combat`]&&get.is.versus()) lib.translate[info]=lib.translate[`${info}_combat`]; const card=lib.card[libCardKey]; if(card.filterTarget&&card.selectTarget==undefined) card.selectTarget=1; if(card.autoViewAs){ if(!card.ai) card.ai={}; if(!card.ai.order){ card.ai.order=lib.card[card.autoViewAs].ai.order; if(!card.ai.order&&lib.card[card.autoViewAs].ai.basic) card.ai.order=lib.card[card.autoViewAs].ai.basic.order; } } if(card.type=='equip'){ if(card.enable==undefined) card.enable=true; if(card.selectTarget==undefined) card.selectTarget=-1; if(card.filterTarget==undefined) card.filterTarget=filterTarget; if(card.modTarget==undefined) card.modTarget=true; if(card.allowMultiple==undefined) card.allowMultiple=false; if(card.content==undefined) card.content=lib.element.content.equipCard; if(card.toself==undefined) card.toself=true; if(card.ai==undefined) card.ai={ basic:{} }; if(card.ai.basic==undefined) card.ai.basic={}; if(card.ai.result==undefined) card.ai.result={ target:1.5 }; if(card.ai.basic.order==undefined) card.ai.basic.order=aiBasicOrder; if(card.ai.basic.useful==undefined) card.ai.basic.useful=2; if(card.subtype=='equip3'){ if(card.ai.basic.equipValue==undefined) card.ai.basic.equipValue=7; } else if(card.subtype=='equip4'){ if(card.ai.basic.equipValue==undefined) card.ai.basic.equipValue=4; } else if(card.ai.basic.equipValue==undefined) card.ai.basic.equipValue=1; if(card.ai.basic.value==undefined) card.ai.basic.value=aiBasicValue; if(!card.ai.result.keepAI) card.ai.result.target=aiResultTarget; } else if(card.type=='delay'){ if(card.enable==undefined) card.enable=true; if(card.filterTarget==undefined) card.filterTarget=lib.filter.judge; if(card.content==undefined) card.content=lib.element.content.addJudgeCard; if(card.allowMultiple==undefined) card.allowMultiple=false; } }); Object.keys(lib.skill).forEach(value=>game.finishSkill(value)); }, checkMod:function(){ const argumentArray=Array.from(arguments),name=argumentArray[argumentArray.length-2]; let skills=argumentArray[argumentArray.length-1]; if(skills.getSkills) skills=skills.getModableSkills(_status.event.useCache === true); const arg=argumentArray.slice(0,-2); skills.forEach(value=>{ var mod = get.info(value).mod[name]; if(!mod)return; const result=mod.apply(this,arg); if(typeof arg[arg.length-1]!='object'&&result!=undefined) arg[arg.length-1]=result; }); return arg[arg.length-1]; }, prepareArena:num=>{ _status.prepareArena=true; game.showHistory(false); ui.create.players(num); ui.create.me(); ui.create.cardsAsync(); game.finishCards(); }, clearArena:()=>{ ui.control.innerHTML=''; ui.arenalog.innerHTML=''; Array.from(ui.arena.childNodes).forEach(value=>{ if(value==ui.canvas) return; if(value==ui.control) return; if(value==ui.arenalog) return; if(value==ui.roundmenu) return; if(value==ui.timer) return; if(value==ui.autonode) return; value.remove(); }); ui.sidebar.innerHTML=''; ui.cardPile.innerHTML=''; ui.discardPile.innerHTML=''; ui.special.innerHTML=''; ui.ordering.innerHTML=''; ui.playerids.remove(); game.players.length=0; game.dead.length=0; game.me=null; }, clearConnect:()=>{ if(ui.ipnode){ ui.ipnode.remove(); delete ui.ipnode; } if(ui.iptext){ ui.iptext.remove(); delete ui.iptext; } if(ui.ipbutton){ ui.ipbutton.remove(); delete ui.ipbutton; } if(ui.recentIP){ ui.recentIP.remove(); delete ui.recentIP; } if(ui.hall_button){ ui.hall_button.remove(); delete ui.hall_button; } if(ui.startServer){ ui.startServer.remove(); delete ui.startServer; } if(ui.rooms){ ui.rooms.forEach(value=>value.remove()); delete ui.rooms; } if(ui.roombase){ ui.roombase.remove(); delete ui.roombase; } if(!ui.connectEvents) return; ui.connectEvents.remove(); ui.connectEventsCount.remove(); ui.connectClients.remove(); ui.connectClientsCount.remove(); ui.createRoomButton.remove(); delete ui.connectEvents; delete ui.connectEventsCount; delete ui.connectClients; delete ui.connectClientsCount; delete ui.createRoomButton; }, log:function(){ let str='',str2='',logvid=null; const color=new Map([ ['b','blue'], ['y','yellow'], ['g','green'] ]); Array.from(arguments).forEach(value=>{ const itemtype=get.itemtype(value); if(itemtype=='player'||itemtype=='players'){ str+=`<span class="bluetext">${get.translation(value)}</span>`; str2+=get.translation(value); } else if(itemtype=='cards'||itemtype=='card'||(typeof value=='object'&&value&&value.name)){ str+=`<span class="yellowtext">${get.translation(value)}</span>`; str2+=get.translation(value); } else if(typeof value=='object'){ if(value.parentNode==ui.historybar) logvid=value.logvid; else{ str+=get.translation(value); str2+=get.translation(value); } } else if(typeof value=='string'){ if(value[0]=='【'&&value[value.length-1]=='】'){ str+=`<span class="greentext">${get.translation(value)}</span>`; str2+=get.translation(value); } else if(value[0]=='#'){ str+=`<span class="${color.get(value[1])||''}text">${get.translation(value.slice(2))}</span>`; str2+=get.translation(value.slice(2)); } else{ str+=get.translation(value); str2+=get.translation(value); } } else{ str+=value; str2+=value; } }); const node=ui.create.div(); node.innerHTML=lib.config.log_highlight?str:str2; ui.sidebar.insertBefore(node,ui.sidebar.firstChild); game.addVideo('log',null,lib.config.log_highlight?str:str2); game.broadcast((str,str2)=>game.log(lib.config.log_highlight?str:str2),str,str2); if(!_status.video&&!game.online){ if(logvid) game.logv(logvid,`<div class="text center">${lib.config.log_highlight?str:str2}</div>`); else logvid=_status.event.getLogv(); } if(lib.config.show_log=='off'||game.chess) return; const nodeentry=node.cloneNode(true); ui.arenalog.insertBefore(nodeentry,ui.arenalog.firstChild); if(!lib.config.clear_log) while(ui.arenalog.childNodes.length&&ui.arenalog.scrollHeight>ui.arenalog.offsetHeight){ ui.arenalog.lastChild.remove(); } if(!lib.config.low_performance){ nodeentry.style.transition='all 0s'; nodeentry.style.marginBottom=`-${nodeentry.offsetHeight}px`; ui.refresh(nodeentry); nodeentry.style.transition=''; nodeentry.style.marginBottom=''; } if(!lib.config.clear_log) return; nodeentry.timeout=setTimeout(()=>nodeentry.delete(),1000); Array.from(ui.arenalog.childNodes).forEach(value=>{ if(!value.timeout) value.remove(); }); }, logv:(player,card,targets,event,forced,logvid)=>{ if(!player){ player=_status.event.getParent().logvid; if(!player) return; } const node=ui.create.div('.hidden'); node.node={}; logvid=logvid||get.id(); game.broadcast(game.logv,player,card,targets,event,forced,logvid); if(typeof player=='string'){ const childNode=Array.from(ui.historybar.childNodes).find(value=>value.logvid==player); if(childNode) childNode.added.push(card); return; } if(typeof card=='string'){ if(card!='die'){ if(lib.skill[card]&&lib.skill[card].logv===false&&!forced) return; if(!lib.translate[card]) return; } let avatar; if(!player.isUnseen(0)) avatar=player.node.avatar.cloneNode(); else if(!player.isUnseen(1)) avatar=player.node.avatar2.cloneNode(); else return; node.node.avatar=avatar; avatar.style.transform=''; avatar.className='avatar'; if(card=='die'){ node.dead=true; node.player=player; const avatar2=avatar.cloneNode(); avatar2.className='avatarbg grayscale1'; avatar.appendChild(avatar2); avatar.style.opacity=0.6; } else{ node.node.text=ui.create.div('',get.translation(card,'skill'),avatar); node.node.text.dataset.nature='water'; node.skill=card; } node.appendChild(avatar); if(card=='die'&&targets&&targets!=player){ node.source=targets; player=targets; if(!player.isUnseen(0)) avatar=player.node.avatar.cloneNode(); else if(!player.isUnseen(1)) avatar=player.node.avatar2.cloneNode(); else if(get.mode()=='guozhan'&&player.node&&player.node.name_seat){ avatar=ui.create.div('.avatar.cardbg'); avatar.innerHTML=player.node.name_seat.innerHTML[0]; } else return; avatar.style.transform=''; node.node.avatar2=avatar; avatar.classList.add('avatar2'); node.appendChild(avatar); } } else if(Array.isArray(card)){ node.cards=card[1].slice(0) card=card[0]; const info=[card.suit||'',card.number||'',card.name||'',card.nature||'']; if(!Array.isArray(node.cards)||!node.cards.length) node.cards=[ui.create.card(node,'noclick',true).init(info)]; if(card.name=='wuxie'){ if(ui.historybar.firstChild&&ui.historybar.firstChild.type=='wuxie'){ ui.historybar.firstChild.players.push(player); ui.historybar.firstChild.cards.addArray(node.cards); return; } node.type='wuxie'; node.players=[player]; } if(card.copy) card.copy(node,false); else{ card=ui.create.card(node,'noclick',true); card.init(info); } let avatar; if(!player.isUnseen(0)) avatar=player.node.avatar.cloneNode(); else if(!player.isUnseen(1)) avatar=player.node.avatar2.cloneNode(); else if(get.mode()=='guozhan'&&player.node&&player.node.name_seat){ avatar=ui.create.div('.avatar.cardbg'); avatar.innerHTML=player.node.name_seat.innerHTML[0]; } else return; node.node.avatar=avatar; avatar.style.transform=''; avatar.classList.add('avatar2'); node.appendChild(avatar); if(targets&&targets.length==1&&targets[0]!=player&&get.itemtype(targets[0])=='player') (()=>{ let avatar2; const target=targets[0]; if(!target.isUnseen(0)) avatar2=target.node.avatar.cloneNode(); else if(!player.isUnseen(1)) avatar2=target.node.avatar2.cloneNode(); else if(get.mode()=='guozhan'&&target.node&&target.node.name_seat){ avatar2=ui.create.div('.avatar.cardbg'); avatar2.innerHTML=target.node.name_seat.innerHTML[0]; } else return; node.node.avatar2=avatar2; avatar2.style.transform=''; avatar2.classList.add('avatar2'); avatar2.classList.add('avatar3'); node.insertBefore(avatar2,avatar); })(); } if(targets&&targets.length){ if(targets.length==1&&targets[0]==player){ node.targets=[]; } else{ node.targets=targets; } } const fullheight=ui.historybar.offsetHeight,num=Math.round((fullheight-8)/50),margin=(fullheight-42*num)/(num+1); node.style.transform='scale(0.8)'; ui.historybar.insertBefore(node,ui.historybar.firstChild); ui.refresh(node); node.classList.remove('hidden'); Array.from(ui.historybar.childNodes).forEach((value,index)=>{ if(index<num){ value.style.transform=`scale(1) translateY(${margin+index*(42+margin)-4}px)`; return; } if(value.removetimeout) return; value.style.opacity=0; value.style.transform=`scale(1) translateY(${fullheight}px)`; value.removetimeout=setTimeout((current=>()=>current.remove())(value),500); }); if(lib.config.touchscreen) node.addEventListener('touchstart',ui.click.intro); else{ node.addEventListener(lib.config.pop_logv?'mousemove':'click',ui.click.logv); node.addEventListener('mouseleave',ui.click.logvleave); } node.logvid=logvid; node.added=[]; if(!game.online){ event=event||_status.event; event.logvid=node.logvid; } return node; }, putDB:(storeName,idbValidKey,value,onSuccess,onError)=>{ if(!lib.db) return Promise.resolve(value); if(lib.status.reload) return new Promise((resolve,reject)=>lib[_status.dburgent?'ondb2':'ondb'].push(['putDB',[storeName,idbValidKey,value,event=>{ if(typeof onSuccess=='function') onSuccess(event); resolve(event); },event=>{ if(typeof onError=='function'){ onError(event); resolve(); } else reject(event); }]])); lib.status.reload++; return new Promise((resolve,reject)=>{ const record=lib.db.transaction([storeName],'readwrite').objectStore(storeName).put(value,idbValidKey); record.onerror=event=>{ if(typeof onError=='function'){ onError(event); game.reload2(); resolve(); } else{ game.reload2(); reject(event); } };; record.onsuccess=event=>{ if(typeof onSuccess=='function'){ _status.dburgent=true; onSuccess(event); delete _status.dburgent; } game.reload2(); resolve(event); }; }); }, getDB:(storeName,query,onSuccess,onError)=>{ if(!lib.db) return new Promise(resolve=>{ if(typeof onSuccess=='function') onSuccess(null); resolve(null); }); if(lib.status.reload) return new Promise((resolve,reject)=>lib[_status.dburgent?'ondb2':'ondb'].push(['getDB',[storeName,query,result=>{ if(typeof onSuccess=='function') onSuccess(result); resolve(result); },event=>{ if(typeof onError=='function'){ onError(event); resolve(); } else reject(event); }]])); return new Promise(query?(resolve,reject)=>{ lib.status.reload++; const idbRequest=lib.db.transaction([storeName],'readwrite').objectStore(storeName).get(query); idbRequest.onerror=event=>{ if(typeof onError=='function'){ onError(event); game.reload2(); resolve(); } else{ game.reload2(); reject(event); } };; idbRequest.onsuccess=event=>{ const result=event.target.result; if(typeof onSuccess=='function'){ _status.dburgent=true; onSuccess(result); delete _status.dburgent; } game.reload2(); resolve(result); }; }:(resolve,reject)=>{ lib.status.reload++; const idbRequest=lib.db.transaction([storeName],'readwrite').objectStore(storeName).openCursor(),object={}; idbRequest.onerror=event=>{ if(typeof onError=='function'){ onError(event); game.reload2(); resolve(); } else{ game.reload2(); reject(event); } };; idbRequest.onsuccess=event=>{ const result=event.target.result; if(result){ object[result.key]=result.value; result.continue(); return; } if(typeof onSuccess=='function'){ _status.dburgent=true; onSuccess(object); delete _status.dburgent; } game.reload2(); resolve(object); }; }); }, deleteDB:(storeName,query,onSuccess,onError)=>{ if(!lib.db) return new Promise(resolve=>{ if(typeof onSuccess=='function') onSuccess(false); resolve(false); }); if(lib.status.reload) return new Promise((resolve,reject)=>lib[_status.dburgent?'ondb2':'ondb'].push(['deleteDB',[storeName,query,event=>{ if(typeof onSuccess=='function') onSuccess(event); resolve(event); },event=>{ if(typeof onError=='function'){ onError(event); resolve(); } else reject(event); }]])); return query?new Promise((resolve,reject)=>{ lib.status.reload++; const record=lib.db.transaction([storeName],'readwrite').objectStore(storeName).delete(query); record.onerror=event=>{ if(typeof onError=='function'){ onError(event); game.reload2(); resolve(); } else{ game.reload2(); reject(event); } }; record.onsuccess=event=>{ if(typeof onSuccess=='function') onSuccess(event); game.reload2(); resolve(event); }; }):game.getDB(storeName).then(object=>{ const keys=Object.keys(object); lib.status.reload+=keys.length; const store=lib.db.transaction([storeName],'readwrite').objectStore(storeName); return Promise.allSettled(keys.map(key=>new Promise((resolve,reject)=>{ const request=store.delete(key); request.onerror=event=>{ game.reload2(); reject(event); };; request.onsuccess=event=>{ game.reload2(); resolve(event); }; }))); }); }, save:(key,value,mode)=>{ if(_status.reloading) return; mode=mode||lib.config.mode; if(lib.db){ if(!key){ game.putDB('data',mode,get.copy(lib.storage)); return; } if(mode==lib.config.mode){ if(value==undefined) delete lib.storage[key]; else lib.storage[key]=value; lib.storage.version=lib.version; game.putDB('data',mode,lib.storage); } else game.getDB('data',mode,config=>{ if(!config) config={}; if(value==undefined) delete config[key]; else config[key]=value; config.version=lib.version; game.putDB('data',mode,config); }); return; } if(!key){ localStorage.setItem(`${lib.configprefix}${mode}`,JSON.stringify(lib.storage)); return; } let config; try{ config=JSON.parse(localStorage.getItem(`${lib.configprefix}${mode}`)); if(typeof config!='object') throw 'err'; } catch(err){ config={}; } if(value==undefined){ delete config[key]; if(mode==lib.config.mode) delete lib.storage[key]; } else{ config[key]=value; if(mode==lib.config.mode) lib.storage[key]=value; } config.version=lib.version; localStorage.setItem(`${lib.configprefix}${mode}`,JSON.stringify(config)); }, showChangeLog:()=>{ if(lib.version==lib.config.version&&!_status.extensionChangeLog) return; const ul=document.createElement('ul'); ul.style.textAlign='left'; const caption=lib.version==lib.config.version?'扩展更新':`${lib.version}更新内容`; let players=null,cards=null; if(lib.version!=lib.config.version) lib.changeLog.forEach(value=>{ if(value.startsWith('players://')) try{ players=JSON.parse(value.slice(10)).filter(value=>lib.character[value]); } catch(e){ players=null; } else if(value.startsWith('cards://')) try{ cards=JSON.parse(value.slice(8)).filter(value=>lib.card[value]); } catch(e){ cards=null; } else{ const li=document.createElement('li'); li.innerHTML=value; ul.appendChild(li); } }); game.saveConfig('version',lib.version); if(_status.extensionChangeLog) Object.keys(_status.extensionChangeLog).forEach(value=>{ const li=document.createElement('li'); li.innerHTML=`${value}:${_status.extensionChangeLog[value]}`; ul.appendChild(li); }); const dialog=ui.create.dialog(caption,'hidden'),lic=ui.create.div(dialog.content); lic.style.display='block'; ul.style.display='inline-block'; ul.style.marginLeft='-40px'; lic.appendChild(ul); if(players&&players.length){ dialog.addSmall([players,'character']); dialog.classList.add('forcebutton'); dialog.classList.add('withbg'); } if(cards&&cards.length){ dialog.addSmall([cards.map(value=>[get.translation(get.type(value)),'',value]),'vcard']); dialog.classList.add('forcebutton'); dialog.classList.add('withbg'); } dialog.open(); let hidden=false; if(!ui.auto.classList.contains('hidden')){ ui.auto.hide(); hidden=true; } game.pause(); const control=ui.create.control('确定',()=>{ dialog.close(); control.close(); if(hidden) ui.auto.show(); game.resume(); }); lib.init.onfree(); }, showExtensionChangeLog:(str,extname)=>{ extname=extname||_status.extension; const cfg=`extension_${extname}_changelog`; if(!lib.extensionPack[extname]||lib.extensionPack[extname].version==lib.config[cfg]) return; game.saveConfig(cfg,lib.extensionPack[extname].version); if(_status.extensionChangeLog) return; _status.extensionChangeLog={}; _status.extensionChangeLog[extname]=str; }, saveConfig:(key,value,local,callback)=>{ if(_status.reloading) return; if(local){ const localmode=typeof local=='string'?local:lib.config.mode; if(!lib.config.mode_config[localmode]) lib.config.mode_config[localmode]={}; if(value==undefined) delete lib.config.mode_config[localmode][key]; else lib.config.mode_config[localmode][key]=value; key+=`_mode_config_${localmode}`; } else if(value==undefined) delete lib.config[key]; else lib.config[key]=value; if(lib.db){ if(value==undefined) game.deleteDB('config',key,callback); else game.putDB('config',key,value,callback); return; } let config; try{ config=JSON.parse(localStorage.getItem(`${lib.configprefix}config`)); if(!config||typeof config!='object') throw 'err'; } catch(err){ config={}; } if(value===undefined) delete config[key]; else config[key]=value; localStorage.setItem(`${lib.configprefix}config`,JSON.stringify(config)); if(callback) callback(); }, saveConfigValue:key=>game.saveConfig(key,lib.config[key]), saveExtensionConfig:(extension,key,value)=>game.saveConfig(`extension_${extension}_${key}`,value), saveExtensionConfigValue:(extension,key)=>game.saveExtensionConfig(extension,key,game.getExtensionConfig(extension,key)), getExtensionConfig:(extension,key)=>lib.config[`extension_${extension}_${key}`], clearModeConfig:mode=>{ if(_status.reloading) return; if(lib.db){ game.getDB('config',null,config=>Object.keys(config).forEach(value=>{ if(value.substr(value.indexOf('_mode_config')+13)==mode) game.saveConfig(value); })); return; } let config; try{ config=JSON.parse(localStorage.getItem(`${lib.configprefix}config`)); if(!config||typeof config!='object') throw 'err'; } catch(err){ config={}; } Object.keys(config).forEach(value=>{ if(value.substr(value.indexOf('_mode_config')+13)==mode) delete config[value]; }); localStorage.setItem(`${lib.configprefix}config`,JSON.stringify(config)); localStorage.removeItem(`${lib.configprefix}${mode}`); }, addPlayer:(position,character,character2)=>{ if(position<0||position>game.players.length+game.dead.length||position==undefined) position=Math.ceil(Math.random()*(game.players.length+game.dead.length)); const players=game.players.concat(game.dead); ui.arena.setNumber(players.length+1); players.forEach(value=>{ if(parseInt(value.dataset.position)>=position) value.dataset.position=parseInt(value.dataset.position)+1; }); const player=ui.create.player(ui.arena).animate('start'); if(character) player.init(character,character2); game.players.push(player); player.dataset.position=position; game.arrangePlayers(); return player; }, addFellow:(position,character,animation)=>{ game.addVideo('addFellow',null,[position,character,animation]); const player=ui.create.player(ui.arena).animate(animation||'start'); player.dataset.position=position||game.players.length+game.dead.length; player.getId(); if(character) player.init(character); game.players.push(player); game.arrangePlayers(); return player; }, triggerEnter:player=>{ const next=game.createEvent('enterGame',false); next.player=player; next.setContent(()=>{ event.trigger('enterGame'); }); return next; }, restorePlayer:player=>{ if(game.players.contains(player)||game.dead.contains(player)) return; let position=parseInt(player.dataset.position); if(position<0||position>game.players.length+game.dead.length||position==undefined) position=Math.ceil(Math.random()*(game.players.length+game.dead.length)); const players=game.players.concat(game.dead); ui.arena.setNumber(players.length+1); players.forEach(value=>{ if(parseInt(value.dataset.position)>=position) value.dataset.position=parseInt(value.dataset.position)+1; }); game.players.push(player); delete player.removed; player.removeAttribute('style'); player.animate('start'); ui.arena.appendChild(player); game.arrangePlayers(); return player; }, removePlayer:player=>{ if(_status.roundStart==player) _status.roundStart=player.next||player.getNext()||game.players[0]; const players=game.players.concat(game.dead); player.style.left=`${player.getLeft()}px`; player.style.top=`${player.getTop()}px`; if(player==undefined) player=game.dead[0]||game.me.next; const position=parseInt(player.dataset.position); players.forEach(value=>{ if(parseInt(value.dataset.position)>position) value.dataset.position=parseInt(value.dataset.position)-1; }); if(player.isAlive()){ player.next.previous=player.previous; player.previous.next=player.next; } player.nextSeat.previousSeat=player.previousSeat; player.previousSeat.nextSeat=player.nextSeat; player.delete(); game.players.remove(player); game.dead.remove(player); ui.arena.setNumber(players.length-1); player.removed=true; if(player==game.me){ ui.me.hide(); ui.auto.hide(); ui.wuxie.hide(); } setTimeout(()=>player.removeAttribute('style'),500); return player; }, replacePlayer:(player,character,character2)=>{ player.removed=true; const position=parseInt(player.dataset.position); game.players.remove(player); game.dead.remove(player); player.delete(); const player2=ui.create.player(ui.arena).animate('start'); if(character) player2.init(character,character2); game.players.push(player2); player2.dataset.position=position; player2.nextSeat=player.nextSeat; player2.previousSeat=player.previousSeat; player2.nextSeat.previousSeat=player2; player2.previousSeat.nextSeat=player2; const player3=player2.nextSeat; while(player3.isDead()){ player3=player3.nextSeat; } player3.previous=player2; player2.next=player3; const player4=player2.previousSeat; while(player4.isDead()){ player4=player4.previousSeat; } player4.next=player2; player2.previous=player4; if(_status.roundStart==player) _status.roundStart=player2; return player2; }, arrangePlayers:()=>{ if(game.chess&&game.me){ let friendCount=0,enemyCount=0; const rand=Math.random()<0.5,sortCount=new Map(); game.players.forEach(value=>{ if(value.side==game.me.side){ if(rand) if(value==game.friendZhu) sortCount.set(value,-2); else sortCount.set(value,2*friendCount); else if(value==game.friendZhu) sortCount.set(value,-1); else sortCount.set(value,2*friendCount+1); friendCount++; return; } if(rand) if(value==game.enemyZhu) sortCount.set(value,-1); else sortCount.set(value,2*enemyCount+1); else if(value==game.enemyZhu) sortCount.set(value,-2); else sortCount.set(value,2*enemyCount); enemyCount++; }); game.players.sort((a,b)=>sortCount.get(a)-sortCount.get(b)); } else game.players.sort(lib.sort.position); game.players.concat(game.dead).sort(lib.sort.position).forEach((value,index,array)=>{ if(index==0) value.previousSeat=array[array.length-1]; else value.previousSeat=array[index-1]; if(index==array.length-1) value.nextSeat=array[0]; else value.nextSeat=array[index+1]; }); game.players.forEach((value,index,array)=>{ if(index==0) value.previous=array[array.length-1]; else value.previous=array[index-1]; if(index==array.length-1) value.next=array[0]; else value.next=array[index+1]; }); }, filterSkills:(skills,player,exclude)=>{ const out=skills.slice().removeArray(Object.keys(player.disabledSkills)); if(!player.storage.skill_blocker||!player.storage.skill_blocker.length) return out; return out.filter(value=>exclude&&exclude.includes(value)||!get.is.blocked(value,player)); }, expandSkills:skills=>skills.addArray(skills.reduce((previousValue,currentValue)=>{ const info=get.info(currentValue); if(info){ if(Array.isArray(info.group)) previousValue.push(...info.group); else if(info.group) previousValue.push(info.group); } else console.log(currentValue); return previousValue; },[])), css:style=>Object.keys(style).forEach(value=>{ let uiStyle=ui.style[value]; if(!uiStyle){ uiStyle=ui.style[value]=document.createElement('style'); document.head.appendChild(uiStyle); } uiStyle.innerHTML=`${value}${JSON.stringify(style[value]).replace(/"/g,"")}`; }), hasPlayer:(func,includeOut)=>game.players.some(value=>(includeOut||!value.isOut())&&func(value)), hasPlayer2:(func,includeOut)=>game.players.concat(game.dead).some(value=>(includeOut||!value.isOut())&&func(value)), countPlayer:(func,includeOut)=>{ if(typeof func!='function') func=lib.filter.all; return game.players.reduce((previousValue,currentValue)=>{ if(!includeOut&¤tValue.isOut()) return previousValue; const result=func(currentValue); if(typeof result=='number') previousValue+=result; else if(result) previousValue++; return previousValue; },0); }, countPlayer2:(func,includeOut)=>{ if(typeof func!='function') func=lib.filter.all; return game.players.concat(game.dead).reduce((previousValue,currentValue)=>{ if(!includeOut&¤tValue.isOut()) return previousValue; const result=func(currentValue); if(typeof result=='number') previousValue+=result; else if(result) previousValue++; return previousValue; },0); }, filterPlayer:(func,list,includeOut)=>{ if(!Array.isArray(list)) list=[]; if(typeof func!='function') func=lib.filter.all; return list.addArray(game.players.filter(value=>(includeOut||!value.isOut())&&func(value))); }, filterPlayer2:(func,list,includeOut)=>{ if(!Array.isArray(list)) list=[]; if(typeof func!='function') func=lib.filter.all; return list.addArray(game.players.concat(game.dead).filter(value=>(includeOut||!value.isOut())&&func(value))); }, findPlayer:(func,includeOut)=>game.players.find(value=>(includeOut||!value.isOut())&&func(value))||null, findPlayer2:(func,includeOut)=>game.players.concat(game.dead).find(value=>(includeOut||!value.isOut())&&func(value))||null, findCards:(func,all)=>Object.keys(lib.card).filter(value=>{ if(!lib.translate[`${value}_info`]) return false; if(lib.card[value].mode&&lib.card[value].mode.includes(lib.config.mode)==false) return false; if(!all&&!lib.inpile.includes(value)) return false; return func(value,lib.card[value]); }), countGroup:()=>{ const list=lib.group.slice(0); return game.countPlayer(current=>{ if(!list.includes(current.group)) return false; list.remove(current.group); return true; }); }, players:[], dead:[], imported:[], playerMap:{}, phaseNumber:0, roundNumber:0, shuffleNumber:0, }; window['b'+'ann'+'e'+'dE'+'x'+'ten'+'s'+'i'+'o'+'ns']=['\u4fa0\u4e49','\u5168\u6559\u7a0b']; const ui={ updates:[], thrown:[], touchlines:[], todiscard:{}, refresh:function(node){ void window.getComputedStyle(node, null).getPropertyValue("opacity"); }, create:{ /** * 创建codemirror编辑器 * @param {HTMLDivElement} container * @param {Function} saveInput */ editor:function(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; }, cardTempName:function(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.contains(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+=`<span>${cardTempNameConfig=='default'?get.verticalStr(tempname):tempname}</span>`; node.tempname=tempname; return node; }, connectRooms:function(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('<div class="popup text pointerdiv" style="width:calc(100% - 10px);display:inline-block;white-space:nowrap">空房间</div>'); player.roomindex=i; player.initRoom=lib.element.player.initRoom; player.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.connectroom); player.initRoom(list[i]); ui.rooms.push(player); } }, rarity:function(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'); }*/ }, div:function(){ 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(get.objtype(arguments[i])=='div'|| get.objtype(arguments[i])=='table'|| get.objtype(arguments[i])=='tr'|| get.objtype(arguments[i])=='td'|| get.objtype(arguments[i])=='body') 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; }, filediv:function(){ 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; }, node:function(){ 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(get.objtype(arguments[i])=='div'|| get.objtype(arguments[i])=='table'|| get.objtype(arguments[i])=='tr'|| get.objtype(arguments[i])=='td'|| get.objtype(arguments[i])=='body') 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; }, iframe:function(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); }, identitycircle:function(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)'; } }, chat:function(){ var chat=ui.create.system('聊天',null,true); ui.chatButton=chat; lib.setPopped(chat,ui.click.chat,220); }, exit:function(){ if(!ui.exit){ ui.exit=ui.create.control('退出房间',ui.click.exit); } }, connecting:function(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); } }, roomInfo:function(){ 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); }, templayer:function(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); }, selectlist:function(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; }, menu:function(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('<div class="text" style="display:inline">'+str+'</div>'); }); } } else{ node.innerHTML='<span>'+config.name+'</span>'; if(!config.nopointer){ node.classList.add('pointerspan'); } } if(config.item){ if(typeof config.item=='function'){ config.item=config.item(); } if(Array.isArray(config.init)){ } 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){ } 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(/<br>/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(/<br>/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 }; } for(var j in infoconfig){ if(j==='update'){ continue; } var cfg=copyObj(infoconfig[j]); cfg._name=j; cfg.mode=mode; if(!config.hasOwnProperty(j)){ game.saveConfig(j,cfg.init,mode); } else{ cfg.init=config[j]; } 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','<div style="margin-right:10px" class="pointerdiv">上移↑</div><div class="pointerdiv">下移↓</div>'); 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','更多 <div>></div>',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','<span>隐藏此模式</span>',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.contains(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.contains(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.contains(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+='<div class="placeholder slim" style="display:block;height:8px"></div>'; } } 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','自动发动 <div>></div>',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','双将禁配 <div>></div>',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','<span class="pointerdiv">添加...</span>',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.contains(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(!config.hasOwnProperty(j)){ if(cfg.type!='autoskill'&&cfg.type!='banskill'){ game.saveConfig(j,cfg.init); } } else{ cfg.init=config[j]; } 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','更多 <div>></div>',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','导入素材包 <div>></div>',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('','<input type="file" accept="application/zip" style="width:153px"><button>确定</button>',importExtension); var promptnode=ui.create.div('','<div style="width:153px;font-size:small;margin-top:8px">',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='导入成功。<span class="hrefnode">重新启动</span><span class="closenode">×</span>'; 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='正在导入... <span class="hrefnode">详细信息</span>'; 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('','<span>'+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('','<span>'+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.contains(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.contains(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].contains('unseen')) continue; if(connectMenu&&lib.connectBanned.contains(i)) continue; list.push(i); if(boolAI&&!lib.config.forbidai_user.contains(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.contains(_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:lib.config.characters.contains(mode), onclick:togglePack }); var cfgnodeAI=createConfig({ name:'仅点将可用', _name:mode, init:boolAI, intro:'将该武将包内的武将全部设置为仅点将可用', onclick:function(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:function(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.contains(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.contains(list2[ii])){ listx.add(list2[ii]); if(!listb.contains(list2[ii])) boolx=true; list2.splice(ii--,1); } } if(listx.length){ var cfgnodeY={ name:lib.translate[pak], _name:pak, init:boolx, onclick:function(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.contains(mode)){ ui.create.div('.config.pointerspan','<span style="opacity:0.5">该武将包不可被隐藏</span>',page); } else if(!mode.startsWith('mode_')){ ui.create.div('.config.pointerspan','<span>隐藏武将包</span>',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.contains(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.contains(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.contains(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.contains(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.contains(mode)&&!mode.startsWith('mode_')){ ui.create.div('.config.pointerspan','<span>隐藏卡牌包</span>',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','编辑牌堆 <div>></div>',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].contains(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.contains(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.contains('当前牌堆')){ 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','保存当前牌堆 <div>></div>',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('','名称:<input type="text"><button>确定</button>',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.contains(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(!lib.config.hasOwnProperty(j)){ game.saveConfig(j,cfg.init); } else{ cfg.init=lib.config[j]; } 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.contains(i)&&!lib.config.all.plays.contains(i)) continue; if(lib.config.hiddenPlayPack.contains(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]; } game.readFile('LICENSE',function(data){ extension['LICENSE']=data; game.writeFile(data,'extension/'+page.currentExtension,'LICENSE',function(){}) 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=''; }); } },function(){ alert('许可证文件丢失,无法导出扩展'); }); },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='已保存。退出游戏并重新打开后生效<span class="closenode">×</span>'; exportExtLine.querySelectorAll('span')[0].onclick=function(){ exportExtLine.style.display='none'; }; } else{ exportExtLine.innerHTML='重启后生效。<span class="hrefnode">立即重启</span><span class="closenode">×</span>'; 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='已导出扩展。<span class="hrefnode">分享扩展</span><span class="closenode">×</span>'; 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=lib.gnc.of(function*(){ 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].contains(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) }; yield 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='编辑武将 <div>></div>'; 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','<div style="transform:none;margin-right:3px">←</div>返回',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','创建武将 <div>></div>',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='创建武将 <div>></div>'; 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','姓名:<input class="new_name" type="text">',newCharacter).style.paddingTop='8px'; ui.create.div('.indent','介绍:<input class="new_des" type="text">',newCharacter).style.paddingTop='8px'; ui.create.div('.indent','体力:<input class="new_hp" type="text" placeholder="体/限/甲">',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','<span>主公<input type="checkbox" name="zhu"></span><span>BOSS<input type="checkbox" name="boss"></span><span>仅点将可用<input type="checkbox" name="forbidai"></span><br><span>隐匿技<input type="checkbox" name="hiddenSkill"></span><br>',newCharacter); var addSkill=ui.create.div('.add_skill','添加技能<br>',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.contains('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='编辑卡牌 <div>></div>'; 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','<div style="transform:none;margin-right:3px">←</div>返回',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','创建卡牌 <div>></div>',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='创建卡牌 <div>></div>'; 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','名称:<input class="new_name" type="text">',newCard).style.paddingTop='8px'; ui.create.div('.indent','描述:<input class="new_description" type="text">',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){ lib.init.js(lib.assetURL+'game','codemirror',()=>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','编辑牌堆 <div>></div>',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.contains(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','<div style="transform:none;margin-right:3px">←</div>返回',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(info); toggle.innerHTML='编辑技能 <div>></div>'; 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','创建技能 <div>></div>',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='创建技能 <div>></div>'; 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','名称:<input class="new_name" type="text" style="width:120px"></input>',newSkill); var descnode=ui.create.div('.config','描述:<input class="new_description" type="text" style="width:120px"></input>',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){ lib.init.js(lib.assetURL+'game','codemirror',()=>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.contains(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(lib.skill[skillopt.value]); 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','<div style="transform:none;margin-right:3px">←</div>返回',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\n\/*\n示例:\nhelp={\n "帮助条目":"<ul><li>列表1-条目1<li>列表1-条目2</ul><ol><li>列表2-条目1<li>列表2-条目2</ul>"\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){ lib.init.js(lib.assetURL+'game','codemirror',()=>lib.codeMirrorReady(node,this.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 "帮助条目":"<ul><li>列表1-条目1<li>列表1-条目2</ul><ol><li>列表2-条目1<li>列表2-条目2</ul>"\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','导入扩展 <div>></div>',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('','<input type="file" accept="application/zip" style="width:153px"><button>确定</button>',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='<span>正在下载</span><div>正在下载</div>'; 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.contains(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]&&game.importedPack.config[i].hasOwnProperty('init')){ 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+'<span>('+list[i].size+')</span>',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+'<p style="margin-top:8px;white-space:nowrap"></p>'; li2.innerHTML='素材版本:'+(lib.config.asset_version||'无')+'<p style="margin-top:8px"></p>'; li3.innerHTML='更新地址:<span>'+trimURL(lib.config.updateURL||lib.updateURL)+'</span><p style="margin-top:8px"></p>'; 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.contains(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.contains(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','选项 <div>></div>'); 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&¤trow1.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&¤trow1.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&¤trow1.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.contains(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'); var text=document.createElement('div'); text.style.width='194px'; text.style.height='124px'; text.style.padding='3px'; text.style.borderRadius='2px'; text.style.boxShadow='rgba(0, 0, 0, 0.2) 0 0 0 1px'; text.style.textAlign='left'; text.style.webkitUserSelect='initial'; text.style.overflow='scroll'; text.style.position='absolute'; text.style.left='30px'; text.style.top='50px'; text.style.wordBreak='break-all'; var pre=ui.create.node('pre.fullsize',text); pre.style.margin=0; pre.style.padding=0; pre.style.position='relative'; pre.style.webkitUserSelect = pre.style.userSelect = 'text'; lib.setScroll(pre); page.appendChild(text); // var caption=ui.create.div('','输入命令',page); // caption.style.margin='6px'; // caption.style.position='absolute'; // caption.style.width='120px'; // caption.style.top='129px'; // caption.style.left='64px'; var text2=document.createElement('input'); text2.style.width='200px'; text2.style.height='20px'; text2.style.padding='0'; text2.style.position='absolute'; text2.style.top='15px'; text2.style.left='30px'; text2.style.resize='none'; text2.style.border='none'; text2.style.borderRadius='2px'; text2.style.boxShadow='rgba(0, 0, 0, 0.2) 0 0 0 1px'; var g={}; var logs=[]; var logindex=-1; var cheat=lib.cheat; //使用正则匹配绝大多数的普通obj对象,避免解析成代码块。 var 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$_]*\(\))))*\}$/; //使用new Function隔绝作用域,避免在控制台可以直接访问到runCommand等变量 var fun=(new Function('reg','value','_status','lib','game','ui','get','ai',`"use strict";\nreturn eval(reg.test(value)?('('+value+')'):value)`)); var runCommand=function(e){ if(text2.value&&!['up','down'].contains(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{ var value=text2.value.trim(); if(value.endsWith(";")) value=value.slice(0,-1).trim(); var result=fun(reg,value,_status,lib,game,ui,get,ai); game.print(result); } catch(e){ game.print(e); } } text2.value=''; } } text2.addEventListener('keydown',function(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(){ var args=[].slice.call(arguments); var printResult=args.map(arg=>{ if(get.is.object(arg)||typeof arg=='function'){ var argi=get.stringify(arg); if(argi/*&&argi.length<5000*/){ return argi.replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } else return arg.toString(); }else{ var str=String(arg); if (!/<[a-zA-Z]+[^>]*?\/?>.*?(?=<\/[a-zA-Z]+[^>]*?>|$)/.exec(str)) return String(arg) .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); else return str; } }).join(' '); pre.innerHTML+=printResult+'<br>'; text.scrollTop=text.scrollHeight; } if(_status.toprint){ for(var i=0;i<_status.toprint.length;i++){ game.print.apply(this,_status.toprint[i]); } delete _status.toprint; } runButton.listen(runCommand); clearButton.listen(function(){ 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+'<span>重置</span>',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[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&¤t!=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+'<br>'+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', '<span class="underlinenode slim ">导入录像...</span>',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='<input type="file" accept="*/*" style="width:calc(100% - 40px)">'+ '<button style="width:40px">确定</button>'; 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); } }, table:function(){ 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(get.objtype(arguments[i])=='div'|| get.objtype(arguments[i])=='table'|| get.objtype(arguments[i])=='tr'|| get.objtype(arguments[i])=='td'|| get.objtype(arguments[i])=='body') 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; }, giveup:function(){ 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); }, groupControl:function(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'); } } } } }); }, cardDialog:function(){ var args=['thisiscard']; for(var i=0;i<arguments.length;i++){ args.push(arguments[i]); } return ui.create.characterDialog.apply(this,args); }, characterDialog2:function(filter){ var list=[]; for(var i in lib.character){ if(lib.character[i][4].contains('minskin')) continue; if(lib.character[i][4].contains('boss')||lib.character[i][4].contains('hiddenboss')){ if(lib.config.mode=='boss') continue; if(!lib.character[i][4].contains('bossallowed')) continue; } if(lib.character[i][4].contains('stonehidden')) continue; if(lib.config.banned.contains(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.contains(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; }, characterDialog:function(){ // if(lib.config.character_dialog_style=='newstyle'){ // for(var i=0;i<arguments.length;i++){ // if(arguments[i]=='thisiscard'){ // break; // } // } // if(i==arguments.length){ // return ui.create.characterDialog2.apply(this,arguments); // } // } var filter,str,noclick,thisiscard,seperate,expandall,onlypack,heightset,precharacter,characterx; for(var i=0;i<arguments.length;i++){ if(arguments[i]==='thisiscard'){ thisiscard=true; } else if(arguments[i]==='expandall'){ expandall=true; } else if(arguments[i]==='heightset'){ heightset=true; } else if(arguments[i]=='precharacter'){ precharacter=true; } else if(arguments[i]=='characterx'){ characterx=true; } else if(typeof arguments[i]=='string'&&arguments[i].startsWith('onlypack:')){ onlypack=arguments[i].slice(9); } else if(typeof arguments[i]=='object'&&typeof arguments[i].seperate=='function'){ seperate=arguments[i].seperate; } else if(typeof arguments[i]==='string'){ str=arguments[i]; } else if(typeof arguments[i]==='function'){ filter=arguments[i]; } else if(typeof arguments[i]=='boolean'){ noclick=arguments[i]; } } var list=[]; const groups=[]; var dialog; var node=ui.create.div('.caption.pointerspan'); if(get.is.phoneLayout()){ node.style.fontSize='30px'; } var namecapt=[]; var getCapt=function(str){ var capt; if(str.indexOf('_')==-1){ capt=str[0]; } else{ capt=str[str.lastIndexOf('_')+1]; } capt=capt.toLowerCase(); if(!/[a-z]/i.test(capt)){ capt='自定义'; } return capt; } if(thisiscard){ for(var i in lib.card){ if(!lib.translate[i+'_info']) continue; if(filter&&filter(i)) continue; list.push(['',get.translation(lib.card[i].type),i]); if(namecapt.indexOf(getCapt(i))==-1){ namecapt.push(getCapt(i)); } } } else{ for(var i in lib.character){ if(lib.character[i][4].contains('minskin')) continue; if(lib.character[i][4].contains('boss')||lib.character[i][4].contains('hiddenboss')){ if(lib.config.mode=='boss') continue; if(!lib.character[i][4].contains('bossallowed')) continue; } if(lib.character[i][4].contains('stonehidden')) continue; if(lib.character[i][4].contains('unseen')) continue; if(lib.config.banned.contains(i)) continue; if(lib.characterFilter[i]&&!lib.characterFilter[i](get.mode())) continue; if(filter&&filter(i)) continue; list.push(i); if(get.is.double(i)){ groups.add('double'); } else groups.add(lib.character[i][1]); if(namecapt.indexOf(getCapt(i))==-1){ namecapt.push(getCapt(i)); } } } namecapt.sort(function(a,b){ return a>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.contains(lib.config.all.characters[i])) continue; packlist.push(lib.config.all.characters[i]); } for(var i in lib.characterPack){ if(!lib.config.all.characters.contains(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].contains(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; }, dialog:function(){ var i; var hidden=false; var notouchscroll=false; var forcebutton=false; var noforcebutton=false; var dialog=ui.create.div('.dialog'); dialog.contentContainer=ui.create.div('.content-container',dialog); dialog.content=ui.create.div('.content',dialog.contentContainer); dialog.bar1=ui.create.div('.bar.top',dialog); dialog.bar2=ui.create.div('.bar.bottom',dialog); dialog.buttons=[]; for(i in lib.element.dialog){ dialog[i]=lib.element.dialog[i]; } for(i=0;i<arguments.length;i++){ if(typeof arguments[i]=='boolean') dialog.static=arguments[i]; else if(arguments[i]=='hidden') hidden=true; else if(arguments[i]=='notouchscroll') notouchscroll=true; else if(arguments[i]=='forcebutton') forcebutton=true; else if(arguments[i]=='noforcebutton') noforcebutton=true; else dialog.add(arguments[i]); } if(!hidden){ dialog.open(); } if(!lib.config.touchscreen) dialog.contentContainer.onscroll=ui.update; if(!notouchscroll){ dialog.contentContainer.ontouchstart=ui.click.dialogtouchStart; dialog.contentContainer.ontouchmove = ui.click.touchScroll; dialog.contentContainer.style.WebkitOverflowScrolling='touch'; dialog.ontouchstart=ui.click.dragtouchdialog; } if(noforcebutton){ dialog.noforcebutton=true; } else if(forcebutton){ dialog.forcebutton=true; dialog.classList.add('forcebutton'); } return dialog; }, line2:function(){ var node=ui.create.line.apply(this,arguments); node.classList.add('line2'); return node; }, line:function(){ 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; }, switcher:function(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; }, caption:function(str,position){ var caption=ui.create.div('.caption',position); caption.innerHTML=str; return caption; }, control:function(){ var nc=!ui.control.querySelector('div:not(.removing):not(.stayleft)'); // for(var i=0;i<ui.control.childNodes.length;i++){ // if(ui.control.childNodes[i].classList.contains('removing')){ // var that=ui.control.childNodes[i]; // var width=that.offsetWidth; // that.style.marginLeft=(-width/2)+'px'; // that.style.marginRight=(-width/2)+'px'; // that.style.transitionDuration=0.8*parseFloat(getComputedStyle(that).opacity)+'s'; // } // } var i,controls; var nozoom=false; if(Array.isArray(arguments[0])) controls=arguments[0]; else controls=arguments; var control=ui.create.div('.control'); ui.control.insertBefore(control,_status.createControl||ui.confirm); for(i in lib.element.control){ control[i]=lib.element.control[i]; } for(i=0;i<controls.length;i++){ if(typeof controls[i]=='function'){ control.custom=controls[i]; } else if(controls[i]=='nozoom'){ nozoom=true; } else if(controls[i]=='stayleft'){ control.stayleft=true; control.classList.add('stayleft'); } else{ control.add(controls[i]); } } ui.controls.unshift(control); if(nc){ ui.control.animate('nozoom',100); } // if(ui.control.classList.contains('nozoom')){ // nozoom=true; // } // if(nozoom){ // control.classList.add('nozoom'); // } if(control.childNodes.length){ // if(nozoom||true){ control.style.transition='opacity 0.5s'; control.animate('controlpressdownx',500); // } // else{ // control.style.transition=''; // control.style.transform='scale(0.8)'; // } ui.refresh(control); if(!control.stayleft){ control.style.transform='translateX(-'+(control.offsetWidth/2)+'px)'; } control.style.opacity=1; ui.refresh(control); control.style.transition=''; } control.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.control2); if(lib.config.button_press){ control.addEventListener(lib.config.touchscreen?'touchstart':'mousedown',function(){ if(this.classList.contains('disabled')) return; this.classList.add('controlpressdown'); if(typeof this._offset=='number'){ this.style.transform='translateX('+this._offset+'px) scale(0.97)'; } }); control.addEventListener(lib.config.touchscreen?'touchend':'mouseup',function(){ this.classList.remove('controlpressdown'); if(typeof this._offset=='number'){ this.style.transform='translateX('+this._offset+'px)'; } }); } ui.updatec(); return control; }, confirm:function(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; } }, skills:function(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.contains(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; }, skills2:function(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.contains(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; }, skills3:function(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.contains(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; }, arena:function(){ 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; // 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)<parseInt(lib.config.fewplayer)){ // this.classList.add('fewplayer'); // } // else{ // this.classList.remove('fewplayer'); // } } if(lib.config.low_performance){ ui.window.classList.add('low_performance'); } if(game.layout=='mobile'||game.layout=='long'){ ui.arena.classList.add('mobile'); } if(game.layout=='long'||game.layout=='long2'){ ui.arena.classList.add('long'); } if(game.layout=='default'){ ui.arena.classList.add('oldlayout'); } if(lib.config.player_border!='wide'||game.layout=='long'||game.layout=='long2'){ ui.arena.classList.add('slim_player'); } if(lib.config.player_border=='slim'){ ui.arena.classList.add('uslim_player'); } if(lib.config.player_border=='narrow'){ ui.arena.classList.add('mslim_player'); } if(lib.config.player_border=='normal'&&lib.config.mode!='brawl'&&(game.layout=='long'||game.layout=='long2')){ ui.arena.classList.add('lslim_player'); } ui.window.dataset.player_border=lib.config.player_border; if(lib.config.compatiblemode){ ui.window.classList.add('compatiblemode'); } ui.window.dataset.radius_size=lib.config.radius_size||'default'; if(game.layout=='long'||game.layout=='mobile'){ //if(lib.config.textequip=='text') ui.arena.classList.add('textequip'); ui.arena.classList.add('textequip'); } if(game.layout=='long'||game.layout=='long2'||game.layout=='mobile'||game.layout=='nova'){ if(lib.config.cardshape=='oblong'){ ui.window.classList.add('oblongcard'); ui.arena.classList.add('oblongcard'); } } if(lib.config.blur_ui){ ui.window.classList.add('blur_ui'); } if(lib.config.glass_ui){ ui.window.classList.add('glass_ui'); } if(lib.config.custom_button){ lib.configMenu.appearence.config.custom_button.onclick('skip'); } if(lib.config.show_statusbar_ios=='overlay'){ document.body.classList.add('statusbar'); } if(lib.config.keep_awake){ if(window.plugins&&window.plugins.insomnia) window.plugins.insomnia.keepAwake(); else{ lib.init.js(lib.assetURL+'game','NoSleep',function(){ var noSleep = new NoSleep(); document.addEventListener(lib.config.touchscreen?'touchend':'click', function enableNoSleep() { document.removeEventListener(lib.config.touchscreen?'touchend':'click', enableNoSleep, false); noSleep.enable(); window.noSleep=noSleep; }, false); }); } } lib.init.js(lib.assetURL+'game','pinyinjs',function(){}) lib.init.js(lib.assetURL+'game','keyWords',function(){}); lib.updateURL=lib.updateURLS[lib.config.update_link]||lib.updateURLS.coding; lib.init.cssstyles(); ui.arena.dataset.player_height=lib.config.player_height||'default'; ui.arena.dataset.player_height_nova=lib.config.player_height_nova||'default'; // if(lib.config.player_height_nova=='long') ui.arena.classList.add('player_autolong'); ui.arena.dataset.target_shake=lib.config.target_shake||'off'; ui.backgroundMusic=document.createElement('audio'); ui.backgroundMusic.volume=lib.config.volumn_background/8; game.playBackgroundMusic(); ui.backgroundMusic.autoplay=true; ui.backgroundMusic.addEventListener('ended',game.playBackgroundMusic); ui.window.appendChild(ui.backgroundMusic); ui.window.addEventListener(lib.config.touchscreen?'touchend':'click', function playMusic() { ui.window.removeEventListener(lib.config.touchscreen?'touchend':'click', playMusic, false); if(!ui.backgroundMusic.played.length && lib.config.background_music != 'music_off') ui.backgroundMusic.play(); }, false); if(lib.config.cursor_style=='pointer'){ ui.window.classList.add('nopointer'); } if(lib.config.turned_style==false){ ui.arena.classList.add('hide_turned'); } if(lib.config.link_style2!='chain'){ ui.arena.classList.add('nolink'); } if(lib.config.show_name==false){ ui.arena.classList.add('hide_name'); } if(lib.config.change_skin_auto!='off'){ _status.skintimeout=setTimeout(ui.click.autoskin,parseInt(lib.config.change_skin_auto)); } if(lib.config.border_style&&lib.config.border_style.startsWith('dragon_')){ ui.arena.dataset.framedecoration=lib.config.border_style.slice(7); } ui.gameinfo=ui.create.div('#time',ui.window); ui.arenalog=ui.create.div('#arenalog',ui.arena); if(lib.config.show_log=='off'){ ui.arenalog.style.display='none'; } else{ ui.arenalog.dataset.position=lib.config.show_log; } ui.historybar=ui.create.div('#historybar.shadowed',ui.window); lib.setScroll(ui.historybar); ui.roundmenu=ui.create.div('#roundmenu.roundarenabutton.menubutton.round',ui.arena); ui.roundmenu._position=[180,210]; ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); if(lib.config.show_time2){ ui.roundmenu.classList.add('clock'); } ui.roundmenu.dataset.watchface=lib.config.watchface||'none'; if(get.is.phoneLayout()){ if(lib.config.show_time3){ ui.time3=ui.create.div('.touchinfo.left',ui.window); } ui.cardPileNumber=ui.create.div('.touchinfo.right',ui.window); } else{ if(lib.config.show_time3){ ui.time3=ui.create.div(ui.gameinfo); } ui.cardPileNumber=ui.create.div(ui.gameinfo); } if(!lib.config.show_cardpile_number){ ui.cardPileNumber.style.display='none'; } if(ui.time3){ ui.time3.starttime=get.utc(); ui.time3.interval=setInterval(function(){ var num=Math.round((get.utc()-ui.time3.starttime)/1000); if(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'].contains(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','<div>托管中...</div>',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.contains('replay')) ui.replay.classList.add('forcehide'); if(lib.forcehide.contains('auto')) ui.auto.classList.add('forcehide'); if(lib.forcehide.contains('pause')) ui.pause.classList.add('forcehide'); if(lib.forcehide.contains('wuxie')) ui.wuxie.classList.add('forcehide'); if(lib.forcehide.contains('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).animate('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','<span>重来</span>',ui.shortcut,game.reload).dataset.position=1; ui.create.div('.menubutton.round','<span>退出</span>',ui.shortcut,game.exit).dataset.position=3; ui.create.div('.menubutton.round','<span>记录</span>',ui.shortcut,ui.click.pause).dataset.position=4; ui.shortcut.autobutton=ui.create.div('.menubutton.round','<span>托管</span>',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.contains(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','<span>菜单</span>',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().animate('start'); node.appendChild(ui.sidebar); node.firstChild.innerHTML='正在测试'; node.removeEventListener('click',ui.click.resume); },500); } }, system:function(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; }, pause:function(){ 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; }, prebutton:function(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; }, buttonPresets:{ tdnodes:(item,type,position,noclick,node)=>{ node=ui.create.div('.shadowed.reduce_radius.pointerdiv.tdnode.tdnodes',position); if(Array.isArray(item)){ node.innerHTML='<span>'+(item[1])+'</span>'; node.link=item[0]; } else{ node.innerHTML='<span>'+(item)+'</span>'; node.link=item; } return node; }, blank:(item,type,position,noclick,node)=>{ node=ui.create.div('.button.card',position); node.link=item; return node; }, 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; }, 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; }, 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}<div data-nature="${get.groupnature(currentValue)}">${get.translation(currentValue)}</div>`,''); 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=`<div>${get.translation(infoitem[1])}</div>`; 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; }, characterx:(item,type,position,noclick,node)=>{ return ui.create.buttonPresets.character(item,type,position,noclick,node); }, 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; } }, button:function(item,type,position,noclick,node){ if(ui.create.buttonPresets[type]){ node=ui.create.buttonPresets[type](item,type,position,noclick,node); } else if(typeof type=='function'){ node=type(item,type,position,noclick,node); } if(!noclick){ node.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.button); } else{ node.classList.add('noclick'); if(node.querySelector('.intro')){ node.querySelector('.intro').remove(); } } for(var i in lib.element.button){ node[i]=lib.element.button[i]; } return node; }, buttons:function(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; }); } } for(var i=0;i<list.length;i++){ if(pre){ buttons.push(ui.create.prebutton(list[i],type.slice(3),position,noclick)); } else{ buttons.push(ui.create.button(list[i],type,position,noclick)); } } return buttons; }, textbuttons:function(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('<div')) str='<div class="popup text textbutton">'+str+'</div>'; var next=dialog.add(str); if(!noclick) next.firstChild.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.button); next.firstChild.link=link; for(var j in lib.element.button){ next[j]=lib.element.button[j]; } dialog.buttons.add(next.firstChild) } }, player:function(position,noclick){ var node=ui.create.div('.player',position); node.node={ avatar:ui.create.div('.avatar',node,ui.click.avatar).hide(), avatar2:ui.create.div('.avatar2',node,ui.click.avatar2).hide(), turnedover:ui.create.div('.turned','<div>'+get.verticalStr('翻面')+'<div>',node), framebg:ui.create.div('.framebg',node), intro:ui.create.div('.intro',node), identity:ui.create.div('.identity',node), hp:ui.create.div('.hp',node), name:ui.create.div('.name',node), name2:ui.create.div('.name.name2',node), nameol:ui.create.div('.nameol',node), count:ui.create.div('.count',node).hide(), equips:ui.create.div('.equips',node).hide(), judges:ui.create.div('.judges',node), marks:ui.create.div('.marks',node), chain:ui.create.div('.chain','<div></div>',node), handcards1:ui.create.div('.handcards'), handcards2:ui.create.div('.handcards'), expansions:ui.create.div('.expansions'), }; node.node.expansions.display='none'; var chainlength=game.layout=='default'?64:40; for(var i=0;i<chainlength;i++){ ui.create.div(node.node.chain.firstChild,'.cardbg').style.transform='translateX('+(i*5-5)+'px)'; } node.node.action=ui.create.div('.action',node.node.avatar); node.phaseNumber=0; node.skipList=[]; node.skills=[]; node.invisibleSkills=[]; node.initedSkills=[]; node.additionalSkills={}; node.disabledSkills={}; node.hiddenSkills=[]; node.awakenedSkills=[]; node.forbiddenSkills={}; node.popups=[]; node.damagepopups=[]; node.judging=[]; node.stat=[{card:{},skill:{}}]; node.actionHistory=[{useCard:[],respond:[],skipped:[],lose:[],gain:[],sourceDamage:[],damage:[],custom:[],useSkill:[]}]; node.tempSkills={}; node.storage={}; node.marks={}; node.expandedSlots={}; node.disabledSlots={}; node.ai={friend:[],enemy:[],neutral:[],handcards:{global:[],source:[],viewed:[]}}; node.queueCount=0; node.outCount=0; for(var i in lib.element.player){ node[i]=lib.element.player[i]; } node.node.link=node.mark(' ',{mark:get.linkintro}); node.node.link.firstChild.setBackgroundImage('image/card/tiesuo_mark.png') node.node.link.firstChild.style.backgroundSize='cover'; ui.create.div(node.node.identity); if(!noclick){ node.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.target); node.node.identity.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.identity); if(lib.config.touchscreen){ node.addEventListener('touchstart',ui.click.playertouchstart); } } else node.noclick=true; return node; }, connectPlayers:function(ip){ game.connectPlayers=[]; for(var i=0;i<8;i++){ var player=ui.create.player(ui.window); player.dataset.position=i; player.classList.add('connect'); game.connectPlayers.push(player); if(i>=lib.configOL.number){ player.classList.add('unselectable2'); } } 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.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(); delete ui.connectStartButton; delete ui.connectStartBar; button.clicked=true; }); ui.connectStartButton=button; ui.connectStartBar=bar; }, players:function(num){ if(num===0){ return; } if(num==undefined) num=lib.configOL.number; if(num==undefined) num=get.playerNumber(); if(typeof num=='string'){ num=parseInt(num); } if(!num) num=5; for(var i=0;i<num;i++){ var player=ui.create.player().animate('start'); game.players.push(player); player.dataset.position=i; } var players=game.players; for(var i=0;i<players.length;i++){ if(i>0){ players[i].previous=players[i-1]; players[i].previousSeat=players[i-1]; } if(i<players.length-1){ players[i].next=players[i+1]; players[i].nextSeat=players[i+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(num); for(var i=0;i<num;i++){ ui.arena.appendChild(players[i]); } // ui.arena.classList.add('glass'); // for(var i=0;i<num;i++){ // var bg=ui.create.div('.glassbg'); // var bg2=ui.create.div(bg); // ui.create.div(bg); // var rect=players[i].getBoundingClientRect(); // bg2.style.backgroundImage='url("image/background/huangtian_bg.jpg")'; // bg2.style.width=ui.window.offsetWidth+'px'; // bg2.style.height=ui.window.offsetHeight+'px'; // bg2.style.transform='translate('+(-rect.left)+'px,'+(-rect.top)+'px)'; // players[i].insertBefore(bg,players[i].firstChild); // } return players; }, me:function(hasme){ ui.mebg=ui.create.div('#mebg',ui.arena); ui.me=ui.create.div('#me',ui.arena).animate('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(); } }, card:function(position,info,noclick){ var node=ui.create.div('.card',position); node.node={ image:ui.create.div('.image',node), info:ui.create.div('.info',node), name:ui.create.div('.name',node), name2:ui.create.div('.name2',node), background:ui.create.div('.background',node), intro:ui.create.div('.intro',node), range:ui.create.div('.range',node), gaintag:ui.create.div('.gaintag',node), } for(var i in lib.element.card){ node[i]=lib.element.card[i]; } node.node.intro.innerHTML=lib.config.intro; if(!noclick){ lib.setIntro(node); } node.storage={}; node.vanishtag=[]; node.gaintag=[]; node._uncheck=[]; if(info!='noclick'){ node.addEventListener(lib.config.touchscreen?'touchend':'click',ui.click.card); if(lib.config.touchscreen){ node.addEventListener('touchstart',ui.click.cardtouchstart); node.addEventListener('touchmove',ui.click.cardtouchmove); } if(lib.cardSelectObserver){ lib.cardSelectObserver.observe(node,{attributes:true}); } } return node; }, cardsAsync:function(){ 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); } }, cards:function(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.contains(lib.card.list[i][2])) continue; } else{ if(lib.configOL.bannedcards.contains(lib.card.list[i][2])) continue; } if(game.bannedcards&&game.bannedcards.contains(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); }, }, click:{ identitycircle:function(){ 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; }, connectEvents:function(){ 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('<input type="text" style="width:calc(100% - 10px);resize: none;border: none;border-radius: 2px;box-shadow: rgba(0, 0, 0, 0.2) 0px 0px 0px 1px;margin-top: -2px;margin-bottom: 2px;">'); 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.contains(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)+'<br>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.contains(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(); } }; } }, connectClients:function(){ 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('<input type="text" style="width:calc(100% - 10px);resize: none;border: none;border-radius: 2px;box-shadow: rgba(0, 0, 0, 0.2) 0px 0px 0px 1px;margin-top: -2px;margin-bottom: 2px;">'); 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','<span class="thundertext thunderauto">'+(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','<span style="opacity:0.6">'+(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(); } }; } }, autoskin:function(){ 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(); }, skin:function(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'; }, touchpop:function(forced){ if(lib.config.touchscreen||forced){ _status.touchpopping=true; clearTimeout(_status.touchpoppingtimeout); _status.touchpoppingtimeout=setTimeout(function(){ _status.touchpopping=false; },600); } }, exit:function(){ 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(); } }, shortcut:function(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'); } }, favouriteCharacter:function(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.contains(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(); }, buttonnameenter:function(){ 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); } }, buttonnameleave:function(){ 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); } }, dragtouchdialog:function(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(); } }, identity:function(e){ if(_status.dragged) return; _status.clicked=true; if(!game.getIdentityList) return; if(_status.video) return; if(this.parentNode.forceShown) 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.contains(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); // } // } } }, identity2:function(){ 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; } }, roundmenu:function(){ 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; }, pausehistory:function(){ 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; }, pauseconfig:function(){ 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.contains(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; }, cardPileButton:function(){ 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('剩余 <span style="font-family:'+'xinwei'+'">'+num); if(_status.connectMode) return uiintro; uiintro.add('<div class="text center">轮数 <span style="font-family:xinwei">'+game.roundNumber+'</span> 洗牌 <span style="font-family:xinwei">'+game.shuffleNumber+'</div>'); uiintro.add('<div class="text center">弃牌堆</div>'); 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('<div class="text center" style="padding-bottom:3px">无</div>'); } return uiintro; }, chat:function(){ 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('<input type="text" value="'+_status.chatValue+'">'); 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{ lib.element.player.chat.call(player,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','<img src="'+lib.assetURL+'image/emotion/'+i+'/1.gif" width="50" height="50">',function(){ emotionTitle.innerHTML=get.translation(this.pack); for(var j=1;j<=lib.emotionList[this.pack];j++){ var emotionButton=ui.create.div('.card.fullskin','<img src="'+lib.assetURL+'image/emotion/'+this.pack+'/'+j+'.gif" width="50" height="50">',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{ lib.element.player.emotion.apply(player,[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{ lib.element.player.chat.call(player,str); } }); node.innerHTML=lib.quickVoice[i]; list3.appendChild(node); } list3.scrollTop=list1.scrollHeight; return uiintro; }, volumn:function(){ 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; }, volumn_background:function(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(); }, volumn_audio:function(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(); }, hoverpopped:function(){ 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); } }, hoverpopped_leave:function(){ this._poppedalready=false; }, leavehoverpopped:function(){ 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); }, dierevive:function(){ 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; } } }, dieswap:function(){ 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; } } }, dieswap2:function(){ if(_status.dragged) return; game.swapPlayer(this.link); }, touchconfirm:function(){ _status.touchconfirmed=true; document.removeEventListener('touchstart',ui.click.touchconfirm); }, windowtouchstart:function(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); // } }, windowtouchmove:function(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; } }, windowtouchend:function(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; }, checkroundtranslate:function(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)'; }, checkdialogtranslate:function(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)'; }, windowmousewheel:function(e){ _status.tempunpopup=e; }, windowmousemove:function(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<remained.length;j++){ // if(remained[j]) remained[j].remove(); // } 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.clientX/game.documentZoom-ui.arena.offsetLeft,e.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(); } } } while(item){ if(item==_status.mousedragorigin){ if(_status.mouseleft){ _status.mousedragging=null; _status.mousedragorigin=null; _status.clicked=false; if(_status.event.type=='phase'&&!_status.event.skill&&ui.confirm){ ui.confirm.classList.add('removing'); } 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.clientX/game.documentZoom-ui.arena.offsetLeft; var ey=e.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; 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; } } }, windowmousedown:function(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; } }, cardtouchstart:function(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 }; } }, cardtouchmove:function(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; } }, windowmouseup:function(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'); } }, mousemove:function(){ if(!lib.config.hover_handcard&&this.parentNode&&this.parentNode.parentNode==ui.me){ return; } if(!_status.currentmouseenter){ _status.currentmouseenter=this; } }, mouseenter:function(){ if(!lib.config.hover_handcard&&this.parentNode&&this.parentNode.parentNode==ui.me){ return; } _status.currentmouseenter=this; }, mouseleave:function(){ ui.click.mouseentercancel(); if(_status.currentmouseenter==this){ _status.currentmouseenter=null; } this._mouseentercreated=false; }, mousedown:function(){ ui.click.mouseentercancel(); if(_status.currentmouseenter==this){ _status.currentmouseenter=null; } this._mouseentercreated=true; }, mouseentercancel:function(){ if(_status._mouseentertimeout){ clearTimeout(_status._mouseentertimeout); delete _status._mouseentertimeout } }, hoverplayer:function(e){ var node=get.nodeintro(this,true); if(node) node.style.zIndex=21; return node; }, longpressdown:function(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; }, longpresscallback:function(){ 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(); } }, longpresscancel:function(){ if(this._longpresstimeout){ clearTimeout(this._longpresstimeout); delete this._longpresstimeout; } delete this._longpressevent; if(_status.longpressing==this){ delete _status.longpressing; } }, window:function(){ 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); } }, toggle:function(){ 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); } }, editor:function(){ if(_status.dragged) return; if(_status.editing) return; _status.clicked=true; this.innerHTML=''; _status.editing=this; if(this.additionalCommand) this.additionalCommand(this); }, switcher:function(){ 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).animate('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); } }, choice:function(){ 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); } }, button:function(){ 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(); }, touchintro:function(){ var rect=this.getBoundingClientRect(); ui.click.touchpop(); ui.click.intro.call(this,{ clientX:rect.left+18, clientY:rect.top+12 }); _status.clicked=false; }, card:function(){ 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 }); } }, avatar:function(){ 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.contains(player)&&!game.dead.contains(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); }, avatar2:function(){ 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.contains(player)&&!game.dead.contains(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); }, connectroom:function(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); } } }, player:function(){ return ui.click.target.apply(this,arguments); }, target:function(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(); }, control2:function(){ if(this.childNodes.length==1&&!this._doubleclick){ ui.click.control.call(this.firstChild); } }, control:function(){ 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(); } }, dialogcontrol:function(){ _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(); }, skill:function(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,'<div><div style="width:100%;text-align:center">'+str2+'</div></div>'); if(info.longprompt){ event.skillDialog.forcebutton=true; ui.update(); } } else if(info.promptfunc){ event.skillDialog=ui.create.dialog(str,'<div><div style="width:100%">'+info.promptfunc(event,event.player)+'</div></div>'); } else if(lib.dynamicTranslate[skill]){ event.skillDialog=ui.create.dialog(str,'<div><div style="width:100%">'+lib.dynamicTranslate[skill](event.player,skill)+'</div></div>'); } else if(lib.translate[skill+'_info']){ event.skillDialog=ui.create.dialog(str,'<div><div style="width:100%">'+lib.translate[skill+'_info']+'</div></div>'); } } }, ok:function(node){ var event=_status.event; if(event.custom&&event.custom.replace.confirm){ event.custom.replace.confirm(true);return; } event.result={ buttons:ui.selected.buttons.slice(0), cards:ui.selected.cards.slice(0), targets:ui.selected.targets.slice(0), confirm:'ok', bool:true, links:get.links(ui.selected.buttons) }; if(node){ node.parentNode.close(); } if(event.skill){ event.result.skill=event.skill; if(typeof get.info(event.skill).viewAs=='function') event.result.card=get.info(event.skill).viewAs(event.result.cards,event.player); else event.result.card=get.copy(get.info(event.skill).viewAs); if(event.result.cards.length==1&&event.result.card){ if(!event.result.card.suit) event.result.card.suit=get.suit(event.result.cards[0]); if(!event.result.card.number) event.result.card.number=get.number(event.result.cards[0]); } if(event.skillDialog&&get.objtype(event.skillDialog)=='div'){ event.skillDialog.close(); } var cards=event.player.getCards('hej'); for(var i=0;i<cards.length;i++){ cards[i].recheck('useSkill'); } event.restore(); } else if(event.name=='chooseToUse'||event.name=='chooseToRespond'){ event.result.card=get.autoViewAs(event.result.cards[0]); } 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(); }, cancel:function(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.animate('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(); }, logv:function(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); } }, logvleave:function(){ 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; } }, charactercard:function(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].contains('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].contains('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'].contains(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.contains(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='<span style="font-size:7px">'+' '+'</span>'+'|'+'<span style="font-size:7px">'+' '+'</span>'; intro.innerHTML='<span style="font-weight:bold;margin-right:5px">'+charactername+'</span>'+'<span style="font-size:14px;font-family:SimHei,STHeiti,sans-serif">'+'['+characterpinyin+']'+'</span>'+spacemark+charactersex+spacemark+charactergroup+spacemark+characterhp+'<span style="line-height:2"></span>'+'<br>'+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='<span style="font-weight:bold;margin-right:5px">'+skillname+'</span>'+'<span style="font-size:14px;font-family:SimHei,STHeiti,sans-serif">'+'['+skillpinyin+']'+'</span>'+' '+skilltranslationinfo; }else{ intro2.innerHTML='<span style="font-weight:bold;margin-right:5px">'+skillname+'</span>'+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+='<br><br><span style="font-weight:bold;margin-right:5px">'+derivationname+'</span>'+'<span style="font-size:14px;font-family:SimHei,STHeiti,sans-serif">'+'['+derivationpinyin+']'+'</span>'+' '+derivationtranslationinfo; }else{ intro2.innerHTML+='<br><br><span style="font-weight:bold;margin-right:5px">'+derivationname+'</span>'+derivationtranslationinfo; } } } if(info.alter){ intro2.innerHTML+='<br><br><div class="hrefnode skillversion"></div>'; var skillversionnode=intro2.querySelector('.hrefnode.skillversion'); if(lib.config.vintageSkills.contains(skill)){ skillversionnode.innerHTML='切换至新版'; } else{ skillversionnode.innerHTML='切换至旧版'; } skillversionnode.listen(function(){ if(lib.config.vintageSkills.contains(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'){ var audioname=this.link; if(info.audioname2&&info.audioname2[playername]){ audioname=info.audioname2[playername]; info=lib.skill[audioname]; } var audioinfo=info.audio; var that=this; var getIndex=function(i){ if(typeof that.audioindex!='number'){ that.audioindex=i; } that.audioindex++; if(that.audioindex>i){ that.audioindex=1; } return that.audioindex; }; if(typeof audioinfo=='string'){ if(audioinfo.indexOf('ext:')==0){ audioinfo=audioinfo.split(':'); if(audioinfo.length==3){ if(audioinfo[2]=='true'){ game.playAudio('..','extension',audioinfo[1],audioname); } else{ audioinfo[2]=parseInt(audioinfo[2]); if(audioinfo[2]){ game.playAudio('..','extension',audioinfo[1],audioname+getIndex(audioinfo[2])); } } } return; } else{ audioname=audioinfo; if(lib.skill[audioinfo]){ audioinfo=lib.skill[audioinfo].audio; } } } else if(Array.isArray(audioinfo)){ audioname=audioinfo[0]; audioinfo=audioinfo[1]; } if(typeof audioinfo=='number'){ if(Array.isArray(info.audioname)&&info.audioname.contains(playername)) audioname=audioname+'_'+playername; game.playAudio('skill',audioname+getIndex(audioinfo)); } else if(typeof audioinfo=="object"&&"type" in audioinfo&&audioinfo.type=="direct"&&"files" in audioinfo){ let audioFiles=audioinfo.files; if(typeof audioFiles=="object"){ if(!Array.isArray(audioFiles)&&playername&&playername in audioFiles)audioFiles=audioFiles[playername]; if(Array.isArray(audioFiles)){ const length=audioFiles.length; game.playAudio(audioFiles[getIndex(length)-1]); } } } else if(audioinfo){ if(Array.isArray(info.audioname)&&info.audioname.contains(playername)) audioname=audioname+'_'+playername; game.playAudio('skill',audioname); } else if(true&&info.audio!==false){ if(Array.isArray(info.audioname)&&info.audioname.contains(playername)) audioname=audioname+'_'+playername; game.playSkillAudio(audioname,getIndex(2)); } } } }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.contains(skill)){ skillversionnode.innerHTML='切换至新版'; } else{ skillversionnode.innerHTML='切换至旧版'; } skillversionnode.listen(function(){ if(lib.config.vintageSkills.contains(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'){ var audioname=this.link; if(info.audioname2&&info.audioname2[playername]){ audioname=info.audioname2[playername]; info=lib.skill[audioname]; } var audioinfo=info.audio; var that=this; var getIndex=function(i){ if(typeof that.audioindex!='number'){ that.audioindex=i; } that.audioindex++; if(that.audioindex>i){ that.audioindex=1; } return that.audioindex; }; if(typeof audioinfo=='string'){ if(audioinfo.indexOf('ext:')==0){ audioinfo=audioinfo.split(':'); if(audioinfo.length==3){ if(audioinfo[2]=='true'){ game.playAudio('..','extension',audioinfo[1],audioname); } else{ audioinfo[2]=parseInt(audioinfo[2]); if(audioinfo[2]){ game.playAudio('..','extension',audioinfo[1],audioname+getIndex(audioinfo[2])); } } } return; } else{ audioname=audioinfo; if(lib.skill[audioinfo]){ audioinfo=lib.skill[audioinfo].audio; } } } else if(Array.isArray(audioinfo)){ audioname=audioinfo[0]; audioinfo=audioinfo[1]; } if(typeof audioinfo=='number'){ if(Array.isArray(info.audioname)&&info.audioname.contains(playername)) audioname=audioname+'_'+playername; game.playAudio('skill',audioname+getIndex(audioinfo)); } else if(typeof audioinfo=="object"&&"type" in audioinfo&&audioinfo.type=="direct"&&"files" in audioinfo){ let audioFiles=audioinfo.files; if(typeof audioFiles=="object"){ if(!Array.isArray(audioFiles)&&playername&&playername in audioFiles)audioFiles=audioFiles[playername]; if(Array.isArray(audioFiles)){ const length=audioFiles.length; game.playAudio(audioFiles[getIndex(length)-1]); } } } else if(audioinfo){ if(Array.isArray(info.audioname)&&info.audioname.contains(playername)) audioname=audioname+'_'+playername; game.playAudio('skill',audioname); } else if(true&&info.audio!==false){ if(Array.isArray(info.audioname)&&info.audioname.contains(playername)) audioname=audioname+'_'+playername; game.playSkillAudio(audioname,getIndex(2)); } } } } 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); }, intro:function(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; }, intro2:function(){ if(ui.intro){ ui.intro.close(); if(ui.intro.source==this){ delete ui.intro; ui.control.show(); game.resume2(); return; } } }, auto:function(){ 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); } } }, wuxie:function(){ 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); } }, tempnowuxie:function(){ 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); } }, pause:function(){ 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.animate('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(); } }, resume:function(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; }, config:function(){ 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'); }, swap:function(){ 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); }, mousewheel:function(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); } }, touchStart:function(e){ this.startX=e.touches[0].clientX/game.documentZoom; this.startY=e.touches[0].clientY/game.documentZoom; _status.dragged=false; }, dialogtouchStart:function(e){ ui.click.touchStart.call(this,e); _status.dialogtouched=true; }, touchScroll:function(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(); } }, autoskill:function(bool,node){ var list=lib.config.autoskilllist; if(bool){ list.remove(node.link); } else{ list.add(node.link); } game.saveConfig('autoskilllist',list); }, skillbutton:function(){ this.func(this.link); }, autoskill2:function(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(); }, hiddenskill:function(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(); }, // forcetouch:function(){ // if(_status.force||_status.dragged){ // clearInterval(_status.forcetouchinterval); // delete _status.forcetouchinterval; // return; // } // window.ForceTouch.getForceTouchData(function(ForceTouchData){ // if(ForceTouchData.touches[0]){ // var force = parseFloat(ForceTouchData.touches[0].force); // if(force > 0.2){ // _status.force=true; // var taptic=false; // if(_status.longpressing){ // delete _status.longpressing._waitingfordrag; // ui.click.touchpop(); // ui.click.longpresscallback.call(_status.longpressing); // taptic=true; // } // else if(!_status.forceright){ // _status.forceright=true; // setTimeout(function(){ // _status.forceright=false; // },600); // if(_status.mousedragging){ // _status.mousedragging=null; // _status.mouseleft=false; // _status.mousedragorigin=null; // _status.dragstatuschanged=false; // game.uncheck(); // game.check(); // } // switch(lib.config.pressure_click){ // case 'pause':ui.click.pause();break; // case 'auto':ui.click.auto();break; // case 'config':ui.click.config();break; // } // taptic=true; // } // if(taptic&&lib.config.pressure_taptic){ // if(window.TapticEngine){ // window.TapticEngine.generateTapticFeedback(); // } // else{ // game.vibrate(50); // } // } // } // } // }); // }, // pressurepause:function(force,event){ // if(!_status.force&&!_status.mousedragging&&force>=0.5&&!_status.forceright){ // _status.force=true; // _status.forceright=true; // setTimeout(function(){ // _status.forceright=false; // },600); // switch(lib.config.pressure_click){ // case 'pause':ui.click.pause();break; // case 'auto':ui.click.auto();break; // case 'config':ui.click.config();break; // } // } // }, // rightpressure:function(force, event){ // if(force>0){ // _status.force=true; // } // if(force>=0.5){ // if(_status.mousedragging){ // _status.mousedragging=null; // _status.mouseleft=false; // _status.mousedragorigin=null; // _status.dragstatuschanged=false; // game.uncheck(); // game.check(); // } // ui.click.rightplayer.call(this,event); // _status.clickedplayer=false; // } // }, rightplayer:function(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; }, right:function(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; } }, selected:{ buttons:[],cards:[],targets:[] }, clear:function(){ 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(); } }, updatec:function(){ 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.animate('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.animate('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.animate('controlpressdownx',500); control.style.transform='translateX('+offset+'px)'; control._offset=offset; } } }, updatex:function(){ 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; }, updatexr:function(){ if(ui._updatexr){ clearTimeout(ui._updatexr); } ui._updatexr=setTimeout(ui.updatex,500); }, updatejm:function(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; } } }, updatem:function(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]); } } }, updatej:function(player){ if(player){ ui.updatejm(player,player.node.judges); } else{ for(var i=0;i<game.players.length;i++){ ui.updatej(game.players[i]); } } }, updatehl:function(){ 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'; }, updateh:function(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); }, updatehx:function(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'); } }, updated:function(){ 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; } }, updatez:function(){ 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=''; } }, update:function(){ 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'); } } } } }, recycle:function(node,key){ if(!ui._recycle) ui._recycle={}; if(typeof node=='string'){ return ui._recycle[node] } ui._recycle[key]=node; }, }; const get={ //Generate an object URL from the Base64-encoded octet stream //从Base64编码的八位字节流生成对象URL 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 //获取此牌的字数 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) //获取(此牌的)应变条件 yingbianConditions:card=>get.complexYingbianConditions(card).concat(get.simpleYingbianConditions(card)), complexYingbianConditions:card=>{ const complexYingbianConditions=Array.from(lib.yingbian.condition.complex.keys()); return card?complexYingbianConditions.filter(value=>get.cardtag(card,`yingbian_${value}`)):complexYingbianConditions; }, 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) //获取(此牌的)应变效果 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 //获取此牌的默认应变效果 defaultYingbianEffect:card=>{ const info=get.info(card); return info&&info.defaultYingbianEffect||null; }, //优先度判断 priority:function(skill){ const info=get.info(skill); if(!info) return 0; if(info.hasOwnProperty('_priority')) 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,返回数组 subtypes:function(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) return get.copy(lib.card[name].subtypes); else if(lib.card[name].subtype) return [lib.card[name].subtype]; return []; }, //装备栏 END 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); }, yunmu:function(str){ //部分整体认读音节特化处理 const util=window.pinyinUtilx; if(util&&lib.pinyins._metadata.zhengtirendu.contains(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.contains(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。 paramToCacheKey:function(){ 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; }, yunjiao:function(str){ const util=window.pinyinUtilx; if(util) str=util.removeTone(str) if(lib.pinyins._metadata.zhengtirendu.contains(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.contains(i)) str='ü'+str.slice(1); break; } } } for(let i in lib.pinyins._metadata.yunjiao){ if(lib.pinyins._metadata.yunjiao[i].contains(str)) return i; } return null; }, skillCategoriesOf:function(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; }, numOf:function(obj,item){ var num=0; for(var i=0;i<obj.length;i++){ if(obj[i]==item) num++; } return num; }, connectNickname:function(){ return typeof lib.config.connect_nickname=='string'?(lib.config.connect_nickname.slice(0,12)):'无名玩家'; }, zhinangs:function(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(function(i){ return lib.inpile.contains(i); }); if(list.length) return list; return get.inpile('trick','trick').randomGets(3); }, sourceCharacter:function(str){ if(str){ for(var i in lib.characterReplace){ if(lib.characterReplace[i].contains(str)) return i; } } return str; }, isLuckyStar:function(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; }, infoHp:function(hp){ if(typeof hp=='number') return hp; else if(typeof hp=='string'&&hp.includes('/')){ return parseInt(hp.split('/')[0]); } return 0; }, infoMaxHp:function(hp){ if(typeof hp=='number') return hp; else if(typeof hp=='string'&&hp.includes('/')){ return parseInt(hp.split('/')[1]); } return 0; }, infoHujia:function(hp){ if(typeof hp=='string'&&hp.includes('/')){ var splited=hp.split('/'); if(splited.length>2) return parseInt(splited[2]); } return 0; }, is:{ /** * 判断传入的参数的属性是否相同(参数可以为卡牌、卡牌信息、属性等) * @param ...infos 要判断的属性列表 * @param every {boolean} 是否判断每一个传入的属性是否完全相同而不是存在部分相同 */ sameNature:function(){ let processedArguments=[],every=false; Array.from(arguments).forEach(argument=>{ if(typeof argument=='boolean') every=argument; else if(argument) processedArguments.push(argument); }); if(!processedArguments.length) return true; if(processedArguments.length==1){ const argument=processedArguments[0]; if(!Array.isArray(argument)) return false; if(!argument.length) return true; if(argument.length==1) return false; processedArguments=argument; } const naturesList=processedArguments.map(card=>{ if(typeof card=='string') return card.split(lib.natureSeparator); else if(Array.isArray(card)) return card; return get.natureList(card||{}); }); const testingNaturesList=naturesList.slice(0,naturesList.length-1); if(every) return testingNaturesList.every((natures,index)=>naturesList.slice(index+1).every(testingNatures=>testingNatures.length==natures.length&&testingNatures.every(nature=>natures.includes(nature)))); return testingNaturesList.every((natures,index)=>{ const comparingNaturesList=naturesList.slice(index+1); return natures.some(nature=>comparingNaturesList.every(testingNatures=>testingNatures.includes(nature))); }); }, /** * 判断传入的参数的属性是否不同(参数可以为卡牌、卡牌信息、属性等) * @param ...infos 要判断的属性列表 * @param every {boolean} 是否判断每一个传入的属性是否完全不同而不是存在部分不同 */ differentNature:function(){ let processedArguments=[],every=false; Array.from(arguments).forEach(argument=>{ if(typeof argument=='boolean') every=argument; else if(argument) processedArguments.push(argument); }); if(!processedArguments.length) return false; if(processedArguments.length==1){ const argument=processedArguments[0]; if(!Array.isArray(argument)) return true; if(!argument.length) return false; if(argument.length==1) return true; processedArguments=argument; } const naturesList=processedArguments.map(card=>{ if(typeof card=='string') return card.split(lib.natureSeparator); else if(Array.isArray(card)) return card; return get.natureList(card||{}); }); const testingNaturesList=naturesList.slice(0,naturesList.length-1); if(every) return testingNaturesList.every((natures,index)=>naturesList.slice(index+1).every(testingNatures=>testingNatures.every(nature=>!natures.includes(nature)))); return testingNaturesList.every((natures,index)=>{ const comparingNaturesList=naturesList.slice(index+1); return natures.some(nature=>comparingNaturesList.every(testingNatures=>testingNatures.some(testingNature=>testingNature!=nature))); }); }, //判断一张牌是否为明置手牌 shownCard:card=>{ if(!card) return false; const gaintag=card.gaintag; return Array.isArray(gaintag)&&gaintag.some(tag=>tag.startsWith('visible_')); }, //是否是虚拟牌 vituralCard:card=>card.isCard||(!("cards" in card)||!Array.isArray(card.cards)||card.cards.length==0), //是否是转化牌 convertedCard:card=>!card.isCard&&("cards" in card)&&Array.isArray(card.cards)&&card.cards.length>0, //是否是实体牌 ordinaryCard:card=>card.isCard&&("cards" in card)&&Array.isArray(card.cards)&&card.cards.length==1, //押韵判断 yayun:function(str1,str2){ if(str1==str2) return true; var pinyin1=get.pinyin(str1,false),pinyin2=get.pinyin(str2,false); if(!pinyin1.length||!pinyin2.length) return false; var pron1=pinyin1[pinyin1.length-1],pron2=pinyin2[pinyin2.length-1]; if(pron1==pron2) return true; return get.yunjiao(pron1)==get.yunjiao(pron2); }, blocked:function(skill,player){ if(!player.storage.skill_blocker||!player.storage.skill_blocker.length) return false; for(var i of player.storage.skill_blocker){ if(lib.skill[i]&&lib.skill[i].skillBlocker&&lib.skill[i].skillBlocker(skill,player)) return true; } return false; }, double:(name,array)=>{ const extraInformations=get.character(name,4); if(!extraInformations) return false; for(const extraInformation of extraInformations){ if(!extraInformation.startsWith('doublegroup:')) continue; return array?extraInformation.split(':').slice(1):true; } return false; }, //Check if the card has a Yingbian condition //检测此牌是否具有应变条件 yingbianConditional:card=>get.is.complexlyYingbianConditional(card)||get.is.simplyYingbianConditional(card), complexlyYingbianConditional:card=>{ for(const key of lib.yingbian.condition.complex.keys()){ if(get.cardtag(card,`yingbian_${key}`)) return true; } return false; }, simplyYingbianConditional:card=>{ for(const key of lib.yingbian.condition.simple.keys()){ if(get.cardtag(card,`yingbian_${key}`)) return true; } return false; }, //Check if the card has a Yingbian effect //检测此牌是否具有应变效果 yingbianEffective:card=>{ for(const key of lib.yingbian.effect.keys()){ if(get.cardtag(card,`yingbian_${key}`)) return true; } return false; }, yingbian:card=>get.is.yingbianConditional(card)||get.is.yingbianEffective(card), emoji:function(substring){ if(substring){ var reg=new RegExp("[~#^$@%&!?%*]",'g'); if(substring.match(reg)){ return true; } for(var i=0;i<substring.length;i++){ var hs=substring.charCodeAt(i); if(0xd800<=hs&&hs<=0xdbff){ if(substring.length>1){ var ls=substring.charCodeAt(i+1); var uc=((hs-0xd800)*0x400)+(ls-0xdc00)+0x10000; if(0x1d000<=uc&&uc<=0x1f77f){ return true; } } } else if(substring.length>1){ var ls=substring.charCodeAt(i+1); if(ls==0x20e3){ return true; } } else{ if(0x2100<=hs&&hs<=0x27ff){ return true; } else if(0x2B05<=hs&&hs<=0x2b07){ return true; } else if(0x2934<=hs&&hs<=0x2935){ return true; } else if(0x3297<=hs&&hs<=0x3299){ return true; } else if(hs==0xa9||hs==0xae||hs==0x303d||hs==0x3030 ||hs==0x2b55||hs==0x2b1c||hs==0x2b1b ||hs==0x2b50){ return true; } } } } return false; }, banWords:function(str){ if(get.is.emoji(str)) return true; for(var i of window.bannedKeyWords){ if(str.includes(i)) return true; } return false; }, converted:function(event){ return !(event.card&&event.card.isCard); }, safari:function(){ var ua=navigator.userAgent.toLowerCase(); return ua.indexOf('safari'!=-1)&&ua.indexOf('chrome')==-1; }, freePosition:function(cards){ for(var i=0;i<cards.length;i++){ if(!cards[i].hasPosition) return false; if(cards[i].hasPosition()) return false; } return true; }, nomenu:function(name,item){ var menus=['system','menu']; var configs={ show_round_menu:lib.config.show_round_menu, round_menu_func:lib.config.round_menu_func, touchscreen:lib.config.touchscreen, swipe_up:lib.config.swipe_up, swipe_down:lib.config.swipe_down, swipe_left:lib.config.swipe_left, swipe_right:lib.config.swipe_right, right_click:lib.config.right_click, phonelayout:lib.config.phonelayout }; configs[name]=item; if(!configs.phonelayout) return false; if(configs.show_round_menu&&menus.contains(configs.round_menu_func)){ return false; } if(configs.touchscreen){ if(menus.contains(configs.swipe_up)) return false; if(menus.contains(configs.swipe_down)) return false; if(menus.contains(configs.swipe_left)) return false; if(menus.contains(configs.swipe_right)) return false; } else{ if(configs.right_click=='config') return false; } if(name){ setTimeout(function(){ alert('请将至少一个操作绑定为显示按钮或打开菜单,否则将永远无法打开菜单'); }); } return true; }, altered:function(skill){ return false; // if(_status.connectMode) return true; // return !lib.config.vintageSkills.contains(skill); }, node:function(obj){ var str=Object.prototype.toString.call(obj); if(str&&str.indexOf('[object HTML')) return true; return false; }, div:function(obj){ return Object.prototype.toString.call(obj) === '[object HTMLDivElement]'; }, map:function(obj){ return Object.prototype.toString.call(obj) === '[object Map]'; }, set:function(obj){ return Object.prototype.toString.call(obj) === '[object Set]'; }, object:function(obj){ return Object.prototype.toString.call(obj) === '[object Object]'; }, singleSelect:function(func){ if(typeof func=='function') return false; var select=get.select(func); return select[0]==1&&select[1]==1; }, jun:function(name){ if(get.mode()=='guozhan'){ if(name&&typeof name=='object'){ if(name.isUnseen&&name.isUnseen(0)) return false; name=name.name1; } if(typeof name=='string'&&name.startsWith('gz_jun_')){ return true; } } return false; }, versus:function(){ return !_status.connectMode&&get.mode()=='versus'&&_status.mode=='three'; }, changban:function(){ return get.mode()=='single'&&_status.mode=='changban'; }, single:function(){ return get.mode()=='single'&&_status.mode=='normal'; }, mobileMe:function(player){ return (game.layout=='mobile'||game.layout=='long')&&!game.chess&&player.dataset.position==0; }, newLayout:function(){ if(game.layout!='default') return true; return false; }, phoneLayout:function(){ if(!lib.config.phonelayout) return false; return (game.layout=='mobile'||game.layout=='long'||game.layout=='long2'||game.layout=='nova'); }, singleHandcard:function(){ if(game.singleHandcard||game.layout=='mobile'||game.layout=='long'||game.layout=='long2'||game.layout=='nova'){ return true; } return false; }, linked2:function(player){ if(game.chess) return true; if(lib.config.link_style2!='rotate') return true; // if(game.chess) return false; if(game.layout=='long'||game.layout=='long2'||game.layout=='nova') return true; if(player.dataset.position=='0'){ return ui.arena.classList.contains('oblongcard'); } return false; }, empty:function(obj){ for(var i in obj) return false; return true; }, pos:function(str){ return (str=='h'||str=='e'||str=='j'||str=='he'||str=='hj'||str=='ej'||str=='hej'); }, locked:function(skill,player){ var info=lib.skill[skill]; if(typeof info.locked=='function') return info.locked(skill,player); if(info.locked==false) return false; if(info.trigger&&info.forced) return true; if(info.mod) return true; if(info.locked) return true; return false; }, }, bottomCards:function(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; }, discarded:function(){ var list=_status.discarded.slice(0); for(var i=0;i<list.length;i++){ if(list[i].parentNode!=ui.discardPile){ list.splice(i--,1); } } return list; }, cardOffset:function(){ var x=ui.arena.getBoundingClientRect(); var y=ui.window.getBoundingClientRect(); return -y.width/2+(x.left+x.width/2); }, colorspan:function(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 '<span class="'+color+'text '+color+'auto">'+str.slice(2)+'</span>'; } return str; }, evtprompt:function(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); } } }, autoViewAs:function(card,cards){ let _card; if(get.itemtype(card)=='card'){ _card={ name:get.name(card), suit:get.suit(card), color:get.suit(card), number:get.number(card), nature:get.nature(card), isCard:true, cardid:card.cardid, wunature:card.wunature, storage:get.copy(card.storage), }; if(Array.isArray(cards)) _card.cards=cards.slice(0); else _card.cards=[card]; } else{ _card=get.copy(card); if(Array.isArray(cards)){ if(_card.cards){ _card.cards=cards.slice(0); } else{ _card.cards=cards.slice(0); if(!lib.suits.includes(_card.suit)) _card.suit=get.suit(_card); if(!Object.keys(lib.color).includes(_card.color)) _card.color=get.color(_card); if(!_card.hasOwnProperty('number')) _card.number=get.number(_card); if(!_card.hasOwnProperty('nature')) _card.nature=(get.nature(_card)||false); } } } const info=get.info(_card,false); if(info.autoViewAs){ _card.name=info.autoViewAs; } return _card; }, //deprecated _autoViewAs:function(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; } }, max:function(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]); } }, min:function(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]); } }, character:function(name,num){ let info=lib.character[name]; if(!info){ const pack=Object.keys(lib.characterPack).find(pack=>lib.characterPack[pack].hasOwnProperty(name)); if(pack) info=lib.characterPack[pack][name]; } if(info){ if(typeof num=='number'){ return info[num]; } return info; } return null; }, characterIntro:function(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 '暂无武将介绍'; }, 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]||''; }, groupnature:function(group,method){ var nature=lib.groupnature[group]; if(!nature) return ''; if(method=='raw'){ return nature; } return nature+'mm'; }, sgn:function(num){ if(num>0) return 1; if(num<0) return -1; return 0; }, rand:function(num,num2){ if(typeof num2=='number'){ return num+Math.floor(Math.random()*(num2-num+1)); } else{ return Math.floor(Math.random()*num); } }, sort:function(arr,method){ switch(method){ case 'seat':{ lib.tempSortSeat=arguments[2]; arr.sort(lib.sort.seat); delete lib.tempSortSeat; return arr; } } }, sortSeat:function(arr,target){ lib.tempSortSeat=target; arr.sort(lib.sort.seat); delete lib.tempSortSeat; return arr; }, zip:function(callback){ if(!window.JSZip){ lib.init.js(lib.assetURL+'game','jszip',function(){ callback(new JSZip()); }); } else{ callback(new JSZip()); } }, delayx:function(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); } }, prompt:function(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)+'】?'; } }, prompt2:function(skill,target,player){ var str=get.prompt.apply(this,arguments); if(!lib.translate[skill+'_info']) return str; return '###'+str+'###'+lib.translate[skill+'_info']; }, url:function(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+'/'; } }, round:function(num,f){ var round=1; for(var i=0;i<f;i++){ round*=10; } return Math.round(num*round)/round; }, playerNumber:function(){ var num; if(_status.brawl&&_status.brawl.playerNumber){ num=_status.brawl.playerNumber } else{ num=get.config('player_number'); } return parseInt(num)||2; }, benchmark:function(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)); }, stringify:function(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){ if(/[^a-zA-Z]/.test(i)){ str+=indent+' "'+i+'":'+get.stringify(obj[i],level+1)+',\n'; } else{ str+=indent+' '+i+':'+get.stringify(obj[i],level+1)+',\n'; } } 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 /g,'\n'); } } else{ try{ if(Array.isArray(obj)&&obj.contains(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; } }, copy:function(obj){ if(get.objtype(obj)=='object'){ var copy={}; for(var i in obj){ copy[i]=get.copy(obj[i]); } return copy; } else if(Array.isArray(obj)){ var copy=[]; for(var i=0;i<obj.length;i++){ copy.push(get.copy(obj[i])); } return copy; } else{ return obj; } }, inpilefull:function(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.contains(info[2])&&get.type(info[2])==type){ list.push({ name:info[2], suit:info[0], number:info[1], nature:info[3] }); } } } return list; }, inpile:function(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; }, inpile2:function(type){ return get.inpile(type,'trick'); }, typeCard:function(type,filter){ var list=[]; for(var i in lib.card){ if(lib.card[i].mode&&lib.card[i].mode.contains(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.contains(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; }, libCard:function(filter){ var list=[]; for(var i in lib.card){ if(lib.card[i].mode&&lib.card[i].mode.contains(get.mode())==false) continue; // if(lib.card[i].vanish||lib.card[i].destroy) continue; if(lib.card[i].destroy) continue; if(lib.config.bannedcards.contains(i)) continue; if(!lib.translate[i+'_info']) continue; if(filter(lib.card[i],i)){ list.push(i); } } return list; }, ip:function(){ 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; } } } }, modetrans:function(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 '官渡之战'; } } else if(config.mode=='single'){ switch(config.single_mode){ case 'normal':return '新1v1'; case 'changban':return '血战长坂坡'; case 'dianjiang':return '点将单挑'; } } else if(config.mode=='identity'){ switch(config.identity_mode){ case 'purple':return '三对三对二'; case 'zhong':return (config.double_character?'双将':'')+'忠胆英杰'; default:return get.cnNumber(parseInt(config.number))+'人'+(config.double_character?'双将':'')+'身份'; } } else if(config.mode=='guozhan'&&config.guozhan_mode!='normal'){ switch(config.guozhan_mode){ case 'yingbian':return '应变国战'; case 'old':return '怀旧国战'; } } else{ if(server){ return get.translation(config.mode)+'模式'; } else{ return get.cnNumber(parseInt(config.number))+'人'+get.translation(config.mode); } } }, charactersOL:function(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.contains(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; }, trimip:function(str){ var len=str.length-5; if(str.lastIndexOf(':8080')==len){ str=str.slice(0,len); } return str; }, mode:()=>lib[_status.connectMode?'configOL':'config'].mode, idDialog:function(id){ for(var i=0;i<ui.dialogs.length;i++){ if(ui.dialogs[i].videoId==id){ return ui.dialogs[i]; } } return null; }, arenaState:function(){ 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; }, skillState:function(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; }, id:function(){ return (Math.floor(1000000+9000000*Math.random())).toString()+(10+lib.status.globalId++); }, zhu:function(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; }, config:function(item,mode){ mode=mode||lib.config.mode; if(!lib.config.mode_config[mode]) return; return lib.config.mode_config[mode][item]; }, coinCoeff:function(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; }, rank:function(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.contains(skills[i])){ name=lib.rank.a[0];break; } } } if(rank.s.contains(name)) return num?Math.round(8*(num-1)/8+1):'s'; if(rank.ap.contains(name)) return num?Math.round(7*(num-1)/8+1):'ap'; if(rank.a.contains(name)) return num?Math.round(6*(num-1)/8+1):'a'; if(rank.am.contains(name)) return num?Math.round(5*(num-1)/8+1):'am'; if(rank.bp.contains(name)) return num?Math.round(4*(num-1)/8+1):'bp'; if(rank.b.contains(name)) return num?Math.round(3*(num-1)/8+1):'b'; if(rank.bm.contains(name)) return num?Math.round(2*(num-1)/8+1):'bm'; if(rank.c.contains(name)) return num?Math.round(1*(num-1)/8+1):'c'; if(rank.d.contains(name)) return num?Math.round(0*(num-1)/8+1):'d'; if(lib.character[name]&&lib.character[name][4]){ if(lib.character[name][4].contains('boss')|| lib.character[name][4].contains('bossallowed')|| lib.character[name][4].contains('hiddenboss')){ return num?Math.round(9*(num-1)/8+1):'sp'; } } return num?Math.round(9*(num-1)/8+1):'x'; }, skillRank:function(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; }, targetsInfo:function(targets){ var info=[]; for(var i=0;i<targets.length;i++){ info.push(targets[i].dataset.position); } return info; }, infoTargets:function(info){ var targets=[]; for(var i=0;i<info.length;i++){ targets.push(game.playerMap[info[i]]); } return targets; }, cardInfo:function(card){ return [card.suit,card.number,card.name,card.nature]; }, cardsInfo:function(cards){ var info=[]; for(var i=0;i<cards.length;i++){ info.push(get.cardInfo(cards[i])); } return info; }, infoCard:function(info){ var card=ui.create.card(); if(info[0]){ card.init(info); } return card; }, infoCards:function(info){ var cards=[]; for(var i=0;i<info.length;i++){ cards.push(get.infoCard(info[i])); } return cards; }, cardInfoOL:function(card){ return '_noname_card:'+JSON.stringify([card.cardid,card.suit,card.number,card.name,card.nature]); }, infoCardOL:function(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; }, cardsInfoOL:function(cards){ var info=[]; for(var i=0;i<cards.length;i++){ info.push(get.cardInfoOL(cards[i])); } return info; }, infoCardsOL:function(info){ var cards=[]; for(var i=0;i<info.length;i++){ cards.push(get.infoCardOL(info[i])); } return cards; }, playerInfoOL:function(player){ return '_noname_player:'+player.playerid; }, infoPlayerOL:function(info){ if(!lib.playerOL) return info return lib.playerOL[info.slice(15)]||info; }, playersInfoOL:function(players){ var info=[]; for(var i=0;i<players.length;i++){ info.push(get.playerInfoOL(players[i])); } return info; }, infoPlayersOL:function(info){ var players=[]; for(var i=0;i<info.length;i++){ players.push(get.infoPlayerOL(info[i])); } return players; }, funcInfoOL:function(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 ''; }, infoFuncOL:function(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; }, eventInfoOL:function(item,level,nomore){ if(Object.prototype.toString.call(item)=='[object Object]'){ var item2={}; for(var i in item){ if(i=='_trigger'){ if(nomore===false) continue; else item2[i]=get.eventInfoOL(item[i],null,false); } else if(lib.element.event[i]||i=='content'||get.itemtype(item[i])=='event') continue; else item2[i]=get.stringifiedResult(item[i],null,false); } return '_noname_event:'+JSON.stringify(item2); } else{ return ''; } }, infoEventOL:function(item){ var evt; try{ evt=JSON.parse(item.slice(14)); for(var i in evt){ evt[i]=get.parsedResult(evt[i]); } for(var i in lib.element.event) evt[i]=lib.element.event[i]; } catch(e){ console.log(e); } return evt||item; }, stringifiedResult:function(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; } }, parsedResult:function(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; } }, verticalStr:function(str,sp){ if(typeof str!='string') return ''; return Array.from(str).filter(value=>value!='`').join(''); }, numStr:function(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(); }, rawName:function(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 rawName2:function(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; }, 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)}<span>${slimName.slice(prefix.length)} </span>`; return `${get.prefixSpan(prefix,str)}<span>${slimName.slice(prefix.length)}</span>`; } return slimName; }, /** * @param {string} prefix * @param {string} name * @returns {string} */ prefixSpan:(prefix,name)=>{ let color='#ffffff',nature=false; const map=lib.namePrefix.get(prefix),config=lib.config.buttoncharacter_prefix; if(config=='off') return ''; if(map){ if(map.getSpan) return map.getSpan(prefix,name); if(map.color) color=map.color; if(map.nature) nature=map.nature; if(map.showName) prefix=map.showName; } if(config=='simple') return `<span>${prefix}</span>` return `<span style="color: ${color};"${nature?(`data-nature="${nature}"`):''}>${prefix}</span>` }, slimName:function(str){ return get.verticalStr(get.slimNameHorizontal(str),true); }, time:function(){ 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; } }, utc:function(){ return (new Date()).getTime(); }, evtDistance:function(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); }, xyDistance:function(from,to){ return Math.sqrt((from[0]-to[0])*(from[0]-to[0])+(from[1]-to[1])*(from[1]-to[1])); }, itemtype:function(obj){ var i,j; if(typeof obj=='string'){ if(obj.length<=5){ var bool=true; for(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){ var isPlayers=true; for(i=0;i<obj.length;i++){ if(get.itemtype(obj[i])!='player') {isPlayers=false;break;} } if(isPlayers) return 'players'; var isCards=true; for(i=0;i<obj.length;i++){ if(get.itemtype(obj[i])!='card') {isCards=false;break;} } if(isCards) 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){ var isPosition=true; for(i=0;i<obj.length;i++){ if(typeof obj[i]!='number') {isPosition=false;break;} } if(isPosition) return 'divposition'; } } if(get.objtype(obj)=='div'){ if(obj.classList.contains('button')) return 'button'; if(obj.classList.contains('card')) return 'card'; if(obj.classList.contains('player')) return 'player'; if(obj.classList.contains('dialog')) return 'dialog'; } if(get.is.object(obj)){ if(obj.isMine==lib.element.event.isMine) return 'event'; } }, equipNum:function(card){ if(get.type(card)=='equip'){ return parseInt(get.subtype(card)[5]); } return 0; }, objtype:function(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'; }, type:function(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]) return; if(method=='trick'&&lib.card[name].type=='delay') return 'trick'; return lib.card[name].type; }, type2:function(card,player){ return get.type(card,'trick',player); }, subtype:function(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; return lib.card[name].subtype; }, equiptype:function(card,player){ var subtype=get.subtype(card,player); if(subtype.startsWith('equip')) return parseInt(subtype[5]); return 0; }, name:function(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; }, suit:function(card,player){ if(!card) return; if(Array.isArray(card)){ if(card.length==1) return get.suit(card[0],player); return 'none'; } else if(!card.hasOwnProperty('suit')&&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,card.suit,'suit',owner); } } if(lib.suits.contains(card.suit)) return card.suit; return 'none'; } }, color:function(card,player){ if(!card) return; if(Array.isArray(card)){ if(!card.length) return 'none'; const color=get.color(card[0],player); for(let i=1;i<card.length;i++){ if(get.color(card[i],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(let i in lib.color){ if(lib.color[i].includes(suit)) return i; } return 'none'; } }, number:function(card,player){ if(!card) return; //狗卡你是真敢出啊 var number=null; if(card.hasOwnProperty('number')){ 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 nature:function(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; }, //返回包含所有属性的数组 natureList:function(card,player){ if(!card) return []; if(get.itemtype(card)=='natures') return card.split(lib.natureSeparator); if(get.itemtype(card)=='nature') return [card]; var natures=get.nature.apply(this,arguments); if(typeof natures!='string') return []; return natures.split(lib.natureSeparator); }, cards:function(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; }, judge:function(card){ if(card.viewAs) return lib.card[card.viewAs].judge; return get.info(card).judge; }, judge2:function(card){ if(card.viewAs) return lib.card[card.viewAs].judge2; return get.info(card).judge2; }, distance:function(from,to,method){ if(from==to) return 0; if(!game.players.contains(from)&&!game.dead.contains(from)) return Infinity; if(!game.players.contains(to)&&!game.dead.contains(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.contains(card); }),equips2=to.getCards('e',function(card){ return !ui.selected.cards||!ui.selected.cards.contains(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<equips2.length;i++){ let info=get.info(equips2[i]).distance; if(!info) continue; if(info.attaclTo){ m+=info.attaclTo; } } return n; } else if(method=='unchecked') return n; return Math.max(1,n); }, info:function(item,player){ if(typeof item=='string'){ return lib.skill[item]; } if(typeof item=='object'){ var name=item.name; if(player!==false) name=get.name(item,player); return lib.card[name]; } }, select:function(select){ if(typeof select=='number') return [select,select]; if(get.itemtype(select)=='select') return select; if(typeof select=='function') return get.select(select()); return [1,1] }, card:function(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; }, player:function(){ return _status.event.player; }, players:function(sort,dead,out){ var players=game.players.slice(0); if(sort!=false){ if(typeof sort=='function'){ players.sort(sort); } else{ if(get.itemtype(sort)!='player') lib.tempSortSeat=_status.event.player; else lib.tempSortSeat=sort; players.sort(lib.sort.seat); delete lib.tempSortSeat; } } if(dead) players=players.concat(game.dead); if(!out){ for(var i=0;i<players.length;i++){ if(players[i].isOut()) players.splice(i--,1); } } return players; }, position:function(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; }, skillTranslation:function(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); }, skillInfoTranslation:function(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,'<span class="yellowtext">锁定技</span>'). // replace(/限定技/g,'<span class="yellowtext">限定技</span>'). // replace(/觉醒技/g,'<span class="greentext">觉醒技</span>'). // replace(/主将技/g,'<span class="bluetext">主将技</span>'). // replace(/副将技/g,'<span class="bluetext">副将技</span>'). // replace(/阵法技/g,'<span class="bluetext">阵法技</span>'). // replace(/主公技/g,'<span class="firetext">主公技</span>'); }, translation:function(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].contains(str.cardid)){ tagstr+=lib.translate[i+'_tag']; } } if(tagstr){ str2+='·'+tagstr; } } if(str.suit&&str.number){ var cardnum=str.number||''; if([1,11,12,13].contains(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(str.suit)+cardnum+'】'; // var len=str2.length-1; // str2=str2.slice(0,len)+'<span style="letter-spacing: -2px">'+str2[len]+'·</span>'+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 ''; }, strNumber:function(num){ switch(num){ case 1:return 'A'; case 11:return 'J'; case 12:return 'Q'; case 13:return 'K'; default:return num.toString(); } }, cnNumber:function(num,two){ if(num==Infinity) return '∞'; if(isNaN(num)) return ''; if(typeof num!='number') return num; if(num<0||num>99) return num; if(num<=10){ switch(num){ case 0:return '〇'; case 1:return '一'; case 2:return two?'二':'两'; case 3:return '三'; case 4:return '四'; case 5:return '五'; case 6:return '六'; case 7:return '七'; case 8:return '八'; case 9:return '九'; case 10:return '十'; } } if(num<20){ return '十'+get.cnNumber(num-10,true); } var x=Math.floor(num/10); return get.cnNumber(x,true)+'十'+(num>10*x?get.cnNumber(num-10*x,true):''); }, selectableButtons:function(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; }, selectableCards:function(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; }, skills:function(){ 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; }, gainableSkills:function(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].contains('boss')) continue; if(lib.character[i][4].contains('hiddenboss')) continue; if(lib.character[i][4].contains('minskin')) continue; if(lib.character[i][4].contains('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; }, gainableSkillsName:function(name, func){ var list=[]; if(name&&lib.character[name]){ if(lib.character[name][4]){ if(lib.character[name][4].contains('boss')) return list; if(lib.character[name][4].contains('hiddenboss')) return list; if(lib.character[name][4].contains('minskin')) return list; if(lib.character[name][4].contains('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; }, gainableCharacters:function(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; }, selectableTargets:function(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; }, filter:function(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(filter.hasOwnProperty(j)){ if(get.itemtype(arguments[i])=='card'){ if(j=='name'){ if(Array.isArray(filter[j])){ if(filter[j].contains(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].contains(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].contains(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].contains(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].contains(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].contains(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].contains(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; }, cardCount:function(card,player){ var num; 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(player==undefined) player=_status.event.player; if(typeof card=='object'){ card=card.name; } num=player.getStat('card')[card]; if(num==undefined) return 0; return num; }, skillCount:function(skill,player){ if(player==undefined) player=_status.event.player; var num=player.getStat('skill')[skill]; if(num==undefined) return 0; return num; }, owner:function(card,method){ var list=game.players.concat(game.dead); for(var i=0;i<list.length;i++){ if(list[i].getCards('hejsx').contains(card)) return list[i]; if(list[i].judging[0]==card&&method!='judge') return list[i]; } //for(var i=0;i<game.players.length;i++){ // if(game.players[i].using&&game.players[i].using.contains(card)) return game.players[i]; //} }, noSelected:function(){ return (ui.selected.buttons.length+ui.selected.cards.length+ui.selected.targets.length==0) }, population:function(identity){ if(identity==undefined) return game.players.length+game.dead.length; var i; var num=0; for(i=0;i<game.players.length;i++){ if(game.players[i].identity==identity) num++; } return num; }, totalPopulation:function(identity){ if(identity==undefined) return game.players.length+game.dead.length; var i,players=game.players.concat(game.dead); var num=0; for(i=0;i<players.length;i++){ if(players[i].identity==identity) num++; } return num; }, cardtag:function(item,tag){ if(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].contains(item.cardid)){ return true; } if(item.cardtags&&item.cardtags.contains(tag)) return true; return false; }, tag:function(item,tag,item2,bool){ var result; if(get.info(item)&&get.info(item).ai&&get.info(item).ai.tag){ result=get.info(item,bool).ai.tag[tag]; } if(typeof result=='function') return result(item,item2); return result; }, sortCard:function(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; }, difficulty:function(){ switch(get.config('difficulty')){ case 'easy':return 1; case 'normal':return 2; case 'hard':return 3; default: return 1; } }, cardPile:function(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'].contains(create)){ return game.createCard(name); } return null; }, cardPile2:function(name){ return get.cardPile(name,'cardPile'); }, discardPile:function(name){ return get.cardPile(name,'discardPile'); }, aiStrategy:function(){ 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; } }, skillintro:function(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+='<div class="skill" style="'+opacity+ '">【'+skilltrans+'】</div><div style="'+opacity+'">'+ get.skillInfoTranslation(skills[i])+'</div><div style="display:block;height:10px"></div>'; } } return str; }, intro:function(name){ var info=lib.character[name]; var str='性别:'+get.translation(info[0])+'<br/>'; str+='势力:'+get.translation(info[1])+'<br/>'; str+='体力:'+get.translation(info[2])+'<br/>'; 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; }, storageintro:function(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; } } }, nodeintro:function(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; 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('<div class="text center" style="padding-bottom:5px">'+content+'</div>'); } 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('<div class="text center">明置的手牌</div>'); uiintro.addSmall(shownHs); if(allShown){ var hs=node.getCards('h'); hs.removeArray(shownHs) if(hs.length){ uiintro.add('<div class="text center">其他手牌</div>'); uiintro.addSmall(hs); } } } else if(allShown){ var hs=node.getCards('h'); if(hs.length){ uiintro.add('<div class="text center">手牌</div>'); 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.contains(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']){ translation=lib.translate[skills[i]+'_ab']||get.translation(skills[i]).slice(0,2); if(node.forbiddenSkills[skills[i]]){ var forbidstr='<div style="opacity:0.5"><div class="skill">【'+translation+'】</div><div>'; if(node.forbiddenSkills[skills[i]].length){ forbidstr+='(与'+get.translation(node.forbiddenSkills[skills[i]])+'冲突)<br>'; } else{ forbidstr+='(双将禁用)<br>'; } forbidstr+=get.skillInfoTranslation(skills[i],node)+'</div></div>' uiintro.add(forbidstr); } else if(!skills2.contains(skills[i])){ if(lib.skill[skills[i]].preHidden&&get.mode()=='guozhan'){ uiintro.add('<div><div class="skill" style="opacity:0.5">【'+translation+'】</div><div><span style="opacity:0.5">'+get.skillInfoTranslation(skills[i],node)+'</span><br><div class="underlinenode on gray" style="position:relative;padding-left:0;padding-top:7px">预亮技能</div></div></div>'); var underlinenode=uiintro.content.lastChild.querySelector('.underlinenode'); if(_status.prehidden_skills.contains(skills[i])){ underlinenode.classList.remove('on'); } underlinenode.link=skills[i]; underlinenode.listen(ui.click.hiddenskill); } else uiintro.add('<div style="opacity:0.5"><div class="skill">【'+translation+'】</div><div>'+get.skillInfoTranslation(skills[i],node)+'</div></div>'); } else if(lib.skill[skills[i]].temp||!node.skills.contains(skills[i])||lib.skill[skills[i]].thundertext){ if(lib.skill[skills[i]].frequent||lib.skill[skills[i]].subfrequent){ uiintro.add('<div><div class="skill thundertext thunderauto">【'+translation+'】</div><div class="thundertext thunderauto">'+get.skillInfoTranslation(skills[i],node)+'<br><div class="underlinenode on gray" style="position:relative;padding-left:0;padding-top:7px">自动发动</div></div></div>'); var underlinenode=uiintro.content.lastChild.querySelector('.underlinenode'); if(lib.skill[skills[i]].frequent){ if(lib.config.autoskilllist.contains(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.contains(skills[i]+'_'+lib.skill[skills[i]].subfrequent[j])){ underlinenode.classList.remove('on'); } } } if(lib.config.autoskilllist.contains(skills[i])){ underlinenode.classList.remove('on'); } underlinenode.link=skills[i]; underlinenode.listen(ui.click.autoskill2); } else{ uiintro.add('<div><div class="skill thundertext thunderauto">【'+translation+'】</div><div class="thundertext thunderauto">'+get.skillInfoTranslation(skills[i],node)+'</div></div>'); } } else if(lib.skill[skills[i]].frequent||lib.skill[skills[i]].subfrequent){ uiintro.add('<div><div class="skill">【'+translation+'】</div><div>'+get.skillInfoTranslation(skills[i],node)+'<br><div class="underlinenode on gray" style="position:relative;padding-left:0;padding-top:7px">自动发动</div></div></div>'); var underlinenode=uiintro.content.lastChild.querySelector('.underlinenode'); if(lib.skill[skills[i]].frequent){ if(lib.config.autoskilllist.contains(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.contains(skills[i]+'_'+lib.skill[skills[i]].subfrequent[j])){ underlinenode.classList.remove('on'); } } } if(lib.config.autoskilllist.contains(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('<div><div class="skill">【'+translation+'】</div><div>'+get.skillInfoTranslation(skills[i],node)+'<br><div class="menubutton skillbutton" style="position:relative;margin-top:5px">点击发动</div></div></div>').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 if(lib.skill[skills[i]].nobracket){ uiintro.add('<div><div class="skilln">'+get.translation(skills[i])+'</div><div>'+get.skillInfoTranslation(skills[i],node)+'</div></div>'); } else{ uiintro.add('<div><div class="skill">【'+translation+'】</div><div>'+get.skillInfoTranslation(skills[i],node)+'</div></div>'); } if(lib.translate[skills[i]+'_append']){ uiintro._place_text=uiintro.add('<div class="text">'+lib.translate[skills[i]+'_append']+'</div>') } } } // 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).contains(i)==false&&!intro.show) continue; // var name=intro.name?intro.name:get.translation(i); // if(typeof name=='function'){ // name=name(storage[i],node); // } // translation='<div><div class="skill">『'+name.slice(0,2)+'』</div><div>'; // var stint=get.storageintro(intro.content,storage[i],node,null,i); // if(stint){ // translation+=stint+'</div></div>'; // 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'); td.innerHTML=`${node.countCards('h')}/${node.getHandcardLimit()}`; 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('<div><div class="skill">'+es[i].outerHTML+'</div><div>'+cardinfo.cardPrompt(es[i])+'</div></div>'); else uiintro.add('<div><div class="skill">'+es[i].outerHTML+'</div><div>'+lib.translate[es[i].name+'_info']+'</div></div>'); uiintro.content.lastChild.querySelector('.skill>.card').style.transform=''; if(lib.translate[es[i].name+'_append']){ uiintro.add('<div class="text">'+lib.translate[es[i].name+'_append']+'</div>'); } } 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('<div><div class="skill">'+js[i].outerHTML+'</div><div>'+lib.translate[js[i].viewAs]+':'+lib.translate[js[i].viewAs+'_info']+'</div></div>'); } else{ uiintro.add('<div><div class="skill">'+js[i].outerHTML+'</div><div>'+lib.translate[js[i].name+'_info']+'</div></div>'); } 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='<span>'+get.translation(listi[i])+'</span>'; 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='<span>'+get.translation(listi[i])+'</span>'; 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.contains(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.contains(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('<div class="text center">更改皮肤</div>'); } 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].contains('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].contains('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].contains('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('<div class="text" style="display:inline">'+stint+'</div>'); if(!stint.startsWith('<div class="skill"')){ uiintro._place_text=placetext; } // if(stint.length<=100){ // uiintro.add('<div class="text center">'+stint+'</div>'); // } // else{ // uiintro.add('<div class="text">'+stint+'</div>'); // } } } else{ var stint=get.storageintro(info.content,player.storage[node.skill],player,uiintro,node.skill); if(stint){ if(stint[0]=='@'){ uiintro.add('<div class="caption">'+stint.slice(1)+'</div>'); } else{ var placetext=uiintro.add('<div class="text" style="display:inline">'+stint+'</div>'); if(!stint.startsWith('<div class="skill"')){ uiintro._place_text=placetext; } } // else if(stint.length<=100){ // uiintro.add('<div class="text center">'+stint+'</div>'); // } // else{ // uiintro.add('<div class="text">'+stint+'</div>'); // } } } 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('<div class="text" style="display:inline">'+item[1]+'</div>'); } } 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('<div class="text center">('+get.translation(get.translation(node))+')</div>'); // uiintro.add(get.translation(node.viewAs)+'<br><div class="text center" style="padding-top:5px;">('+get.translation(node)+')</div>'); 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.contains(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.contains(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.contains(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(get.subtype(name)=='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('<div class="text center">攻击范围:'+(-dist.attackFrom+1)+'</div>'); } } if(!added){ uiintro.add('<div class="text center">攻击范围:1</div>'); } } else if(get.subtype(name)){ uiintro.add('<div class="text center">'+get.translation(get.subtype(name))+'</div>'); } else if(lib.card[name]&&lib.card[name].addinfomenu){ uiintro.add('<div class="text center">'+lib.card[name].addinfomenu+'</div>'); } else if(lib.card[name]&&lib.card[name].derivation){ if(typeof lib.card[name].derivation=='string'){ uiintro.add('<div class="text center">来源:'+get.translation(lib.card[name].derivation)+'</div>'); } else if(lib.card[name].derivationpack){ uiintro.add('<div class="text center">来源:'+get.translation(lib.card[name].derivationpack+'_card_config')+'包</div>'); } } else{ if(lib.card[name].unique){ uiintro.add('<div class="text center">特殊'+get.translation(lib.card[name].type)+'牌</div>'); } else{ if(lib.card[name].type&&lib.translate[lib.card[name].type]) uiintro.add('<div class="text center">'+get.translation(lib.card[name].type)+'牌</div>'); } } if(lib.card[name].unique&&lib.card[name].type=='equip'){ if(lib.cardPile.guozhan&&lib.cardPack.guozhan.contains(name)){ uiintro.add('<div class="text center">专属装备</div>').style.marginTop='-5px'; } else{ uiintro.add('<div class="text center">特殊装备</div>').style.marginTop='-5px'; } } } if(lib.card[name].cardPrompt){ var str=lib.card[name].cardPrompt(node.link||node),placetext=uiintro.add('<div class="text" style="display:inline">'+str+'</div>'); if(!str.startsWith('<div class="skill"')){ uiintro._place_text=placetext; } } else if(lib.translate[name+'_info']){ var placetext=uiintro.add('<div class="text" style="display:inline">'+lib.translate[name+'_info']+'</div>'); if(!lib.translate[name+'_info'].startsWith('<div class="skill"')){ uiintro._place_text=placetext; } } if(get.is.yingbianConditional(node.link||node)){ const yingbianEffects=get.yingbianEffects(node.link||node); if(!yingbianEffects.length){ const defaultYingbianEffect=get.defaultYingbianEffect(node.link||node); if(lib.yingbian.prompt.has(defaultYingbianEffect)) yingbianEffects.push(defaultYingbianEffect); } if(yingbianEffects.length) uiintro.add(`<div class="text" style="font-family: yuanli">应变:${yingbianEffects.map(value=>lib.yingbian.prompt.get(value)).join(';')}</div>`); } if(lib.translate[name+'_append']){ uiintro.add('<div class="text" style="display:inline">'+lib.translate[name+'_append']+'</div>'); } } 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.contains(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.contains(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.contains(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.contains(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']){ translation=lib.translate[skills[i]+'_ab']||get.translation(skills[i]).slice(0,2); if(lib.skill[skills[i]]&&lib.skill[skills[i]].nobracket){ uiintro.add('<div><div class="skilln">'+get.translation(skills[i])+'</div><div>'+get.skillInfoTranslation(skills[i])+'</div></div>'); } else{ uiintro.add('<div><div class="skill">【'+translation+'】</div><div>'+get.skillInfoTranslation(skills[i])+'</div></div>'); } if(lib.translate[skills[i]+'_append']){ uiintro._place_text=uiintro.add('<div class="text">'+lib.translate[skills[i]+'_append']+'</div>') } } } 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.contains(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('<div class="text center">更改皮肤</div>'); } 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].contains('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].contains('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('<div class="text center" style="padding-bottom:5px">'+lib.translate['_'+career+'_skill_info']+'</div>'); } else if(node.classList.contains('skillbar')){ if(node==ui.friendBar){ uiintro.add('友方怒气值'); uiintro.add('<div class="text center" style="padding-bottom:5px">'+_status.friendRage+'/100</div>'); } else if(node==ui.enemyBar){ uiintro.add('敌方怒气值'); uiintro.add('<div class="text center" style="padding-bottom:5px">'+_status.enemyRage+'/100</div>'); } } else if(node.parentNode==ui.historybar){ if(node.dead){ if(!node.source||node.source==node.player){ uiintro.add('<div class="text center">'+get.translation(node.player)+'阵亡</div>'); uiintro.addSmall([node.player]); } else{ uiintro.add('<div class="text center">'+get.translation(node.player)+'被'+get.translation(node.source)+'杀害</div>'); uiintro.addSmall([node.source]); } } if(node.skill){ uiintro.add('<div class="text center">'+get.translation(node.skill,'skill')+'</div>'); uiintro._place_text=uiintro.add('<div class="text" style="display:inline">'+get.translation(node.skill,'info')+'</div>'); } if(node.targets&&get.itemtype(node.targets)=='players'){ uiintro.add('<div class="text center">目标</div>'); uiintro.addSmall(node.targets); } if(node.players&&node.players.length>1){ uiintro.add('<div class="text center">使用者</div>'); uiintro.addSmall(node.players); } if(node.cards&&node.cards.length){ uiintro.add('<div class="text center">卡牌</div>'); 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; }, linkintro:function(dialog,content,player){ dialog.content.firstChild.remove(); dialog.add('<div class="text center">已横置</div>'); 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); } }, groups:function(){ return ['wei','shu','wu','qun','jin','western','key']; }, types:function(){ var types=[]; for(var i in lib.card){ if(lib.card[i].mode&&lib.card[i].mode.contains(lib.config.mode)==false) continue; if(lib.card[i].forbid&&lib.card[i].forbid.contains(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; }, links:function(buttons){ var links=[]; for(var i=0;i<buttons.length;i++){ if(buttons[i].link!=undefined) links.push(buttons[i].link); } return links; }, threaten:function(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; }, condition:function(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; }, attitude:function(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; }, sgnAttitude:function(){ return get.sgn(get.attitude.apply(this,arguments)); }, useful_raw:function(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; }, useful:function(card,player){ if(_status.event.useCache){ return game.callFuncUseStepCache("get.useful_raw",get.useful_raw,[card,player]); } return get.useful_raw(card,player); }, unuseful:function(card){ return -get.useful(card); }, unuseful2:function(card){ return 10-get.useful(card); }, unuseful3:function(card){ if(card.name=='du') return 20; return 10-get.useful(card); }, value:function(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.contains(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; }, equipResult:function(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&¤t!=card){ value2=get.equipValue(current,target); if(value2>0&&!target.needsToDiscard()&&!get.tag(card,'valueswap')){ return 0; } } } return Math.max(0,value1-value2)/5; }, equipValue:function(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; }, equipValueNumber:function(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; }, disvalue:function(card,player){ return -get.value(card,player); }, disvalue2:function(card,player){ return -get.value(card,player,'raw'); }, skillthreaten:function(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; }, order:function(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; }, result:function(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; }, effect_use:function(target,card,player,player2,isLink){ var event=_status.event; var eventskill=null; if(player==undefined) player=_status.event.player; 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.countPlayer(function(current){ if(current!=target&¤t.isLinked()) final+=get.effect(current,card,player,player2,true); }); } else if(info.ai.canLink(player,target,card)){ game.countPlayer(function(current){ if(current!=target&¤t.isLinked()) final+=get.effect(current,card,player,player2,true); }); } } return final; }, effect:function(target,card,player,player2,isLink){ var event=_status.event; var eventskill=null; if(player==undefined) player=_status.event.player; 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.countPlayer(function(current){ if(current!=target&¤t.isLinked()) final+=get.effect(current,card,player,player2,true); }); } else if(info.ai.canLink(player,target,card)){ game.countPlayer(function(current){ if(current!=target&¤t.isLinked()) final+=get.effect(current,card,player,player2,true); }); } } return final; }, damageEffect:function(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; }, recoverEffect:function(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); }, buttonValue:function(button){ var card=button.link; var player=get.owner(card); if(!player) player=_status.event.player; if(player.getCards('j').contains(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').contains(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; } }, attitude2:function(to){ return get.attitude(_status.event.player,to); }, }; const ai={ basic:{ chooseButton:function(check){ var event=_status.event; var i,j,range,buttons,buttons2; var ok=false,forced=event.forced; var iwhile=100; while(iwhile--){ range=get.select(event.selectButton); if(ui.selected.buttons.length>=range[0]){ ok=true; } if(range[1]<=-1){ j=0; for(i=0;i<ui.selected.buttons.length;i++){ j+=check(ui.selected.buttons[i]); } return (j>0); } buttons=get.selectableButtons(); if(buttons.length==0){ return ok; } buttons2=buttons.slice(0); var ix=0; var checkix=check(buttons[0],buttons2); for(i=1;i<buttons.length;i++){ var checkixtmp=check(buttons[i],buttons2); if(checkixtmp>checkix){ ix=i; checkix=checkixtmp; } } // buttons.sort(function(a,b){ // return check(b,buttons2)-check(a,buttons2); // }); if(check(buttons[ix])<=0){ if(!forced||ok){ return ok; } } buttons[ix].classList.add('selected'); ui.selected.buttons.add(buttons[ix]); game.check(); if(ui.selected.buttons.length>=range[0]){ ok=true; } if(ui.selected.buttons.length==range[1]){ return true; } } }, chooseCard:function(check){ var event=_status.event; if(event.filterCard==undefined) return (check()>0); var i,j,range,cards,cards2,skills,check,effect; var ok=false,forced=event.forced; var iwhile=100; while(iwhile--){ range=get.select(event.selectCard); if(ui.selected.cards.length>=range[0]){ ok=true; } if(range[1]<=-1){ if(ui.selected.cards.length==0) return true; j=0; for(i=0;i<ui.selected.cards.length;i++){ effect=check(ui.selected.cards[i]); if(effect<0) j-=Math.sqrt(-effect); else j+=Math.sqrt(effect); } return (j>0); } cards=get.selectableCards(); if(!_status.event.player._noSkill){ cards=cards.concat(get.skills()); } if(cards.length==0){ return ok; } cards2=cards.slice(0); // cards.sort(function(a,b){ // return (check(b,cards2)-check(a,cards2)); // }); var ix=0; var checkix=check(cards[0],cards2); for(i=1;i<cards.length;i++){ var checkixtmp=check(cards[i],cards2); if(checkixtmp>checkix){ ix=i; checkix=checkixtmp; } } if(check(cards[ix])<=0){ if(!forced||ok){ return ok; } } if(typeof cards[ix]=='string'){ ui.click.skill(cards[ix]); var info=get.info(event.skill); if(info.filterCard){ check=info.check||get.unuseful2; return (ai.basic.chooseCard(check)); } else{ return true; } } else{ cards[ix].classList.add('selected'); ui.selected.cards.add(cards[ix]); game.check(); if(ui.selected.cards.length>=range[0]){ ok=true; } if(ui.selected.cards.length==range[1]){ return true; } } } }, chooseTarget:function(check){ var event=_status.event; if(event.filterTarget==undefined) return (check()>0); var i,j,range,targets,targets2,effect; var ok=false,forced=event.forced; var iwhile=100; while(iwhile--){ range=get.select(event.selectTarget); if(ui.selected.targets.length>=range[0]){ ok=true; } if(range[1]<=-1){ j=0; for(i=0;i<ui.selected.targets.length;i++){ effect=check(ui.selected.targets[i]); if(effect<0) j-=Math.sqrt(-effect); else j+=Math.sqrt(effect); } return (j>0); } else if(range[1]==0){ return check()>0 } targets=get.selectableTargets(); if(targets.length==0){ return range[0]==0||ok; } targets2=targets.slice(0); // targets.sort(function(a,b){ // return check(b)-check(a); // }); var ix=0; var checkix=check(targets[0],targets2); for(i=1;i<targets.length;i++){ var checkixtmp=check(targets[i],targets2); if(checkixtmp>checkix){ ix=i; checkix=checkixtmp; } } if(check(targets[ix])<=0){ if(!forced||ok){ return ok; } } targets[ix].classList.add('selected'); ui.selected.targets.add(targets[ix]); game.check(); if(ui.selected.targets.length>=range[0]){ ok=true; } if(ui.selected.targets.length==range[1]){ return true; } } } }, get:get }; if('__core-js_shared__' in window) lib.init.init(); else{ const coreJSBundle=document.createElement('script'); coreJSBundle.onerror=coreJSBundle.onload=lib.init.init; coreJSBundle.src=`${lib.assetURL}game/core-js-bundle.js`; document.head.appendChild(coreJSBundle); } }