diff --git a/.eslintrc.json b/.eslintrc.json index 8d79549ec..88229aedd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,5 +1,5 @@ { - "extends": "chrome 46", + "extends": "chrome 46", "env": { "browser": true, "node": true, diff --git a/audio/die/laimin.mp3 b/audio/die/laimin.mp3 new file mode 100644 index 000000000..151b374fd Binary files /dev/null and b/audio/die/laimin.mp3 differ diff --git a/audio/die/ol_zhangzhang.mp3 b/audio/die/ol_zhangzhang.mp3 new file mode 100644 index 000000000..03d811cd2 Binary files /dev/null and b/audio/die/ol_zhangzhang.mp3 differ diff --git a/audio/die/sb_xiaoqiao.mp3 b/audio/die/sb_xiaoqiao.mp3 new file mode 100644 index 000000000..8aad99390 Binary files /dev/null and b/audio/die/sb_xiaoqiao.mp3 differ diff --git a/audio/die/sb_yl_luzhi.mp3 b/audio/die/sb_yl_luzhi.mp3 new file mode 100644 index 000000000..39d41ae09 Binary files /dev/null and b/audio/die/sb_yl_luzhi.mp3 differ diff --git a/audio/die/zhangyan.mp3 b/audio/die/zhangyan.mp3 new file mode 100644 index 000000000..1bbfe249d Binary files /dev/null and b/audio/die/zhangyan.mp3 differ diff --git a/audio/skill/laishou1.mp3 b/audio/skill/laishou1.mp3 new file mode 100644 index 000000000..36cca78a1 Binary files /dev/null and b/audio/skill/laishou1.mp3 differ diff --git a/audio/skill/laishou2.mp3 b/audio/skill/laishou2.mp3 new file mode 100644 index 000000000..ded0373cf Binary files /dev/null and b/audio/skill/laishou2.mp3 differ diff --git a/audio/skill/laishou3.mp3 b/audio/skill/laishou3.mp3 new file mode 100644 index 000000000..dfaf670f3 Binary files /dev/null and b/audio/skill/laishou3.mp3 differ diff --git a/audio/skill/luanqun1.mp3 b/audio/skill/luanqun1.mp3 new file mode 100644 index 000000000..5de13336b Binary files /dev/null and b/audio/skill/luanqun1.mp3 differ diff --git a/audio/skill/luanqun2.mp3 b/audio/skill/luanqun2.mp3 new file mode 100644 index 000000000..f30474e6c Binary files /dev/null and b/audio/skill/luanqun2.mp3 differ diff --git a/audio/skill/nzry_mingren_1_sb_yl_luzhi1.mp3 b/audio/skill/nzry_mingren_1_sb_yl_luzhi1.mp3 new file mode 100644 index 000000000..9ac05aece Binary files /dev/null and b/audio/skill/nzry_mingren_1_sb_yl_luzhi1.mp3 differ diff --git a/audio/skill/nzry_mingren_1_sb_yl_luzhi2.mp3 b/audio/skill/nzry_mingren_1_sb_yl_luzhi2.mp3 new file mode 100644 index 000000000..feafead5b Binary files /dev/null and b/audio/skill/nzry_mingren_1_sb_yl_luzhi2.mp3 differ diff --git a/audio/skill/olguzheng1.mp3 b/audio/skill/olguzheng1.mp3 new file mode 100644 index 000000000..ad52616e1 Binary files /dev/null and b/audio/skill/olguzheng1.mp3 differ diff --git a/audio/skill/olguzheng2.mp3 b/audio/skill/olguzheng2.mp3 new file mode 100644 index 000000000..8e0348ae3 Binary files /dev/null and b/audio/skill/olguzheng2.mp3 differ diff --git a/audio/skill/ollangdao1.mp3 b/audio/skill/ollangdao1.mp3 new file mode 100644 index 000000000..5156a993f Binary files /dev/null and b/audio/skill/ollangdao1.mp3 differ diff --git a/audio/skill/ollangdao2.mp3 b/audio/skill/ollangdao2.mp3 new file mode 100644 index 000000000..4854177ad Binary files /dev/null and b/audio/skill/ollangdao2.mp3 differ diff --git a/audio/skill/olsuji1.mp3 b/audio/skill/olsuji1.mp3 new file mode 100644 index 000000000..1958d30e8 Binary files /dev/null and b/audio/skill/olsuji1.mp3 differ diff --git a/audio/skill/olsuji2.mp3 b/audio/skill/olsuji2.mp3 new file mode 100644 index 000000000..f8b108f08 Binary files /dev/null and b/audio/skill/olsuji2.mp3 differ diff --git a/audio/skill/olzhijian1.mp3 b/audio/skill/olzhijian1.mp3 new file mode 100644 index 000000000..e32c47e09 Binary files /dev/null and b/audio/skill/olzhijian1.mp3 differ diff --git a/audio/skill/olzhijian2.mp3 b/audio/skill/olzhijian2.mp3 new file mode 100644 index 000000000..5b0619a60 Binary files /dev/null and b/audio/skill/olzhijian2.mp3 differ diff --git a/audio/skill/rejizhi_lukang1.mp3 b/audio/skill/rejizhi_lukang1.mp3 index 932a10e21..d9105b8a8 100644 Binary files a/audio/skill/rejizhi_lukang1.mp3 and b/audio/skill/rejizhi_lukang1.mp3 differ diff --git a/audio/skill/rejizhi_lukang2.mp3 b/audio/skill/rejizhi_lukang2.mp3 index 932a10e21..d9105b8a8 100644 Binary files a/audio/skill/rejizhi_lukang2.mp3 and b/audio/skill/rejizhi_lukang2.mp3 differ diff --git a/audio/skill/sbtianxiang1.mp3 b/audio/skill/sbtianxiang1.mp3 new file mode 100644 index 000000000..b7682eb62 Binary files /dev/null and b/audio/skill/sbtianxiang1.mp3 differ diff --git a/audio/skill/sbtianxiang2.mp3 b/audio/skill/sbtianxiang2.mp3 new file mode 100644 index 000000000..5dc838f2e Binary files /dev/null and b/audio/skill/sbtianxiang2.mp3 differ diff --git a/audio/skill/sbzhenliang1.mp3 b/audio/skill/sbzhenliang1.mp3 new file mode 100644 index 000000000..c399afffa Binary files /dev/null and b/audio/skill/sbzhenliang1.mp3 differ diff --git a/audio/skill/sbzhenliang2.mp3 b/audio/skill/sbzhenliang2.mp3 new file mode 100644 index 000000000..459a227ae Binary files /dev/null and b/audio/skill/sbzhenliang2.mp3 differ diff --git a/audio/skill/zhengnan2.mp3 b/audio/skill/zhengnan2.mp3 index a73880663..9d6c1e4a6 100755 Binary files a/audio/skill/zhengnan2.mp3 and b/audio/skill/zhengnan2.mp3 differ diff --git a/card/extra.js b/card/extra.js index 80ad18299..94869ef17 100644 --- a/card/extra.js +++ b/card/extra.js @@ -203,7 +203,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ player.chooseToDiscard({suit:get.suit(event.card2)},function(card){ var evt=_status.event.getParent(); if(get.damageEffect(evt.target,evt.player,evt.player,'fire')>0){ - return 7-get.value(card,evt.player); + return 6.2+Math.min(4,evt.player.hp)-get.value(card,evt.player); } return -1; }).set('prompt',false); @@ -225,8 +225,10 @@ game.import('card',function(lib,game,ui,get,ai,_status){ value:[3,1], useful:1, }, - wuxie:function(target,card,player,current,state){ - if(get.attitude(current,player)>=0&&state>0) return false; + wuxie:function(target,card,player,viewer,state){ + let att=get.attitude(viewer,target), eff=get.effect(target,card,player,target); + if(status*get.attitude(viewer,player)>0&&!player.isMad() || status*eff*att>=0) return 0; + if(get.attitude(viewer,player)>=0 || _status.event.getRand('huogong_wuxie')*4>player.countCards('h')) return 0; }, result:{ player:function(player){ diff --git a/card/huanlekapai.js b/card/huanlekapai.js index f2fc69996..20f1f8bd3 100644 --- a/card/huanlekapai.js +++ b/card/huanlekapai.js @@ -187,40 +187,40 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, equipSkill:true, direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('xuelunyang'),function(card,player,target){ - var names=[]; - if(target.name&&!target.isUnseen(0)) names.add(target.name); - if(target.name1&&!target.isUnseen(0)) names.add(target.name1); - if(target.name2&&!target.isUnseen(1)) names.add(target.name2); - var pss=player.getSkills(); - for(var i=0;i0) return 0; if(!ui.selected.cards.length) return 1; return 0; }, ai2:function(target){ + if (target.hasSkillTag("usedu")) return get.attitude(_status.event.player,target)-0.01; return -get.attitude(_status.event.player,target)+0.01; }, }); diff --git a/card/yunchou.js b/card/yunchou.js index ca76a5e3c..3ed73a7e0 100644 --- a/card/yunchou.js +++ b/card/yunchou.js @@ -268,7 +268,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ return target.countCards('h')>0&&game.hasPlayer(function(current){ return target.canCompare(current); }); - return ui.selected.targets[0].canCompare(target); + //return ui.selected.targets[0].canCompare(target); }, filterAddedTarget:function(card,player,target,preTarget){ return target!=player&&preTarget.canCompare(target); diff --git a/character/clan.js b/character/clan.js index 2ba7634dd..31622434f 100644 --- a/character/clan.js +++ b/character/clan.js @@ -188,6 +188,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //族王浑 clanfuxun:{ + mod:{ + aiOrder:function(player,card,num){ + if(player.isPhaseUsing()&&get.type(card)=='equip'&&get.equipValue(card,player)>0) return num+3; + }, + }, + locked:false, audio:2, enable:'phaseUse', usable:1, @@ -206,6 +212,27 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(!ui.selected.cards.length) return target.countGainableCards(player,'h')>0; return true; }, + check:function(card){ + var player=_status.event.player; + var evtx=_status.event.getParent('phaseUse'); + var targets=game.filterPlayer(target=>target!=player&&lib.skill.clanfuxun.ai.result.target(player,target)!=0); + targets.sort((a,b)=>Math.abs(lib.skill.clanfuxun.ai.result.target(player,b))-Math.abs(lib.skill.clanfuxun.ai.result.target(player,a))); + if(evtx&&targets.length){ + var target=targets[0]; + if(!target.hasHistory('lose',evt=>{ + return evt.getParent(3).name!='clanfuxun'&&evt.getParent('phaseUse')==evtx&&evt.cards2.length; + })&&!target.hasHistory('gain',evt=>{ + return evt.getParent().name!='clanfuxun'&&evt.getParent('phaseUse')==evtx&&evt.cards.length; + })&&Math.abs(player.countCards('h')-target.countCards('h'))==2){ + if(player.countCards('h')>target.countCards('h')) return 1/(get.value(card)||0.5); + return -1; + } + if(card.name=='du') return 20; + return -1; + } + if(card.name=='du') return 20; + return -1; + }, content:function(){ 'step 0' if(cards.length){ @@ -261,9 +288,36 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, ai:{ - order:2, + order:function(item,player){ + var evtx=_status.event.getParent('phaseUse'); + if(game.hasPlayer(current=>{ + if(current==player||!evtx||get.attitude(player,current)==0) return false; + return !current.hasHistory('lose',evt=>{ + return evt.getParent(3).name!='clanfuxun'&&evt.getParent('phaseUse')==evtx&&evt.cards2.length; + })&&!current.hasHistory('gain',evt=>{ + return evt.getParent().name!='clanfuxun'&&evt.getParent('phaseUse')==evtx&&evt.cards.length; + })&&Math.abs(player.countCards('h')-current.countCards('h'))==2; + })) return 10; + return 2; + }, result:{ - target:-1, + target:function(player,target){ + var evtx=_status.event.getParent('phaseUse'); + var num=get.sgn(get.attitude(player,target)); + var targets=game.filterPlayer(current=>{ + if(current==player||!evtx||get.attitude(player,current)==0) return false; + return !current.hasHistory('lose',evt=>{ + return evt.getParent(3).name!='clanfuxun'&&evt.getParent('phaseUse')==evtx&&evt.cards2.length; + })&&!current.hasHistory('gain',evt=>{ + return evt.getParent().name!='clanfuxun'&&evt.getParent('phaseUse')==evtx&&evt.cards.length; + })&&Math.abs(player.countCards('h')-current.countCards('h'))==2; + }); + if(targets.contains(target)){ + if(player.countCards('h')6-get.value(card), + check:function(card){ + var player=_status.event.player; + if(player.hasSkill('clanzhongliu')&&get.position(card)!='h') return 10-get.value(card); + return 5-get.value(card); + }, log:false, precontent:function(){ delete event.result.skill; @@ -2106,7 +2164,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ str+=('摸'+get.cnNumber(Math.min(8,num2-num1))+'张牌,然后手牌上限-1。'); } str+=('
※当前手牌上限:'+num2); - var num3=player.countMark('clanguixiang_count'); + var num3=((_status.event.getParent().phaseIndex||0)+1); if(num3>0){ str+=(';阶段数:'+num3) } @@ -2128,7 +2186,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, ai:{ order:function(item,player){ - var num=player.getHandcardLimit(),numx=player.countMark('clanguixiang_count'); + var num=player.getHandcardLimit(),numx=((_status.event.getParent().phaseIndex||0)+1); if(num==5&&numx==4&&player.getStat('skill').clanyirong) return 0; if(player.countCards('h')==num+1&&num!=2&&(num<=4||num>4&&numx>4)) return 10; return 0.5; @@ -2139,56 +2197,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, clanguixiang:{ audio:2, - init:function(player){ - player.addSkill('clanguixiang_count'); - }, - onremove:function(player){ - player.removeSkill('clanguixiang_count'); - var event=_status.event.getParent('phase'); - if(event) delete event._clanguixiang; - }, trigger:{ - player:['phaseZhunbeiBefore','phaseJudgeBefore','phaseDrawBefore','phaseDiscardBefore','phaseJieshuBefore'], + player:'phaseChange', }, forced:true, filter:function(event,player){ - var evt=event.getParent('phase'); - if(!evt||!evt._clanguixiang) return false; - var num1=player.getHandcardLimit()-1,num2=player.countMark('clanguixiang_count'); + if(event.phaseList[event.num].startsWith('phaseUse')) return false; + var num1=player.getHandcardLimit()-1,num2=event.num; return num1==num2; }, content:function(){ - trigger.cancel(null,null,'notrigger'); - var next=player.phaseUse(); - event.next.remove(next); - trigger.getParent().next.unshift(next); - }, - subSkill:{ - count:{ - trigger:{ - player:['phaseZhunbeiBegin','phaseJudgeBegin','phaseDrawBegin','phaseDiscardBegin','phaseJieshuBegin','phaseUseBegin'], - }, - forced:true, - popup:false, - lastDo:true, - priority:-Infinity, - content:function(){ - player.addMark('clanguixiang_count',1,false); - }, - group:'clanguixiang_clear', - }, - clear:{ - trigger:{player:'phaseBefore'}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - priority:Infinity, - content:function(){ - delete player.storage.clanguixiang_count; - trigger._clanguixiang=true; - }, - }, + trigger.phaseList[trigger.num]='phaseUse|clanguixiang'; + game.delayx(); }, }, clanmuyin:{ diff --git a/character/ddd.js b/character/ddd.js index 53dbc276e..ad2e67a17 100644 --- a/character/ddd.js +++ b/character/ddd.js @@ -3304,14 +3304,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dddduanbing:{ enable:'phaseUse', filter:function(event,player){ - return player.canAddJudge('bingliang')&&player.hasCard((card)=>lib.skill['dddduanbing'].filterCard(card,player),'h'); + return player.canAddJudge('bingliang')&&player.hasCard((card)=>lib.skill['dddduanbing'].filterCard(card,player),'he'); }, filterCard:function(card,player){ if(get.color(card)!='black'||get.type2(card)=='trick') return false; return player.canAddJudge(get.autoViewAs({name:'bingliang'},[card])); }, check:function(card){ - return 6-get.value(card); + return 8.2-get.value(card); }, discard:false, lose:false, diff --git a/character/diy.js b/character/diy.js index ceeba6270..7d5776420 100755 --- a/character/diy.js +++ b/character/diy.js @@ -178,7 +178,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ns_chengpu:['male','wu',4,['decadelihuo','decadechunlao']], ns_sundeng:['male','wu',4,['xinkuangbi']], ns_duji:['male','wei',3,['xinfu_andong','xinyingshi']], - old_majun:["male","wei",3,["xinfu_jingxie1","xinfu_qiaosi"],[]], + old_majun:["male","wei",3,["xinfu_jingxie1","xinfu_qiaosi"]], + ns_mengyou:['male','qun',4,['nsmanzhi']], old_jiakui:['male','wei',4,['tongqu','xinwanlan']], ol_guohuai:['male','wei',3,['rejingce']], @@ -219,7 +220,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ "ns_chentai","ns_huangwudie","ns_sunyi","ns_zhangning","ns_yanghu"], diy_yijiang3:['ns_ruanji','ns_zanghong','ns_limi','ns_zhonglimu','prp_zhugeliang','key_seira','key_kiyu','key_tomoyo','key_minagi','key_michiru'], diy_tieba:["ns_zuoci","ns_lvzhi","ns_wangyun","ns_nanhua","ns_nanhua_left","ns_nanhua_right","ns_huamulan","ns_huangzu","ns_jinke","ns_yanliang","ns_wenchou","ns_caocao","ns_caocaosp","ns_zhugeliang","ns_wangyue","ns_yuji","ns_xinxianying","ns_guanlu","ns_simazhao","ns_sunjian","ns_duangui","ns_zhangbao","ns_masu","ns_zhangxiu","ns_lvmeng","ns_shenpei","ns_yujisp","ns_yangyi","ns_liuzhang","ns_xinnanhua","ns_luyusheng"], - diy_fakenews:["diy_wenyang","ns_zhangwei","ns_caimao","ns_chengpu",'ns_sundeng','ns_duji'], + diy_fakenews:["diy_wenyang","ns_zhangwei","ns_caimao","ns_chengpu",'ns_sundeng','ns_duji','ns_mengyou'], diy_xushi:["diy_feishi","diy_hanlong","diy_liufu","diy_liuyan","diy_liuzan","diy_tianyu","diy_xizhenxihong","diy_yangyi","diy_zaozhirenjun"], diy_default:["diy_yuji","diy_caiwenji","diy_lukang","diy_zhenji","old_majun"], diy_noname:['noname'], @@ -373,6 +374,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ns_zhangxiu:'#p本因坊神策', ns_yangyi:'#p本因坊神策', ns_liuzhang:'#r矮子剑薄荷糖', + ns_mengyou:'#g残昼厄夜', }, card:{ kano_paibingbuzhen:{ @@ -678,7 +680,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(evt.gaintag_map[i].includes('fuuko_chuanyuan')) return true; } }); - return false; + //return false; }, content:function(){ trigger.addCount=false; @@ -2599,7 +2601,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } else game.delayx(); 'step 3' - player.addTempSkill('nstuilun_effect',{player:'phaseBegin'}); + player.addTempSkill('nstuilun_effect',{player:'phaseBeginStart'}); }, subSkill:{ effect:{ @@ -3560,7 +3562,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(player.countCards('h')>0) player.chooseToDiscard('h',true,player.countCards('h')); player.recover(); trigger.cancel(); - player.addTempSkill('kyou_duanfa_draw',{player:'phaseBegin'}); + player.addTempSkill('kyou_duanfa_draw',{player:'phaseBeginStart'}); }, subSkill:{ draw:{ @@ -6370,9 +6372,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var num=game.roundNumber; if(num&&typeof num=='number') player.draw(Math.min(3,num)); 'step 1' - var next=player.phaseUse(); - event.next.remove(next); - trigger.next.push(next); + trigger.phaseList.splice(trigger.num,0,'phaseUse|godan_yuanyi'); }, }, godan_feiqu:{ @@ -17953,6 +17953,96 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, + nsmanzhi:{ + audio:'dcmanzhi', + trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, + direct:true, + filter:function(event,player){ + var nums=[]; + game.countPlayer(current=>{ + nums.add(current.hp); + nums.add(current.maxHp); + nums.add(current.countCards('h')); + nums.add(current.countCards('e')); + nums.add(current.countCards('j')); + }); + for(var a of nums){ + for(var b of nums){ + if((0.5*a*a)+(2.5*b)-game.roundNumber==game.countPlayer()) return true; + } + } + return false; + }, + content:function(){ + 'step 0' + var nums=[]; + game.countPlayer(current=>{ + nums.add(current.hp); + nums.add(current.maxHp); + nums.add(current.countCards('h')); + nums.add(current.countCards('e')); + nums.add(current.countCards('j')); + }); + nums.sort((a,b)=>a-b); + var a=null,b=null,goon=false; + for(a of nums){ + for(b of nums){ + if((0.5*a*a)+(2.5*b)-game.roundNumber==game.countPlayer()){ + goon=true; + break; + } + } + if(goon) break; + } + player.chooseButton(2,[ + '蛮智:请选择让下列等式成立的A与B的值', + '
目标等式
', + `0.5 × A² + 2.5 × B - ${game.roundNumber} = ${game.countPlayer()}`, + '
A的可选值
', + [nums.map(i=>{ + return [ + `A|${i}`, + i==a?(`${i}`):i, + ] + }),'tdnodes'], + '
B的可选值
', + [nums.map(i=>{ + return [ + `B|${i}`, + i==b?(`${i}`):i, + ] + }),'tdnodes'], + ]).set('filterButton',function(button){ + if(!ui.selected.buttons.length) return true; + return button.link[0]!=ui.selected.buttons[0].link[0]; + }).set('filterOk',function(){ + if(ui.selected.buttons.length!=2) return false; + var a,b; + for(var i of ui.selected.buttons){ + if(i.link[0]=='A') a=parseInt(i.link.slice(2)); + else b=parseInt(i.link.slice(2)); + } + return (0.5*a*a)+(2.5*b)-game.roundNumber==game.countPlayer(); + }).set('choice',[a,b]).set('ai',(button)=>{ + var choice=_status.event.choice; + if(button.link==`A|${choice[0]}`||button.link==`B|${choice[1]}`) return 1; + return 0; + }); + 'step 1' + if(result.bool){ + var a,b; + for(var i of result.links){ + if(i[0]=='A') a=parseInt(i.slice(2)); + else b=parseInt(i.slice(2)); + } + equals=`0.5×${a}²+2.5×${b}-${game.roundNumber}=${game.countPlayer()}`; + player.logSkill('nsmanzhi'); + player.chat(equals); + game.log(player,'的计算结果为',equals); + player.draw(game.countPlayer()); + } + }, + }, }, dynamicTranslate:{ nsjiquan:function(player){ @@ -19030,6 +19120,20 @@ game.import('character',function(lib,game,ui,get,ai,_status){ junk_huangyueying_prefix:'旧界', old_majun:'骰子马钧', old_majun_prefix:'骰子', + ns_mengyou:'数学孟优', + ns_mengyou_prefix:'数学', + ns_mengyou_ab:'孟优', + nsmanzhi:'蛮智', + nsmanzhi_info:'准备阶段或结束阶段开始时,你可以将场上出现的数字代入等式中的A和B。若此等式成立,你摸Y张牌。(等式为Y=0.5A²+2.5B-X,其中X为游戏轮数,Y为存活人数)', + ns_chengpu:'铁索程普', + ns_chengpu_prefix:'铁索', + ns_chengpu_ab:'程普', + ns_sundeng:'画饼孙登', + ns_sundeng_prefix:'画饼', + ns_sundeng_ab:'孙登', + ns_duji:'画饼杜畿', + ns_duji_prefix:'画饼', + ns_duji_ab:'杜畿', diy_tieba:'吧友设计', diy_xushi:'玩点论杀·虚实篇', @@ -19041,12 +19145,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ diy_yijiang3:'设计比赛2022', diy_fakenews:'杀海流言', diy_trashbin:'垃圾桶', - ns_chengpu:'铁索程普', - ns_chengpu_ab:'程普', - ns_sundeng:'画饼孙登', - ns_sundeng_ab:'孙登', - ns_duji:'画饼杜畿', - ns_duji_ab:'杜畿', }, pinyins:{ 加藤うみ:['Kato','Umi'], diff --git a/character/extra.js b/character/extra.js index 61cc31fe8..8e6401772 100755 --- a/character/extra.js +++ b/character/extra.js @@ -2453,6 +2453,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(player.needsToDiscard()) return num/3; return 0; } + }, + targetInRange:function(card,player,target){ + if(target.hasMark('yingba_mark')) return true; } }, enable:'phaseUse', @@ -2468,15 +2471,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, locked:false, //global:'yingba_mark', - mod:{ - targetInRange:function(card,player,target){ - if(target.hasMark('yingba_mark')) return true; - }, - }, ai:{ combo:'scfuhai', threaten:3, - order:9, + order:11, result:{ player:function(player,target){ if(player.maxHp==1) return -2.5; @@ -2631,12 +2629,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, content:function(){ game.addGlobalSkill('tianzuo_global'); + var cards=[]; for(var i=2;i<10;i++){ - var card=game.createCard2('qizhengxiangsheng',i%2?'club':'spade',i); - ui.cardPile.insertBefore(card,ui.cardPile.childNodes[get.rand(0,ui.cardPile.childNodes.length)]); + cards.push(game.createCard2('qizhengxiangsheng',i%2?'club':'spade',i)); } game.broadcastAll(function(){lib.inpile.add('qizhengxiangsheng')}); - game.updateRoundNumber(); + game.cardsGotoPile(cards,()=>{ + return ui.cardPile.childNodes[get.rand(0,ui.cardPile.childNodes.length-1)]; + }) }, group:'tianzuo_remove', subSkill:{ @@ -3588,7 +3588,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ huoxin2:{ trigger:{ player:['phaseAfter','dieAfter'], - global:'phaseBefore', + global:'phaseBeforeStart', }, lastDo:true, charlotte:true, @@ -5414,7 +5414,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.chooseTarget(get.prompt('dawu'),'令至多'+get.cnNumber(num)+'名角色获得“大雾”标记', [1,num]).set('ai',function(target){ if(target.isMin()) return 0; - if(target.hasSkill('biantian2')) return 0; + if(target.hasSkill('biantian2')||target.hasSkill('dawu2')) return 0; var att=get.attitude(player,target); if(att>=4){ if(_status.event.allUse) return att; @@ -5428,13 +5428,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ })*2); "step 1" if(result.bool){ - player.logSkill('dawu',result.targets,'thunder'); - var length=result.targets.length; - for(var i=0;i{ + target.addAdditionalSkill(`dawu_${player.playerid}`,'dawu2'); + target.markAuto('dawu2',[player]); + }); + player.addTempSkill('dawu3',{player:'phaseBeginStart'}) player.chooseCardButton('选择弃置'+get.cnNumber(length)+'张“星”',length,player.getExpansions('qixing'),true); - player.addSkill('dawu3'); } else{ event.finish(); @@ -5445,46 +5447,41 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ai:{combo:'qixing'}, }, dawu2:{ - trigger:{player:'damageBegin4'}, - filter:function(event){ - if(!event.hasNature('thunder')) return true; - return false; - }, - mark:true, - forced:true, charlotte:true, - content:function(){ - trigger.cancel(); - }, ai:{ nofire:true, nodamage:true, effect:{ target:function(card,player,target,current){ - if(get.tag(card,'damage')&&!get.tag(card,'thunderDamage')) return [0,0]; + if(get.tag(card,'damage')&&!get.tag(card,'thunderDamage')) return 'zeroplayertarget'; } }, }, intro:{ - markcount:()=>1, - content:'共有1个标记', + content:function(storage){ + return `共有${storage.length}枚标记`; + }, } }, dawu3:{ - trigger:{player:['phaseBegin','dieBegin']}, - silent:true, + trigger:{global:'damageBegin4'}, + filter:function(event,player){ + return !event.hasNature('thunder')&&event.player.getStorage('dawu2').includes(player); + }, + forced:true, charlotte:true, + logTarget:'player', content:function(){ - for(var i=0;i{ + if(current.getStorage('dawu2').includes(player)){ + current.unmarkAuto('dawu2',player); + current.removeAdditionalSkill(`dawu_${player.playerid}`); } - if(game.players[i].hasSkill('kuangfeng2')){ - game.players[i].removeSkill('kuangfeng2'); - } - } - player.removeSkill('dawu3'); - } + },true); + }, }, kuangfeng:{ unique:true, @@ -5501,13 +5498,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } "step 1" if(result.bool){ - var length=result.targets.length; - for(var i=0;i{ + target.addAdditionalSkill(`kuangfeng_${player.playerid}`,'kuangfeng2'); + target.markAuto('kuangfeng2',[player]); + }); + player.addTempSkill('kuangfeng3',{player:'phaseBeginStart'}) + player.chooseCardButton('选择弃置'+get.cnNumber(length)+'张“星”',length,player.getExpansions('qixing'),true); } else{ event.finish(); @@ -5518,28 +5517,40 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ai:{combo:'qixing'}, }, kuangfeng2:{ - trigger:{player:'damageBegin3'}, - filter:function(event){ - if(event.hasNature('fire')) return true; - return false; - }, - mark:true, + charlotte:true, intro:{ - markcount:()=>1, - content:'共有1个标记' - }, - forced:true, - content:function(){ - trigger.num++; + content:function(storage){ + return `共有${storage.length}枚标记`; + }, }, ai:{ effect:{ target:function(card,player,target,current){ - if(get.tag(card,'fireDamage')) return 1.5; + if(get.tag(card,'fireDamage')&¤t<0) return 1.5; } } } }, + kuangfeng3:{ + trigger:{global:'damageBegin3'}, + filter:function(event){ + return event.hasNature('fire')&&event.player.getStorage('kuangfeng2').includes(player); + }, + charlotte:true, + forced:true, + logTarget:'player', + content:function(){ + trigger.num++; + }, + onremove:function(player){ + game.countPlayer2(current=>{ + if(current.getStorage('kuangfeng2').includes(player)){ + current.unmarkAuto('kuangfeng2',player); + current.removeAdditionalSkill(`kuangfeng_${player.playerid}`); + } + },true); + }, + }, yeyan:{ unique:true, forceDie:true, @@ -5563,7 +5574,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ selectCard:[0,4], line:'fire', check:function (){return -1}, - selectTarget:function (){ + selectTarget:function(){ if(ui.selected.cards.length==4) return [1,2]; if(ui.selected.cards.length==0) return [1,3]; game.uncheck('target'); @@ -5571,9 +5582,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, multitarget:true, multiline:true, - content:function (){ - "step 0" + contentBefore:function(){ player.awakenSkill('yeyan'); + }, + content:function(){ + "step 0" event.num=0; targets.sortBySeat(); "step 1" diff --git a/character/huicui.js b/character/huicui.js index 5cd1e4d7a..da6048410 100644 --- a/character/huicui.js +++ b/character/huicui.js @@ -3397,7 +3397,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target:function(player,target){ var val=0; var bool1=!game.hasPlayer(current=>current.maxHp2&&card.name=='tao'&&target==_status.event.dying) return false; }, } @@ -4997,10 +4997,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return false; }, prompt2:'检索一张【无中生有】并置于牌堆顶', - check:function(event,player){ - if(!_status.currentPhase) return false; - return get.attitude(player,_status.currentPhase.next)>0; - }, content:function(){ var card=get.cardPile(function(card){ return card.name=='wuzhong'&&get.suit(card)!='diamond'; @@ -5048,7 +5044,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(evtx3.gaintag_map[i].contains('dcliuzhuan_tag')) return true; } }); - return false; + //return false; } else if(event.name=='lose'){ if(event.player!=current||event.position!=ui.discardPile) return false; @@ -5272,7 +5268,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(target.group!=current.group) return false; if(!ui.selected.targets.length) return true; return ui.selected.targets[0]==current; - return current==target; + //return current==target; }).set('ai',function(target){ var player=_status.event.player; return get.effect(target,{name:'sha'},player,player); @@ -6402,6 +6398,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger.directHit.push(trigger.target); } }, + ai:{ + effect:{ + player:function(card,player,target){ + if(player!==target&&get.itemtype(target)==='player'&&(card.name==='sha'||get.type(card,false)==='trick')&& + target.countCards('he')&&!target.hasSkillTag('noh')) return [1,0,1,-1]; + } + } + } }, }, }, @@ -7631,9 +7635,26 @@ game.import('character',function(lib,game,ui,get,ai,_status){ list.push(suit); } } - if(list.length){ - player.chooseControl(list,'cancel2').set('dialog',dialog); - } + if(list.length) player.chooseControl(list,'cancel2').set('dialog',dialog).set('list',list).set('map',map).set('ai',function(){ + let max=0,res='cancel2'; + for(let s of _status.event.list){ + let temp=0; + for(let i of _status.event.map[s]){ + temp+=get.value(i,_status.event.player)+get.sgn(get.attitude(_status.event.player,get.owner(i)))*(6-get.value(i,get.owner(i))); + } + for(let i in _status.event.map){ + if(i===s) continue; + for(let j of _status.event.map[i]){ + temp-=get.sgn(get.attitude(_status.event.player,get.owner(j)))*get.value(j,get.owner(j)); + } + } + if(temp>max){ + res=s; + max=temp; + } + } + return res; + }); else event.finish(); 'step 3' if(result.control!='cancel2'){ @@ -8390,6 +8411,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ subSkill:{ effect:{ audio:'kuanshi', + mark:true, + intro:{ + content:'每回合限一次,当$于一回合内受到第2点伤害后,其回复1点体力。' + }, trigger:{global:'damageEnd'}, forced:true, charlotte:true, @@ -9359,6 +9384,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, dcdanying:{ audio:2, + mod:{ + aiOrder:function(player,card,num){ + if(num<=0 || card.name!=='sha'&&card.name!=='shan' || !player.hasCard(i=>i.hasGaintag('dcmiyun_tag'),'h')) return; + return Math.max(0.12,num/25); + } + }, + locked:false, enable:['chooseToUse','chooseToRespond'], usable:1, hiddenCard:function(player,name){ @@ -9435,11 +9467,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target:function(card,player,target){ if(_status._dcdanying_aiChecking) return; _status._dcdanying_aiChecking=true; - var eff=get.effect(target,{name:'guohe_copy2'},player,player); + let eff=get.effect(target,{name:'guohe_copy2'},player,player); delete _status._dcdanying_aiChecking; - if(eff>0) eff=-1; - else eff=1; - return [1,eff]; + return [1,get.sgn(eff)]; } } } @@ -10068,6 +10098,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp_jiaxu:['sp_jiaxu','dc_sp_jiaxu','yj_jiaxu'], qiaorui:['qiaorui','tw_qiaorui'], mamidi:['mamidi','xin_mamidi'], + mengyou:['mengyou','ns_mengyou'], }, translate:{ re_panfeng:'潘凤', diff --git a/character/jiange.js b/character/jiange.js index cad3400b3..937a6e4a4 100644 --- a/character/jiange.js +++ b/character/jiange.js @@ -201,7 +201,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, chiying:{ - trigger:{global:'damageBegin'}, + trigger:{global:'damageBegin2'}, check:function(event,player){ return get.attitude(player,event.player)>0; }, @@ -209,7 +209,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(event.num<=1) return false; return true; }, - priority:-11, content:function(){ trigger.num=1; if(trigger.source){ diff --git a/character/jsrg.js b/character/jsrg.js index 6c54f87aa..b0e3b0f23 100644 --- a/character/jsrg.js +++ b/character/jsrg.js @@ -227,7 +227,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target.isOnline()){ player.storage.jsrgbashiing=true; var list=['sha','shan'].filter(name=>trigger.filterCard({name:name},player,trigger)); - var names=list.map(i=>'【'+i+'】').join('或'); + var names=list.map(i=>'【'+get.translation(i)+'】').join('或'); var next=target.chooseToRespond('是否替'+get.translation(player)+'打出一张'+names+'?',{name:list}); next.set('ai',function(){ var event=_status.event; diff --git a/character/mobile.js b/character/mobile.js index 93f127851..abfbcd5bc 100644 --- a/character/mobile.js +++ b/character/mobile.js @@ -6,7 +6,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ connect:true, characterSort:{ mobile:{ - mobile_default:['xin_guozhao',"miheng","taoqian","lingcao","sunru","lifeng","zhuling","liuye","zhaotongzhaoguang","majun","simazhao","wangyuanji","pangdegong","shenpei","hujinding","zhangyì","jiakui","yangbiao","chendeng","dongcheng","yangyi","dengzhi","zhengxuan","sp_sufei","furong","dingyuan","simashi","yanghuiyu","hucheer","gongsunkang","nanhualaoxian","zhouqun","qiaozhou","fuqian","simafu","mayuanyi","yanpu","sunhanhua","sp_maojie","peixiu","sp_jianggan","ruanhui","xin_mamidi","sp_caosong","yangfu","wangjun","sp_pengyang","qianzhao",'shichangshi'], + mobile_default:['xin_wuban','laimin','baoxin','jiangji','liwei','xin_guozhao',"miheng","taoqian","lingcao","sunru","lifeng","zhuling","liuye","zhaotongzhaoguang","majun","simazhao","wangyuanji","pangdegong","shenpei","hujinding","zhangyì","jiakui","yangbiao","chendeng","dongcheng","yangyi","dengzhi","zhengxuan","sp_sufei","furong","dingyuan","simashi","yanghuiyu","hucheer","gongsunkang","nanhualaoxian","zhouqun","qiaozhou","fuqian","simafu","mayuanyi","yanpu","sunhanhua","sp_maojie","peixiu","sp_jianggan","ruanhui","xin_mamidi","sp_caosong","yangfu","wangjun","sp_pengyang","qianzhao",'shichangshi'], mobile_yijiang:["yj_zhanghe","yj_zhangliao","yj_xuhuang","yj_ganning",'yj_huangzhong','yj_weiyan','yj_zhoubuyi'], mobile_standard:["xin_xiahoudun","xin_zhangfei"], mobile_shenhua_feng:['re_xiaoqiao',"xin_zhoutai"], @@ -26,6 +26,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, character:{ + xin_wuban:['male','shu',4,['xinjintao'],['clan:陈留吴氏','character:wuban']], + baoxin:['male','qun',4,['mutao','yimou'],['character:tw_baoxin','die_audio:tw_baoxin']], + jiangji:['male','wei',3,['twjichou','jilun'],['character:tw_jiangji','die_audio:tw_jiangji']], + liwei:['male','shu',4,['jiaohua'],['character:tw_liwei','die:tw_liwei']], + laimin:['male','shu',3,['laishou','luanqun']], yj_zhoubuyi:['male','wei',3,['mbhuiyao','mbquesong']], xin_guozhao:['female','wei',3,['yichong','wufei']], xin_zhangyi:['male','shu',4,['xinwurong','shizhi']], @@ -166,6 +171,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ scs_gaowang:['male','qun','',['scsmiaoyu'],['unseen','sex:male_castrated']], }, characterIntro:{ + laimin:'来敏(165年—261年),字敬达,义阳新野人,东汉太中大夫来歙之后,司空来艳之子,三国时期蜀汉官员。东汉末年,逢董卓之乱,来敏跟随姐夫黄琬到荆州避难,黄琬是刘璋祖母的侄子,来敏又与姐姐来氏入蜀,被刘璋引为宾客。来敏喜欢读书,尤其喜欢《左氏春秋》。刘备平定益州后,以来敏为典学校尉,后立太子,来敏为家令。刘禅继位后,任命来敏为虎贲中郎将,诸葛亮驻汉中,请来敏为军祭酒、辅军将军。却因其口出狂言而被罢官,诸葛亮死后,来敏历任大长秋、光禄大夫、执慎将军等职,期间多次因说错话而被免官,蜀汉景耀年间,来敏去世,时年九十七岁。', shichangshi:'十常侍,指中国东汉(公元25年—220年)灵帝时期(168年-189年)操纵政权的十二个宦官:张让、赵忠、夏恽、郭胜、孙璋、毕岚、栗嵩、段珪、高望、张恭、韩悝、宋典(在小说《三国演义》里,十常侍指的是指张让、赵忠、封谞、段珪、曹节、侯览、蹇硕、程旷、夏恽、郭胜十人),他们都任职中常侍。玩弄小皇帝于股掌之中,以至灵帝称“张常侍是我父,赵常侍是我母”。十常侍自己横征暴敛,卖官鬻爵,他们的父兄子弟遍布天下,横行乡里,祸害百姓,无官敢管。人民不堪剥削、压迫,纷纷起来反抗。当时一些比较清醒的官吏,已看出宦官集团的黑暗腐败,导致大规模农民起义的形势。郎中张钧在给皇帝的奏章中明确指出,黄巾起义是外戚宦官专权逼出来的,他说:“张角所以能兴兵作乱,万人所以乐附之者,其源皆由十常侍多放父兄、子弟、婚宗、宾客典据州郡,辜确财利,侵略百姓,百姓之怨无所告诉,故谋议不轨,聚为‘盗贼’。”后被曹操、袁绍所歼。', sunzhang:'孙璋(?-189年?)东汉末期汉灵帝的宦官,官居中常侍,为十常侍之一,在张让、赵忠之下位居第三。光熹元年(189年),张让、赵忠、段珪等诛杀何进,袁绍率军入宫,诛杀孙璋。', bilan:'毕岚(?—189),东汉宦官,十常侍之一。十常侍朋比为奸,祸乱朝纲,制造出党锢之祸,后被袁绍诛杀。另外,毕岚曾制造翻车,用于取河水洒路。', @@ -380,6 +386,422 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, skill:{ + //庞统 + xinlianhuan:{ + audio:2, + audioname:['ol_pangtong'], + inherit:'lianhuan', + group:'xinlianhuan_add', + subSkill:{ + add:{ + audio:'xinlianhuan', + audioname:['ol_pangtong'], + trigger:{player:'useCard2'}, + filter:function(event,player){ + if(event.card.name!='tiesuo') return false; + var info=get.info(event.card); + if(info.allowMultiple==false) return false; + if(event.targets&&!info.multitarget){ + if(game.hasPlayer(current=>{ + return !event.targets.contains(current)&&lib.filter.targetEnabled2(event.card,player,current); + })) return true; + } + return false; + }, + charlotte:true, + forced:true, + popup:false, + content:function(){ + 'step 0' + player.chooseTarget(get.prompt('xinlianhuan'),'为'+get.translation(trigger.card)+'额外指定一个目标',(card,player,target)=>{ + return !_status.event.sourcex.contains(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); + }).set('sourcex',trigger.targets).set('ai',function(target){ + var player=_status.event.player; + return get.effect(target,_status.event.card,player,player); + }).set('card',trigger.card); + 'step 1' + if(result.bool){ + if(!event.isMine()&&!event.isOnline()) game.delayex(); + } + else event.finish(); + 'step 2' + if(result.bool){ + var targets=result.targets; + player.logSkill('xinlianhuan_add',targets); + trigger.targets.addArray(targets); + game.log(targets,'也成为了',trigger.card,'的目标'); + } + }, + }, + }, + }, + //吴班 + xinjintao:{ + audio:'jintao', + inherit:'jintao', + content:function(){ + var evt=trigger.getParent('phaseUse'); + var index=player.getHistory('useCard',function(evtx){ + return evtx.card.name=='sha'&&evtx.getParent('phaseUse')==evt; + }).indexOf(trigger); + if(index==0){ + game.log(trigger.card,'不可被响应'); + trigger.directHit.addArray(game.players); + } + else{ + game.log(trigger.card,'伤害+1'); + if(typeof trigger.baseDamage!='number') trigger.baseDamage=1; + trigger.baseDamage++; + } + }, + }, + //鲍信 + mutao:{ + audio:'twmutao', + inherit:'twmutao', + content:function(){ + 'step 0' + event.togive=target.getNext(); + var cards=target.getCards('h',{name:'sha'}); + if(!cards.length){ + game.log('但',target,'没有','#y杀','!'); + event.finish(); + } + else target.addToExpansion(cards,target,'give').gaintag.add('mutao'); + 'step 1' + var card=target.getExpansions('mutao').randomGet(); + target.give(card,event.togive); + 'step 2' + if(target.getExpansions('mutao').length){ + event.togive=event.togive.getNext(); + event.goto(1); + } + else{ + target.line(event.togive); + event.togive.damage(Math.min(3,event.togive.countCards('h',{name:'sha'})),target); + } + }, + intro:{ + content:'expansion', + markcount:'expansion', + }, + }, + yimou:{ + audio:'twyimou', + inherit:'twyimou', + content:function(){ + 'step 0' + if(trigger.player!=player) player.addExpose(0.3); + var target=get.translation(trigger.player); + var choiceList=[ + '令'+target+'获得牌堆里的一张【杀】', + '令'+target+'将一张牌交给另一名角色,然后'+target+'摸一张牌', + ]; + var list=['选项一']; + if(trigger.player.countCards('h')) list.push('选项二'); + else choiceList[1]=''+choiceList[1]+''; + player.chooseControl(list).set('prompt','毅谋:请选择一项').set('choiceList',choiceList).set('ai',function(){ + var evt=_status.event.getTrigger(),list=_status.event.list; + var player=_status.event.player; + var target=evt.player; + if(target.countCards('h')&&list.contains('选项二')) return '选项二'; + return '选项一'; + }).set('list',list); + 'step 1' + event.choice=result.control; + 'step 2' + if(event.choice!='选项二'){ + var card=get.cardPile2(function(card){ + return card.name=='sha'; + }); + if(card) trigger.player.gain(card,'gain2'); + else game.log('但牌堆里已经没有','#y杀','了!'); + if(event.choice=='选项一') event.finish(); + } + 'step 3' + if(event.choice!='选项一'){ + if(trigger.player.countCards('h')) trigger.player.chooseCardTarget({ + prompt:'毅谋:将一张手牌交给另一名其他角色', + filterCard:true, + forced:true, + filterTarget:lib.filter.notMe, + ai1:function(card){ + return 1/Math.max(0.1,get.value(card)); + }, + ai2:function(target){ + var player=_status.event.player,att=get.attitude(player,target); + if(target.hasSkillTag('nogain')) att/=9; + return 4+att; + }, + }); + else event.finish(); + } + 'step 4' + var target=result.targets[0]; + trigger.player.line(target); + trigger.player.give(result.cards,target); + trigger.player.draw(); + }, + }, + //蒋济 + jilun:{ + audio:'twjilun', + inherit:'twjilun', + filter:function(event,player){ + return player.hasSkill('twjichou'); + }, + content:function(){ + 'step 0' + var num=Math.min(Math.max(1,player.getStorage('twjichou').length),5); + event.num=num; + var choices=['选项一']; + var choiceList=[ + '摸'+get.cnNumber(num)+'张牌', + '获得一个“机论”标记', + ]; + if(!player.getStorage('twjichou').length||!player.getStorage('twjichou').filter(function(name){ + return !player.getStorage('jilun').contains(name)&&player.hasUseTarget({name:name}); + }).length) choiceList[1]=''+choiceList[1]+''; + else choices.push('选项二'); + player.chooseControl(choices,'cancel2').set('choiceList',choiceList).set('prompt',get.prompt('jilun')).set('ai',()=>{ + if(_status.event.choiceList.length==1||!player.getStorage('twjichou').length) return 0; + var val=_status.event.num>3?Math.min(1.5,1+(_status.event.num-3)*0.1):1; + for(var name of player.getStorage('twjichou')){ + if(player.getStorage('jilun').contains(name)) continue; + if(player.getUseValue({name:name})>4*val) return 1; + } + return 0; + }).set('num',num); + 'step 1' + if(result.control!='cancel2'){ + player.logSkill('jilun'); + if(result.control=='选项一') player.draw(num); + else player.addMark('jilun_mark',1); + } + }, + group:'jilun_effect', + subSkill:{ + mark:{ + intro:{content:'mark'}, + }, + effect:{ + audio:'twjilun', + trigger:{global:'phaseJieshuBegin'}, + filter:function(event,player){ + return player.hasMark('jilun_mark'); + }, + forced:true, + content:function(){ + 'step 0' + if(!player.getStorage('twjichou').length||!player.getStorage('twjichou').filter(function(name){ + return !player.getStorage('jilun').contains(name)&&player.hasUseTarget({name:name}); + }).length){ + if(player.hasMark('jilun_mark')) player.removeMark('jilun_mark',player.countMark('jilun_mark')); + event.finish(); + return; + } + var list=[]; + for(var name of player.getStorage('twjichou')){ + if(!player.getStorage('jilun').contains(name)){ + list.push(['锦囊','',name]); + } + } + player.chooseButton(['###机论:请选择你要执行的选项###
  • 失去1枚“机论”标记,视为使用一张〖急筹〗已记录但〖机论〗未记录的普通锦囊牌
  • 失去所有“机论”标记
  • ',[list,'vcard']]).set('filterButton',function(button){ + return _status.event.player.hasUseTarget({name:button.link[2]}); + }).set('ai',function(button){ + return _status.event.getParent().player.getUseValue({name:button.link[2]},null,true); + }); + 'step 1' + if(result.bool){ + player.removeMark('jilun_mark',1); + var card={name:result.links[0][2],isCard:true}; + player.chooseUseTarget(card,true); + player.markAuto('jilun',[card.name]); + player.syncStorage('jilun'); + } + else{ + player.removeMark('jilun_mark',player.countMark('jilun_mark')); + event.finish(); + } + 'step 2' + if(player.hasMark('jilun_mark')) event.goto(0); + }, + }, + }, + }, + //李遗 + jiaohua:{ + onremove:true, + audio:'twjiaohua', + enable:'phaseUse', + usable:3, + chooseButton:{ + dialog:function(event,player){ + return ui.create.dialog('###教化###选择一种牌的类型,令一名角色从牌堆获得此类型的一张牌'); + }, + chooseControl:function(event,player){ + var list=['basic','trick','equip'].filter(type=>!player.getStorage('jiaohua').contains(type)); + list.push('cancel2'); + return list; + }, + check:function(event,player){ + var list=['trick','equip','basic'].filter(type=>!player.getStorage('jiaohua').contains(type)); + return list[0]; + }, + backup:function(result,player){ + return{ + type:result.control, + audio:'twjiaohua', + filterTarget:true, + content:function(){ + 'step 0' + var type=lib.skill.jiaohua_backup.type; + var card=get.cardPile2(card=>get.type2(card)==type); + if(card) target.gain(card,'gain2'); + else game.log('但牌堆里已经没有','#y'+get.translation(type)+'牌','了!'); + 'step 1' + player.markAuto('jiaohua',[lib.skill.jiaohua_backup.type]); + 'step 2' + if(!['basic','trick','equip'].some(type=>!player.getStorage('jiaohua').contains(type))){ + player.popup('教化'); + player.unmarkAuto('jiaohua',player.getStorage('jiaohua')); + game.log(player,'清空了','#g【教化】','记录'); + } + }, + ai:{ + result:{target:1}, + }, + } + }, + prompt:function(result,player){ + return '令一名角色从牌堆中获得一张'+get.translation(result.control)+'牌'; + }, + }, + ai:{ + order:7, + result:{player:1}, + }, + intro:{content:'已记录$牌'}, + }, + //来敏 + laishou:{ + audio:3, + trigger:{player:['damageBegin4','phaseZhunbeiBegin']}, + filter:function(event,player){ + var num=9; + if(event.name=='damage') return event.num>=player.getHp()&&player.maxHp=num; + }, + forced:true, + content:function(){ + if(trigger.name=='damage'){ + player.gainMaxHp(trigger.num); + trigger.cancel(); + } + else player.die(); + }, + }, + luanqun:{ + audio:2, + enable:'phaseUse', + filter:function(event,player){ + return player.countCards('h'); + }, + usable:1, + content:function(){ + 'step 0' + var targets=game.filterPlayer(current=>current.countCards('h')).sortBySeat(); + event.targets=targets; + var next=player.chooseCardOL(targets,'乱群:请选择要展示的牌',true).set('ai',function(card){ + return -get.value(card); + }).set('source',player); + next.aiCard=function(target){ + var hs=target.getCards('h'); + return {bool:true,cards:[hs.randomGet()]}; + }; + next._args.remove('glow_result'); + 'step 1' + var cards=[]; + event.videoId=lib.status.videoId++; + for(var i=0;icardy!=card&&get.color(cardy,targets[cards.indexOf(cardy)])==get.color(card,player)); + if(cardx.length){ + player.chooseButton(['乱群:是否获得其中的一张牌',cardx]).set('forceAuto',true).set('ai',function(button){ + var cards=_status.event.list[0]; + var targets=_status.event.list[1]; + var player=_status.event.player; + if(get.attitude(player,targets[cards.indexOf(button.link)])) return 0; + return get.value(button.link,player); + }).set('list',[cards,targets]); + } + else event.goto(4); + 'step 3' + if(result.bool){ + var card=result.links[0]; + player.gain(card,get.owner(card),'give'); + } + 'step 4' + var card=cards[targets.indexOf(player)]; + targets=targets.filter(target=>get.color(cards[targets.indexOf(target)],target)!=get.color(card,player)); + if(targets.length){ + player.line(targets); + targets.forEach(target=>{ + target.addTempSkill('luanqun_effect',{player:'phaseUseAfter'}); + target.markAuto('luanqun_effect',[player]); + }); + } + }, + ai:{ + order:9, + result:{ + player:function(player,target){ + if(player.hasSkill('laishou')) return 1; + return player.hp>=2?1:0; + }, + }, + }, + subSkill:{ + effect:{ + charlotte:true, + onremove:true, + intro:{content:'出牌阶段第一张【杀】只能指定$为目标,且此牌不可被响应'}, + mod:{ + playerEnabled:function(card,player,target){ + if(!player.isPhaseUsing()) return; + if(card.name=='sha'&&player.getStorage('luanqun_effect').contains(target)) return false; + }, + }, + trigger:{player:'useCard1'}, + filter:function(event,player){ + return player.isPhaseUsing()&&event.card.name=='sha'; + }, + forced:true, + content:function(){ + trigger.directHit.addArray(player.getStorage('luanqun_effect')); + player.removeSkill('luanqun_effect'); + }, + }, + }, + }, //☆周不疑 mbhuiyao:{ audio:2, @@ -497,6 +919,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ lib.translate['yichong_'+player.playerid+'_bg']='雀'; } }, + getLimit:1, audio:2, trigger:{player:'phaseZhunbeiBegin'}, direct:true, @@ -541,7 +964,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.markSkill('yichong'); game.broadcastAll(function(player,suit){ if(player.marks.yichong) player.marks.yichong.firstChild.innerHTML=get.translation(suit); - },player,suit) + },player,suit); if(target.countCards('he',{suit:suit})) player.gain(target.getCards('he',{suit:suit}),target,'giveAuto'); game.countPlayer(function(current){ current.removeSkill('yichong_'+player.playerid); @@ -560,7 +983,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(!player.storage.yichong) return false; return game.hasPlayer(function(current){ if(!event.getg(current).length||!current.hasSkill('yichong_'+player.playerid)) return false; - if(current.countMark('yichong_'+player.playerid)>=5) return false; + if(current.countMark('yichong_'+player.playerid)>=lib.skill.yichong.getLimit) return false; return event.getg(current).some(card=>get.suit(card,current)==player.storage.yichong&&lib.filter.canBeGained(card,current,player)); }); }, @@ -569,14 +992,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 0' var target=game.findPlayer(function(current){ if(!trigger.getg(current).length||!current.hasSkill('yichong_'+player.playerid)) return false; - if(current.countMark('yichong_'+player.playerid)>=5) return false; + if(current.countMark('yichong_'+player.playerid)>=lib.skill.yichong.getLimit) return false; return trigger.getg(current).some(card=>get.suit(card,current)==player.storage.yichong&&lib.filter.canBeGained(card,current,player)); }); event.target=target; var cards=trigger.getg(target).filter(card=>get.suit(card,target)==player.storage.yichong&&lib.filter.canBeGained(card,target,player)); - if(cards.length<=5-target.countMark('yichong_'+player.playerid)) event._result={bool:true,links:cards}; + if(cards.length<=lib.skill.yichong.getLimit-target.countMark('yichong_'+player.playerid)) event._result={bool:true,links:cards}; else{ - var num=(5-target.countMark('yichong_'+player.playerid)); + var num=(lib.skill.yichong.getLimit-target.countMark('yichong_'+player.playerid)); player.chooseButton(['易宠:获得其中的'+get.cnNumber(num)+'张牌',cards],num,true).set('ai',function(button){ return get.value(button.link); }); @@ -604,7 +1027,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ filter:function(event,player){ var target=game.findPlayer(current=>current.hasSkill('yichong_'+player.playerid)); if(!target) return false; - if(event.name=='damage') return target.hp>Math.max(1,player.hp); + if(event.name=='damage') return target.hp>3; return event.isFirstTarget&&(event.card.name=='sha'||(get.type(event.card)=='trick'&&get.tag(event.card,'damage'))); }, direct:true, @@ -613,7 +1036,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var target=game.findPlayer(current=>current.hasSkill('yichong_'+player.playerid)); event.target=target; if(trigger.name=='damage'){ - player.chooseBool(get.prompt('wufei',target),'对'+get.translation(target)+'造成1点伤害').set('choice',get.damageEffect(target,player,player)>0); + player.chooseBool(get.prompt('wufei',target),'令'+get.translation(target)+'受到1点无来源伤害').set('choice',get.damageEffect(target,player,player)>0); } else{ player.logSkill('wufei',target); @@ -625,7 +1048,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 1' if(result.bool){ player.logSkill('wufei',target); - target.damage(); + target.damage('nosource'); } }, subSkill:{ @@ -4594,7 +5017,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ viewAsFilter:function(player){ return player.hasCard({type:'equip'},'ehs'); }, - check:(card)=>5-get.value(card), + check:function(card){ + if(_status.event.type=='dying') return 1/(get.value(card)||0.5); + return 5-get.value(card); + }, locked:false, mod:{ maxHandcard:function(player,num){ @@ -9476,10 +9902,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var att=get.attitude(player,target); return -att; //if(cards.length==1) return -att; - if(player==target) att/=2; - if(target.hasSkill('pingkou')) att*=1.4; - att*=(1+target.countCards('j')/2); - return att; + // if(player==target) att/=2; + // if(target.hasSkill('pingkou')) att*=1.4; + // att*=(1+target.countCards('j')/2); + // return att; }); "step 3" if(result.bool){ @@ -12164,7 +12590,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player:"linkBefore", }, forced:true, - priority:20, + //priority:20, filter:function(event,player){ return !player.isLinked(); }, @@ -13178,7 +13604,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, cancel:{ trigger:{player:'phaseUseEnd'}, - priority:50, + firstDo:true, silent:true, charlotte:true, content:function(){ @@ -14851,9 +15277,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ xin_guozhao:'手杀郭照', xin_guozhao_prefix:'手杀', yichong:'易宠', - yichong_info:'①准备阶段,你可以选择一名其他角色并选择一个花色,然后你获得其所有此花色的牌,移除场上的所有“雀”标记,令其获得“雀”标记直到你的下个回合开始。②拥有“雀”标记的角色获得你最后一次发动〖易宠①〗选择的花色的牌后,你获得这些牌(你至多通过每个“雀”得到五张牌)。', + yichong_info:'①准备阶段,你可以选择一名其他角色并选择一个花色,然后你获得其所有此花色的牌,移除场上的所有“雀”标记,令其获得“雀”标记直到你的下个回合开始。②拥有“雀”标记的角色获得你最后一次发动〖易宠①〗选择的花色的牌后,你获得这些牌(你至多通过每个“雀”得到一张牌)。', wufei:'诬诽', - wufei_info:'若场上存在拥有“雀”标记的角色A,则:①当你使用【杀】或伤害类锦囊牌指定第一个目标后,你令A成为此牌伤害来源。②当你受到伤害后,若A的体力值大于1且A的体力值大于你,则你可以对A造成1点伤害。', + wufei_info:'若场上存在拥有“雀”标记的角色A,则:①当你使用【杀】或伤害类锦囊牌指定第一个目标后,你令A成为此牌伤害来源。②当你受到伤害后,若A的体力值大于3,则你可以令A受到1点无来源伤害。', yj_zhoubuyi:'☆周不疑', yj_zhoubuyi_prefix:'☆', mbhuiyao:'慧夭', @@ -14886,6 +15312,34 @@ game.import('character',function(lib,game,ui,get,ai,_status){ re_chenqun_prefix:'手杀界', old_yuanshu:'手杀界袁术', old_yuanshu_prefix:'手杀界', + re_liru:'手杀李儒', + re_liru_prefix:'手杀', + re_chenqun:'手杀陈群', + re_chenqun_prefix:'手杀', + old_yuanshu:'手杀袁术', + old_yuanshu_prefix:'手杀', + baoxin:'鲍信', + mutao:'募讨', + mutao_info:'出牌阶段限一次。你可以选择一名角色,令其将手牌中所有的【杀】置于武将牌上,然后将这些牌依次随机交给其下家开始的每一名角色。然后其对最后一名以此法获得【杀】的角色A造成X点伤害(X为A手牌中【杀】的数量且至多为3)。', + yimou:'毅谋', + yimou_info:'当一名角色受到伤害后,若其存活且你至其的距离不大于1,你可以选择一项:1.令其从牌堆中获得一张【杀】;2.令其将一张手牌交给另一名角色,然后摸一张牌。', + jiangji:'蒋济', + jilun:'机论', + jilun_info:'①当你受到伤害后,若你拥有技能〖急筹〗,则你可以一项:1.摸X张牌(X为〖急筹①〗记录数,且X且至少为1,至多为5)。2.获得1枚“机论”标记。②一名角色的结束阶段,若你拥有“机论”,则重复选择执行以下项直到你没有“机论”标记:1.失去1枚“机论”标记,视为使用一张〖急筹①〗记录过且未被〖机论②〗记录过的普通锦囊牌并记录此牌牌名。2.失去所有“机论”标记。', + liwei:'李遗', + jiaohua:'教化', + jiaohua_backup:'教化', + jiaohua_info:'出牌阶段限三次,你可以选择一个未被〖教化〗记录过的牌的类型,令一名角色从牌堆中获得一张此类型的牌,然后记录此类型,若基本、锦囊、装备均已被你发动〖教化〗记录,则你清空〖教化〗记录。', + laimin:'来敏', + laishou:'来寿', + laishou_info:'锁定技。①当你受到伤害值大于等于你的体力值的伤害时,若你的体力上限小于9,你防止此伤害并增加等量体力上限。②准备阶段,若你的体力上限不小于9,你死亡。', + luanqun:'乱群', + luanqun_info:'出牌阶段限一次,若你有手牌,则你可以令所有有手牌的角色同时展示一张手牌,然后你可以获得其中一张与你展示的牌颜色相同的展示牌,所有本次展示牌颜色与你展示的牌颜色不同的角色的下个出牌阶段使用的第一张【杀】只能对你使用,且此【杀】不可被响应。', + xin_wuban:'吴班', + xinjintao:'进讨', + xinjintao_info:'锁定技,你使用【杀】无距离限制且次数上限+1。你于出牌阶段内使用的第一张【杀】不可被响应,第二张【杀】伤害+1。', + xinlianhuan:'连环', + xinlianhuan_info:'你可以将一张♣手牌当【铁索连环】使用或重铸。你使用【铁索连环】选择目标后,可以给此牌增加一个目标。', mobile_standard:'手杀异构·标准包', mobile_shenhua_feng:'手杀异构·其疾如风', diff --git a/character/offline.js b/character/offline.js index c9005b9ac..83492160f 100644 --- a/character/offline.js +++ b/character/offline.js @@ -944,6 +944,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, content:function(){ trigger.cancel(); + }, + ai:{ + effect:{ + target:function(card,player,target){ + if(card.name==='sha'&&!game.hasNature(card)&&target.hasEmptySlot(2)) return 'zeroplayertarget'; + if(get.subtype(card)=='equip2'&&target.isEmpty(2)) return [0.6,-0.8]; + } + } } }, //战役篇蒋钦 @@ -983,9 +991,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ preHidden:true, filter:function(event,player){ if(get.type(event.card)!='equip') return false; - var gz=get.mode()=='guozhan'; - if(gz&&event.player.isFriendOf(player)) return false; - return player.countMark('pkwuku')<(gz?2:3); + return player.countMark('pkwuku')<3; }, content:function(){ player.addMark('pkwuku',1); @@ -1978,7 +1984,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, subSkill:{ skip:{ - trigger:{player:'phaseBefore'}, + trigger:{player:'phaseBeforeStart'}, forced:true, priority:Infinity, popup:false, diff --git a/character/rank.js b/character/rank.js index 46186010d..a12dd4e7e 100644 --- a/character/rank.js +++ b/character/rank.js @@ -313,6 +313,7 @@ window.noname_character_rank={ 'dc_sunquan', 'yuechen', 'sunli', + 'dc_zhangmancheng', 'key_misuzu', 'key_sunohara', 'key_umi', @@ -960,6 +961,8 @@ window.noname_character_rank={ 'mengyou', 're_wenpin', 'yue_zhoufei', + 'ns_mengyou', + 'zhangyan', ], b:[ 'diy_feishi', @@ -1969,6 +1972,7 @@ window.noname_character_rank={ 'clan_zhonghui', 'zhoubuyi', 'dc_wangjun', + 'ns_mengyou', 'key_kano', 'key_haruko', 'key_akiko', diff --git a/character/refresh.js b/character/refresh.js index 2b6570733..c5b8ffa42 100755 --- a/character/refresh.js +++ b/character/refresh.js @@ -167,6 +167,62 @@ game.import('character',function(lib,game,ui,get,ai,_status){ re_guohuai:['xiahouyuan','zhanghe'], }, skill:{ + ollianhuan:{ + audio:'xinlianhuan', + audioname:['ol_pangtong'], + hiddenCard:(player,name)=>{ + return name=='tiesuo'&&player.hasCard(card=>get.suit(card)=='club','she'); + }, + filter:function(event,player){ + if(!player.hasCard(card=>get.suit(card)=='club','she')) return false; + return (event.type=='phase'||event.filterCard({name:'tiesuo'},player,event)); + }, + position:'hes', + inherit:'lianhuan', + group:'ollianhuan_add', + subSkill:{ + add:{ + audio:'xinlianhuan', + audioname:['ol_pangtong'], + trigger:{player:'useCard2'}, + filter:function(event,player){ + if(event.card.name!='tiesuo') return false; + var info=get.info(event.card); + if(info.allowMultiple==false) return false; + if(event.targets&&!info.multitarget){ + if(game.hasPlayer(current=>{ + return !event.targets.contains(current)&&lib.filter.targetEnabled2(event.card,player,current); + })) return true; + } + return false; + }, + charlotte:true, + forced:true, + popup:false, + content:function(){ + 'step 0' + player.chooseTarget(get.prompt('ollianhuan'),'为'+get.translation(trigger.card)+'额外指定一个目标',(card,player,target)=>{ + return !_status.event.sourcex.contains(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); + }).set('sourcex',trigger.targets).set('ai',function(target){ + var player=_status.event.player; + return get.effect(target,_status.event.card,player,player); + }).set('card',trigger.card); + 'step 1' + if(result.bool){ + if(!event.isMine()&&!event.isOnline()) game.delayex(); + } + else event.finish(); + 'step 2' + if(result.bool){ + var targets=result.targets; + player.logSkill('ollianhuan_add',targets); + trigger.targets.addArray(targets); + game.log(targets,'也成为了',trigger.card,'的目标'); + } + }, + }, + }, + }, rehuomo:{ audio:'huomo', audioname:['huzhao','re_zhongyao'], @@ -880,15 +936,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, logTarget:'player', check:function(event,player){ - if(get.attitude(player,event.player)<5) return false; - if(player.maxHp-player.hp>=2) return false; - if(player.hp==1) return false; - if(player.hp==2&&player.countCards('h')<2) return false; - if(event.player.countCards('h')>=event.player.hp) return false; - return true; + if(get.attitude(_status.event.player,event.player)<1) return false; + return player.hp>1||player.hasCard(card=>(get.name(card)==='tao'||get.name(card)==='jiu')&&lib.filter.cardEnabled(card,player),'hs'); }, content:function(){ 'step 0' + if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.2); player.draw(2); 'step 1' var cards=player.getCards('he'); @@ -906,7 +959,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger.player.markAuto('rexiantu_check',[player]); }, ai:{ - threaten:1.1, + threaten:function(player,target){ + return 1+game.countPlayer((current)=>{ + if(current!=target&&get.attitude(target,current)>0) return 0.5; + return 0; + }); + }, expose:0.3 }, subSkill:{ @@ -1921,14 +1979,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ audio:2, enable:'phaseUse', filter:function(event,player){ - var hs=player.getCards('h'); + const hs=player.getCards('h'); if(!hs.length) return false; if((player.getStat('skill').reqice||0)>=player.countMark('reqice_mark')+1) return false; - for(var i=0; i{ + const mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); + return (mod2===false) + })) return false; + return lib.inpile.some(name=>{ + if(get.type(name)!='trick') return false; + const card=get.autoViewAs({name},hs); + return event.filterCard(card,player,event); + }); }, chooseButton:{ dialog:function(event,player){ @@ -1939,7 +2001,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return ui.create.dialog(get.translation('reqice'),[list,'vcard']); }, filter:function(button,player){ - return lib.filter.filterCard({name:button.link[2]},player,_status.event.getParent()); + const event=_status.event.getParent(),card=get.autoViewAs({ + name:button.link[2], + },player.getCards('h')); + return event.filterCard(card,player,event); }, check:function(button){ var player=_status.event.player; @@ -1981,6 +2046,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return 13-num; } }, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&!player.getStat('skill').reqice&&player.hasCard((card)=>get.name(card)!='tao','h'); + }, threaten:1.7, }, subSkill:{ @@ -2725,6 +2794,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } return -0.5; } + }, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&player.countSkill('rezhanjue_draw')<3&&player.hasCard((card)=>get.name(card)!='tao'&&!card.hasGaintag('reqinwang'),'h'); } }, }, @@ -4858,8 +4931,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, check:function(event,player){ return (player.countCards('h')+2+event.num)<=5||game.hasPlayer(function(target){ - return !game.hasPlayer(function(current){ - return current!=player&¤t!=target&¤t.countCards('h')0; }); }, @@ -6258,22 +6331,34 @@ game.import('character',function(lib,game,ui,get,ai,_status){ selectCard:[1,Infinity], position:'hs', check:function(card){ - var player=_status.event.player; - if(ui.selected.cards.length){ - var list=game.filterPlayer(function(current){ - return current!=player&&player.canUse('sha',current,false)&&get.effect(current,{name:'sha'},player,player)>0; - }).sort(function(a,b){ - return get.effect(b,{name:'sha'},player,player)-get.effect(a,{name:'sha'},player,player); + let player = _status.event.player; + if (ui.selected.cards.length) { + let list = game.filterPlayer(function (current) { + return current !== player && player.canUse('sha', current, false) && get.effect(current, {name: 'sha'}, player, player) > 0; + }).sort(function (a, b) { + return get.effect(b, {name: 'sha'}, player, player) - get.effect(a, {name: 'sha'}, player, player); }); - if(!list.length) return 0; - var target=list[0]; - if(target.mayHaveShan()&&!player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card, - },true)) return 0; - return 6.5-get.value(card); + if (!list.length) return 0; + let target = list[0], + cards = ui.selected.cards.concat([card]), + color = []; + for (let i of cards) { + if (!color.includes(get.color(i, player))) color.add(get.color(i, player)); + } + if (color.length !== 1) color[0] = 'none'; + if (player.hasSkillTag( + 'directHit_ai', + true, + { + target: target, + card: {name: 'sha', suit: 'none', color: color[0], cards: cards, isCard: true} + }, + true + )) return 6.5 - get.value(card, player); + if (Math.random() * target.countCards('hs') < 1 || player.needsToDiscard(-ui.selected.cards.length)) return 6 - get.value(card, player); + return 0; } - return 6.3-get.value(card); + return 6.3 - get.value(card); }, onuse:function(result,player){ player.addTempSkill('changbiao_draw'); @@ -6305,6 +6390,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return card.name!='sha'&&get.value(card,player)<6.3; },'hs')?1:0)>1?-1:1); }, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep'){ + let num=0; + if(arg&&(!arg.card||get.name(arg.card)!=='tao')) return false; + player.getHistory('sourceDamage',function(evxt){ + let evt=evxt.getParent(); + if(evt&&evt.name=='sha'&&evt.skill=='changbiao') num+=evt.cards.length; + }); + return player.needsToDiscard(num)>0; + } + } }, }, //国钟会 @@ -7492,9 +7589,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ "step 0" target.chooseToDiscard(cards.length,'弃置'+get.cnNumber(cards.length)+'张牌并失去1点体力,或点取消将武将牌翻面并摸'+get.cnNumber(cards.length)+'张牌','he').set('ai',function(card){ - var player=_status.event.player; - if(player.isTurnedOver()) return -1; - return (player.hp*player.hp)-get.value(card); + if(cards.length>3||target.hasSkillTag('noturn')||target.isTurnedOver()||(get.name(card)=='tao'||get.name(card)=='jiu')&&lib.filter.cardSavable(card,target,target)) return -1; + if(target.hp<=1){ + if(cards.length{ + return (get.name(cardx)=='tao'||get.name(cardx)=='jiu')&&lib.filter.cardSavable(cardx,target,target); + },'hs')) return 7-get.value(card); + return -1; + } + return 24-5*cards.length-2*Math.min(4,target.hp)-get.value(card); }); "step 1" if(!result.bool){ @@ -7505,7 +7607,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, ai:{ order:2, - expose:0.3, threaten:1.8, result:{ target:function(player,target){ @@ -10847,34 +10948,40 @@ game.import('character',function(lib,game,ui,get,ai,_status){ useShan:true, effect:{ target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&&!player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card, - },true)){ - var hastarget=game.hasPlayer(function(current){ - return get.attitude(target,current)<0; - }); - var be=target.countCards('e',{color:'black'}); - if(target.countCards('h','shan')&&be){ - if(!target.hasSkill('xinguidao')) return 0; - return [0,hastarget?target.countCards('he')/2:0]; - } - if(target.countCards('h','shan')&&target.countCards('h')>2){ - if(!target.hasSkill('xinguidao')) return 0; - return [0,hastarget?target.countCards('h')/4:0]; - } - if(target.countCards('h')>3||(be&&target.countCards('h')>=2)){ - return [0,0]; - } - if(target.countCards('h')==0){ - return [1.5,0]; - } - if(target.countCards('h')==1&&!be){ - return [1.2,0]; - } - if(!target.hasSkill('xinguidao')) return [1,0.05]; - return [1,Math.min(0.5,(target.countCards('h')+be)/4)]; + let name='sha'; + if(typeof card=='object'){ + if(card.viewAs) name=card.viewAs; + else name=get.name(card); } + if(name=='shandian'||get.tag(card,'respondShan')&&!player.hasSkillTag('directHit_ai',true,{ + target: target, + card: card + },true)){ + let club=0,spade=0; + if(game.hasPlayer(function(current){ + return get.attitude(target,current)<0&&get.damageEffect(current,target,target,'thunder')>0; + })){ + club=2; + spade=4; + } + if(!target.isHealthy()) club+=2; + if(!club&&!spade) return 1; + if(!target.mayHaveShan(player)) return 1-0.1*Math.min(5,target.countCards('hs')); + if(!target.hasSkillTag('rejudge')) return [1,(club+spade)/4]; + let pos=(player==target||player.hasSkillTag('viewHandcard',null,target,true))?'hes':'e',better=club>spade?'club':'spade',max=0; + target.hasCard(function(cardx){ + if(get.suit(cardx)==better){ + max=2; + return true; + } + if(spade&&get.color(cardx)=='black') max=1; + },pos); + if(max==2) return [1,Math.max(club,spade)]; + if(max==1) return [1,Math.min(club,spade)]; + if(pos=='e') return [1,Math.min(Math.max(1,target.countCards('hs'))*(club+spade)/4,Math.max(club,spade))]; + return [1,(club+spade)/4]; + } + if(name=='lebu'||name=='bingliang') return [target.hasSkillTag('rejudge')?0.4:1,2,target.hasSkillTag('rejudge')?0.4:1,0]; } } } @@ -10910,6 +11017,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, xinguidao:{ audio:2, + mod:{ + aiOrder:function(player,card,num){ + if(num>0&&get.itemtype(card)=='card'&&get.color(card)=='black'&&get.type(card)=='equip') num*1.35; + }, + aiValue:function(player,card,num){ + if(num>0&&get.itemtype(card)=='card'&&get.color(card)=='black') return num*1.15; + }, + aiUseful:function(player,card,num){ + if(num>0&&get.itemtype(card)=='card'&&get.color(card)=='black') return num*1.35; + } + }, + locked:false, trigger:{global:'judge'}, filter:function(event,player){ return player.countCards('hes',{color:'black'})>0; @@ -11087,7 +11206,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, prompt:"将一张红色牌当火攻使用", check:function (card){ - var player=_status.currentPhase; + var player=get.player(); if(player.countCards('h')>player.hp){ return 6-get.value(card); } @@ -12239,6 +12358,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ rezhiheng:{ audio:2, audioname:['shen_caopi'], + mod:{ + aiOrder:function(player,card,num){ + if(num<=0||get.itemtype(card)!=='card'||get.type(card)!=='equip') return num; + let eq=player.getEquip(get.subtype(card)); + if(eq&&get.equipValue(card)-get.equipValue(eq)get.value(i)>Math.max(6,9-player.hp),'he')) return 1; + return 10; + }, result:{ player:1 }, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg&&arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&!player.getStat().skill.rezhiheng&&player.hasCard((card)=>get.name(card)!=='tao','h'); + }, threaten:1.55 }, }, @@ -14521,7 +14655,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ reqiangxi:"强袭", "reqiangxi_info":"出牌阶段对每名其他角色限一次,你可以选择一项:1. 失去一点体力并对你攻击范围内的一名其他角色造成一点伤害;2. 弃置一张武器牌并对你攻击范围内的一名其他角色造成一点伤害。", rehuoji:"火计", - rehuoji_info:"出牌阶段,你可一张红色牌当作【火攻】使用。", + rehuoji_info:"你可一张红色牌当作【火攻】使用。", rekanpo:"看破", rekanpo_info:"你可以将一张黑色牌当作【无懈可击】使用。", reshuangxiong:"双雄", @@ -15244,6 +15378,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ zhoutai_prefix:'界', caoren:'界曹仁', caoren_prefix:'界', + ollianhuan:'连环', + ollianhuan_info:'你可以将一张♣牌当【铁索连环】使用或重铸。你使用【铁索连环】选择目标后,可以给此牌增加一个目标。', refresh_standard:'界限突破·标', refresh_feng:'界限突破·风', diff --git a/character/sb.js b/character/sb.js index f11ea3c0b..1adb01f4b 100644 --- a/character/sb.js +++ b/character/sb.js @@ -38,6 +38,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sb_liubiao:['male','qun',3,['sbzishou','sbzongshi']], sb_zhurong:['female','shu',4,['sblieren','sbjuxiang']], sb_menghuo:['male','shu',4,['sbhuoshou','sbzaiqi']], + sb_yl_luzhi:['male','qun',3,['nzry_mingren','sbzhenliang']], + sb_xiaoqiao:['female','wu',3,['sbtianxiang','xinhongyan']], }, characterSort:{ sb:{ @@ -49,6 +51,185 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, skill:{ + //卢植 + sbzhenliang:{ + mark:true, + locked:false, + zhuanhuanji:true, + marktext:'☯', + intro:{ + content:function(storage,player){ + if(storage) return '你的回合外,一名角色使用或打出牌结算完成后,若此牌与“任”类别相同,则你可以令一名角色摸一张牌。'; + return '出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。'; + }, + }, + audio:2, + enable:'phaseUse', + filter:function(event,player){ + if(player.storage.sbzhenliang) return false; + var storage=player.getExpansions('nzry_mingren'); + if(!storage.length) return false; + var color=get.color(storage[0]); + return game.hasPlayer(function(current){ + return player.inRange(current)&&player.countCards('he',function(card){ + return get.color(card)==color; + })>=Math.max(1,Math.abs(player.getHp()-current.getHp())); + }); + }, + filterCard:function(card,player){ + return get.color(card)==get.color(player.getExpansions('nzry_mingren')[0]); + }, + selectCard:[1,Infinity], + complexSelect:true, + complexCard:true, + position:'he', + filterTarget:function(card,player,target){ + return player.inRange(target)&&ui.selected.cards.length==Math.max(1,Math.abs(player.getHp()-target.getHp())); + }, + check:function(card){ + return 6.5-get.value(card); + }, + prompt:'弃置与攻击范围内的一名角色体力值之差(至少为1)张与“任”颜色相同的牌,对其造成1点伤害。', + content:function(){ + player.changeZhuanhuanji('sbzhenliang'); + target.damage('nocard'); + }, + ai:{ + order:5, + result:{ + player:function(player,target){ + return get.damageEffect(target,player,player); + }, + }, + }, + group:'sbzhenliang_draw', + subSkill:{ + draw:{ + trigger:{global:['useCardAfter','respondAfter']}, + filter:function(event,player){ + if(_status.currentPhase==player||!player.storage.sbzhenliang) return false; + var card=player.getExpansions('nzry_mingren')[0]; + return card&&get.type2(event.card)==get.type2(card); + }, + direct:true, + content:function(){ + 'step 0' + player.chooseTarget(get.prompt('sbzhenliang'),'令一名角色摸一张牌').set('ai',function(target){ + if(target.hasSkillTag('nogain')) return 0.1; + var att=get.attitude(player,target); + return att*(Math.max(5-target.countCards('h'),2)+3); + }); + 'step 1' + if(result.bool){ + var target=result.targets[0]; + player.changeZhuanhuanji('sbzhenliang'); + player.logSkill('sbzhenliang',target); + target.draw(); + } + }, + }, + }, + ai:{combo:'nzry_mingren'}, + }, + //小乔 + sbtianxiang:{ + audio:2, + enable:'phaseUse', + filter:function(event,player){ + return player.countCards('he',card=>lib.skill.sbtianxiang.filterCard(card,player))&&game.hasPlayer(target=>lib.skill.sbtianxiang.filterTarget(null,player,target)); + }, + filterCard:function(card,player){ + return get.color(card,player)=='red'; + }, + filterTarget:function(card,player,target){ + return target!=player&&!target.getSkills().some(skill=>skill.indexOf('sbtianxiang_')==0); + }, + discard:false, + lose:false, + delay:0, + usable:3, + prompt:'将一张红色牌交给一名角色并令其获得此花色的“天香”标记', + content:function(){ + player.give(cards,target); + var suit=get.suit(cards[0],player); + target.addSkill('sbtianxiang_'+suit); + }, + ai:{ + order:5, + result:{target:-1}, + }, + group:['sbtianxiang_draw','sbtianxiang_effect'], + subSkill:{ + heart:{ + charlotte:true, + mark:true, + marktext:'♥︎', + intro:{content:'伤害转移术'}, + }, + diamond:{ + charlotte:true, + mark:true, + marktext:'♦︎', + intro:{content:'掳掠大法'}, + }, + draw:{ + audio:'sbtianxiang', + trigger:{player:'phaseZhunbeiBegin'}, + filter:function(event,player){ + return game.hasPlayer(target=>target.getSkills().some(skill=>skill.indexOf('sbtianxiang_')==0)); + }, + forced:true, + locked:false, + content:function(){ + var num=0; + game.countPlayer(target=>{ + var skills=target.getSkills().filter(skill=>skill.indexOf('sbtianxiang_')==0); + target.removeSkill(skills); + num+=skills.length; + }); + player.draw(num); + }, + }, + effect:{ + trigger:{player:'damageBegin3'}, + filter:function(event,player){ + return game.hasPlayer(target=>target.getSkills().some(skill=>skill.indexOf('sbtianxiang_')==0)); + }, + direct:true, + content:function(){ + 'step 0' + player.chooseTarget(get.prompt('sbtianxiang'),'移去一名角色的“天香”标记并执行相应效果',function(card,player,target){ + return target.getSkills().some(skill=>skill.indexOf('sbtianxiang_')==0); + }).set('ai',target=>{ + var player=_status.event.player; + return -get.attitude(player,target)*target.getSkills().filter(skill=>skill.indexOf('sbtianxiang_')==0).length; + }); + 'step 1' + if(result.bool){ + var target=result.targets[0]; + event.target=target; + player.logSkill('sbtianxiang',target); + var skills=target.getSkills().filter(skill=>skill.indexOf('sbtianxiang_')==0); + target.removeSkill(skills); + if(skills.contains('sbtianxiang_heart')){ + target.damage(trigger.source?trigger.source:'nosource'); + trigger.cancel(); + } + if(skills.contains('sbtianxiang_diamond')){ + var cards=target.getCards('he'); + if(!cards.length) event.finish(); + else if(cards.length<=2) event._result={bool:true,cards:cards}; + else target.chooseCard('he',2,'天香:交给'+get.translation(player)+'两张牌',true); + } + else event.finish(); + } + else event.finish(); + 'step 2' + if(result.bool) player.gain(result.cards,target,'giveAuto'); + }, + }, + }, + }, //张郃 sbqiaobian:{ audio:2, @@ -240,7 +421,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 0' player.chooseTarget(get.prompt('sbzaiqi'),'选择任意名角色并消耗等量蓄力值,令这些角色选择一项:1.令你摸一张牌;2.弃置一张牌,然后你回复1点体力',[1,player.countMark('charge')]).set('ai',function(target){ var player=_status.event.player; - return get.attitude(player,target)+player.getDamagedHp()*3.5; + var att=get.attitude(player,target); + return 3-get.sgn(att)+Math.abs(att/1000); }); 'step 1' if(result.bool){ @@ -275,19 +457,19 @@ game.import('character',function(lib,game,ui,get,ai,_status){ backflow:{ audio:'sbzaiqi', trigger:{ - player:'enterGame', + //player:'enterGame', source:'damageSource', - global:'phaseBefore', + //global:'phaseBefore', }, usable:1, - forced:true, - locked:false, filter:function(event,player){ if(event.name=='damage') return true; return (event.name!='phase'||game.phaseNumber==0); }, + forced:true, + locked:false, content:function(){ - player.addMark('charge',1); + player.addMark('charge',trigger.name=='damage'?1:3); } } } @@ -333,7 +515,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var target=trigger.card.storage.sblieren[1]; player.chooseTarget('烈刃:是否对除'+get.translation(target)+'外的一名其他角色造成1点伤害?',(card,player,target)=>{ return target!=_status.event.targeted&&target!=player; - }).set('targeted',target); + }).set('targeted',target).set('ai',targetx=>get.damageEffect(targetx,_status.event.player,_status.event.player)); 'step 1' if(result.bool){ var target=result.targets[0]; @@ -518,7 +700,19 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } return event.filterCard(get.autoViewAs({name:'juedou'},hs)); }, - ai:{order:0.001}, + ai:{ + order:0.001, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep'){ + if(arg&&(!arg.card||get.name(arg.card)!=='tao')) return false; + let limit=player.hasMark('sbjiang')?(game.countPlayer(current=>{ + return current.group=='wu'&¤t!=player; + })+1):1; + return player.isPhaseUsing()&&(player.getStat('skill').sbjiang_qiben||0)get.name(card)!='tao','h'); + } + } + }, } }, }, @@ -3551,10 +3745,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(result.bool){ var target=result.targets[0],card=result.cards[0]; player.logSkill('sbkurou',target); + if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.15); player.give(card,target); player.loseHp(['tao','jiu'].contains(get.name(card,target))?2:1); } }, + ai:{ + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg.card&&get.name(arg.card)==='tao')&&player.hp<=0&&player.isPhaseUsing(); + } + }, subSkill:{ gain:{ audio:'sbkurou', @@ -3626,6 +3827,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ subSkill:{ draw:{ audio:'sbzhaxiang', + mod:{ + aiOrder:function(player,card,num){ + if(num>0&&_status.event&&_status.event.type=='phase'&&get.tag(card,'recover')) return num/5; + } + }, trigger:{player:'phaseDrawBegin2'}, forced:true, filter:function(event,player){ @@ -3637,7 +3843,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ai:{ effect:{ target:function(card,player,target){ - if(get.tag(card,'recover')&&target.hp>=target.maxHp-1&&target.maxHp>1) return [0,0]; + if(get.tag(card,'recover')&&target.hp>0&&target.needsToDiscard()<1) return [0,0]; } } } @@ -3648,6 +3854,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sbzhiheng:{ audio:2, audioname:['shen_caopi'], + mod:{ + aiOrder:function(player,card,num){ + if(num<=0||get.itemtype(card)!=='card'||get.type(card)!=='equip') return num; + let eq=player.getEquip(get.subtype(card)); + if(eq&&get.equipValue(card)-get.equipValue(eq)get.value(i)>Math.max(6,9-player.hp),'he')) return 1; + return 10; + }, result:{ player:1 }, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg&&arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&!player.getStat().skill.sbzhiheng&&player.hasCard((card)=>get.name(card)!=='tao','h'); + }, threaten:1.56 }, }, @@ -3703,7 +3923,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ onremove:true, content:function(){ 'step 0' - player.chooseControl('变化','不变').set('prompt','统业:猜测场上装备数是否于你下回合准备阶段前发生变化').set('ai',()=>Number((game.countPlayer()<=4?Math.random():1)<0.4)); + player.chooseControl('变化','不变').set('prompt','统业:猜测场上装备数是否于你下回合准备阶段前发生变化').set('ai',()=>{ + let player = _status.event.player; + if(game.countPlayer() > 3) return '变化'; + if(game.countPlayer(function (current){ + return current.hasCard({type: 'equip'}, 'e'); + }) < game.countPlayer()) return '变化'; + if(game.countPlayer() == 2 && game.countPlayer(function (current){ + if (current != player) return current.countCards('e', {type: 'equip'}) + current.countDisabledSlot(); + }) >= 5) return '不变'; + if(Math.random() < 0.3) return '变化'; + return '不变'; + }); 'step 1' if(result.control=='变化'){ player.addSkill('sbtongye_change',1); @@ -4242,7 +4473,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //华雄 sbyangwei:{ - audio:2, + audio:3, enable:'phaseUse', filter:function(event,player){ return !player.hasSkill('sbyangwei_counter',null,null,false); @@ -4882,10 +5113,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sbhuoshou:'祸首', sbhuoshou_info:'锁定技。①【南蛮入侵】对你无效。②当其他角色使用【南蛮入侵】指定第一个目标后,你代替其成为此牌的伤害来源。③出牌阶段开始时,你随机获得弃牌堆中的一张【南蛮入侵】。④出牌阶段,若你于此阶段使用过【南蛮入侵】,你不能使用【南蛮入侵】。', sbzaiqi:'再起', - sbzaiqi_info:'蓄力技(1/7)。①弃牌阶段结束时,你可以消耗任意点蓄力值并选择等量名角色,然后令这些角色选择一项:1.令你摸一张牌;2.弃置一张牌,然后你回复1点体力。②每回合限一次。当你造成伤害后,你获得1点蓄力值。', + sbzaiqi_info:'蓄力技(0/7)。①弃牌阶段结束时,你可以消耗任意点蓄力值并选择等量名角色,然后令这些角色选择一项:1.令你摸一张牌;2.弃置一张牌,然后你回复1点体力。②每回合限一次。当你造成伤害后,你获得1点蓄力值。', sb_zhanghe:'谋张郃', sbqiaobian:'巧变', sbqiaobian_info:'每回合限一次。①你可以失去1点体力并跳过判定阶段,将判定区的所有牌移动给一名其他角色(无法置入其判定区的牌改为弃置之)。②你可以跳过摸牌阶段,于下个准备阶段摸两张牌并回复1点体力。③你可以将手牌数弃置至六张(若手牌数少于六张则跳过之)并跳过出牌阶段和弃牌阶段,然后移动场上的一张牌。', + sb_yl_luzhi:'谋卢植', + sb_yl_luzhi_prefix:'谋', + sbzhenliang:'贞良', + sbzhenliang_info:'转换技。阴:出牌阶段限一次,你可以弃置X张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害(X为你与其体力值值差且X至少为1)。阳:你的回合外,一名角色使用或打出牌结算完成后,若此牌与“任”类别相同,则你可以令一名角色摸一张牌。', + sb_xiaoqiao:'谋小乔', + sb_xiaoqiao_prefix:'谋', + sbtianxiang:'天香', + sbtianxiang_info:'①出牌阶段限三次,你可以交给一名没有“天香”标记的其他角色一张红色牌,然后令其获得此牌花色的“天香”标记。②当你受到伤害时,你可以移去一名角色的“天香”标记,若此“天香”标记为:红桃,你防止此伤害,其受到伤害来源对其造成的1点伤害(若没有伤害来源则改为无来源伤害);方片,其交给你两张牌。③准备阶段,你移去场上所有的“天香”标记,然后摸等量的牌。', sb_zhi:'谋攻篇·知', sb_shi:'谋攻篇·识', diff --git a/character/shenhua.js b/character/shenhua.js index 2921d8533..50686fa68 100755 --- a/character/shenhua.js +++ b/character/shenhua.js @@ -141,6 +141,82 @@ game.import('character',function(lib,game,ui,get,ai,_status){ "chendao":"陈到,字叔至,生卒年不详,豫州汝南(今河南驻马店平舆县)人。三国时期蜀汉将领,刘备帐下白毦兵统领,名位常亚于赵云,以忠勇著称。蜀汉建兴年间,任征西将军、永安都督,封亭侯。在任期间去世。", }, skill:{ + //庞统写法修改 + lianhuan:{ + audio:'lianhuan1', + hiddenCard:(player,name)=>{ + return name=='tiesuo'&&player.hasCard(card=>get.suit(card)=='club','sh'); + }, + enable:'chooseToUse', + filter:function(event,player){ + if(!player.hasCard(card=>get.suit(card)=='club','sh')) return false; + return (event.type=='phase'||event.filterCard({name:'tiesuo'},player,event)); + }, + position:'hs', + filterCard:function(card,player,event){ + if(!event) event=_status.event; + if(get.suit(card)!='club') return false; + if(event.type=='phase'&&get.position(card)!='s'&&player.canRecast(card)){ + return true; + } + else{ + if(game.checkMod(card,player,'unchanged','cardEnabled2',player)===false) return false; + const cardx=get.autoViewAs({name:'tiesuo'},[card]); + return event._backup.filterCard(cardx,player,target); + } + }, + filterTarget:function(fuck,player,target){ + const card=ui.selected.cards[0],event=_status.event,backup=event._backup; + if(!card||game.checkMod(card,player,'unchanged','cardEnabled2',player)===false) return false; + const cardx=get.autoViewAs({name:'tiesuo'},[card]); + return (backup.filterCard(cardx,player,event)&&backup.filterTarget(cardx,player,target)); + }, + selectTarget:function(){ + const card=ui.selected.cards[0],event=_status.event,player=event.player,backup=event._backup; + let recast=false,use=false; + const cardx=get.autoViewAs({name:'tiesuo'},[card]); + if(event.type=='phase'&&player.canRecast(card)) recast=true; + if(game.checkMod(card,player,'unchanged','cardEnabled2',player)!==false){ + if(backup.filterCard(cardx,player,event)) use=true; + } + if(!use) return [0,0]; + else{ + const select=backup.selectTarget(cardx,player); + if(recast&&select[0]>0) select[0]=0; + return select; + } + }, + filterOk:function(){ + const card=ui.selected.cards[0],event=_status.event,player=event.player,backup=event._backup; + const selected=ui.selected.targets.length; + let recast=false,use=false; + const cardx=get.autoViewAs({name:'tiesuo'},[card]); + if(event.type=='phase'&&player.canRecast(card)) recast=true; + if(game.checkMod(card,player,'unchanged','cardEnabled2',player)!==false){ + if(backup.filterCard(cardx,player,event)) use=true; + } + if(recast&&selected==0){ + return true; + } + else if(use){ + const select=backup.selectTarget(cardx,player); + if(select[0]<=-1) return true; + return selected>=select[0]&&selected<=select[1]; + } + }, + discard:false, + lose:false, + delay:false, + precontent:function(){ + var result=event.result; + if(result.targets.length>0) result.card=get.autoViewAs({name:'tiesuo'},result.cards); + }, + content:function(){ + player.recast(cards); + }, + }, + lianhuan1:{audio:2}, + lianhuan2:{audio:2}, //新杀小加强 陈到 dcwanglie:{ audio:'drlt_wanglie', @@ -2270,6 +2346,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, nzry_mingren:{ audio:"nzry_mingren_1", + audioname:['sb_yl_luzhi'], marktext:"任", intro:{ content:'expansion', @@ -2283,6 +2360,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ subSkill:{ 1:{ audio:2, + audioname:['sb_yl_luzhi'], trigger:{ global:'phaseBefore', player:'enterGame', @@ -2307,7 +2385,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, 2:{ - audio:2, trigger:{ player:'phaseJieshuBegin', }, @@ -2317,7 +2394,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ direct:true, content:function(){ 'step 0' - player.chooseCard('h','是否用一张手牌替换“任”('+get.translation(player.getExpansions('nzry_mingren')[0])+')?').set('ai',function(card){ + player.chooseCard('h',get.prompt('nzry_mingren'),'选择一张手牌替换“任”('+get.translation(player.getExpansions('nzry_mingren')[0])+')').set('ai',function(card){ var player=_status.event.player; var color=get.color(card); if(color==get.color(player.getExpansions('nzry_mingren')[0])) return false; @@ -2901,62 +2978,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } }, - ollianhuan:{ - audio:'xinlianhuan', - audioname:['ol_pangtong'], - group:['ollianhuan3','ollianhuan5','lianhuan4'], - }, - ollianhuan5:{ - inherit:'lianhuan2', - audioname:['ol_pangtong'], - audio:['xinlianhuan',2], - position:'he', - filter:function(event,player){ - return player.countCards('he',{suit:'club'})>0; - }, - }, - ollianhuan3:{ - audio:['xinlianhuan',1], - audioname:['ol_pangtong'], - enable:'chooseToUse', - filter:function(event,player){ - return player.countCards('hes',{suit:'club'})>0; - }, - filterCard:{suit:'club'}, - viewAs:{name:'tiesuo'}, - prompt:'将一张梅花牌当铁锁连环使用', - check:function(card){return 6-get.value(card)}, - position:'hes', - }, - xinlianhuan:{ - audio:2, - audioname:['ol_pangtong'], - group:['lianhuan3','lianhuan5','lianhuan4'], - }, - lianhuan5:{ - inherit:'lianhuan2', - audioname:['ol_pangtong'], - audio:['xinlianhuan',2], - }, - lianhuan3:{ - audio:['xinlianhuan',1], - audioname:['ol_pangtong'], - enable:'chooseToUse', - filter:function(event,player){ - return player.countCards('hs',{suit:'club'})>0; - }, - filterCard:{suit:'club'}, - viewAs:{name:'tiesuo'}, - prompt:'将一张梅花牌当铁锁连环使用', - check:function(card){return 6-get.value(card)}, - }, - lianhuan4:{ - mod:{ - selectTarget:function(card,player,range){ - if(card.name=='tiesuo'&&range[1]!=-1) range[1]++; - }, - }, - }, reluanji:{ audio:2, enable:'phaseUse', @@ -3156,13 +3177,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, xinkuanggu:{ - trigger:{source:'damageSource'}, - filter:function(event,player){ - return get.distance(player,event.player)<=1&&event.num>0; - }, - direct:true, audio:'kuanggu', audioname:['re_weiyan','ol_weiyan'], + trigger:{source:'damageSource'}, + filter:function(event,player){ + return event.kuangguCheck&&event.num>0; + }, + direct:true, preHidden:true, content:function(){ 'step 0' @@ -3177,7 +3198,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ else{ choice='draw_card'; } - var next=player.chooseDrawRecover(get.prompt(event.name)).set('logSkill',event.name).set('prompt2','摸一张牌或回复1点体力'); + var next=player.chooseDrawRecover('###'+get.prompt(event.name)+'###摸一张牌或回复1点体力').set('logSkill',event.name); next.set('choice',choice); next.set('ai',function(){ return _status.event.getParent().choice; @@ -3190,7 +3211,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ event.goto(1); } } - } + }, + group:'kuanggu_check', }, xinliegong:{ shaRelated:true, @@ -3803,6 +3825,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ audio:2, preHidden:true, audioname:['sp_lvmeng','re_sunben','re_sunce'], + mod:{ + aiOrder:function(player,card,num){ + if(get.color(card)==='red'&&get.name(card)==='sha') return get.order({name: 'sha'})+0.15; + } + }, trigger:{ player:'useCardToPlayered', target:'useCardToTargeted', @@ -3811,6 +3838,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(!(event.card.name=='juedou'||(event.card.name=='sha'&&get.color(event.card)=='red'))) return false; return player==event.target||event.getParent().triggeredTargets3.length==1; }, + locked:false, frequent:true, content:function(){ player.draw(); @@ -4871,9 +4899,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, preHidden:true, check:function(event,player){ - if(player.countCards('h')<=1) return true; - return game.hasPlayer(function(current){ - return current!=player&¤t.isMinHandcard()&&get.attitude(player,current)>0; + return (player.countCards('h')+2+event.num)<=5||game.hasPlayer(function(target){ + return player!==target&&!game.hasPlayer(function(current){ + return current!==player&¤t!==target&¤t.countCards('h')0; }); }, content:function(){ @@ -5030,6 +5059,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ re_sunyi:'gzyinghun_re_sunyi', tw_ol_sunjian:'yinghun_ol_sunjian', }, + mod:{ + aiOrder:function(player,card,num){ + if(num>0&&_status.event&&_status.event.type=='phase'&&get.tag(card,'recover')){ + if(player.needsToDiscard()) return num/3; + return 0; + } + } + }, + locked:false, trigger:{player:'phaseZhunbeiBegin'}, direct:true, preHidden:true, @@ -5081,6 +5119,20 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(event.num>0) event.target.chooseToDiscard(event.num,true,'he'); } }, + ai:{ + effect:{ + target:function(card,player,target){ + if(get.tag(card,'damage')&&get.itemtype(player)==='player'&&target.hp>(player.hasSkillTag('damageBonus',true,{ + target:target, + card:card + })?2:1)) return [1,1]; + } + }, + threaten:function(player,target){ + return Math.max(0.5,target.getDamagedHp()/2); + }, + maixie:true + } }, gzyinghun:{ audio:'yinghun', @@ -5089,6 +5141,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ re_sunyi:'gzyinghun_re_sunyi', tw_ol_sunjian:'yinghun_ol_sunjian', }, + mod:{ + aiOrder:function(player,card,num){ + if(num>0&&_status.event&&_status.event.type=='phase'&&get.tag(card,'recover')){ + if(player.needsToDiscard()) return num/3; + return 0; + } + } + }, + locked:false, trigger:{player:'phaseZhunbeiBegin'}, filter:function(event,player){ return player.getDamagedHp()>0; @@ -5143,13 +5204,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, ai:{ - threaten:function(player,target){ - if(target.hp==target.maxHp) return 0.5; - if(target.hp==1) return 2; - if(target.hp==2) return 1.5; - return 0.5; + effect:{ + target:function(card,player,target){ + if(get.tag(card,'damage')&&get.itemtype(player)==='player'&&target.hp>(player.hasSkillTag('damageBonus',true,{ + target:target, + card:card + })?2:1)) return [1,1]; + } }, - maixie:true, + threaten:function(player,target){ + return Math.max(0.5,target.getDamagedHp()/2); + }, + maixie:true } }, yinghun_ol_sunjian:{audio:2}, @@ -5405,7 +5471,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, huoji:{ audio:2, - enable:'phaseUse', + enable:'chooseToUse', filterCard:function(card){ return get.color(card)=='red'; }, @@ -5416,7 +5482,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ position:'hs', prompt:'将一张红色牌当火攻使用', check:function(card){ - var player=_status.currentPhase; + var player=get.player(); if(player.countCards('h')>player.hp){ return 6-get.value(card); } @@ -5498,50 +5564,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, threaten:1.2 }, - lianhuan:{ - audio:'lianhuan1', - group:['lianhuan1','lianhuan2'] - }, - lianhuan1:{ - audio:2, - audioname:['re_pangtong'], - enable:'chooseToUse', - filter:function(event,player){ - return player.countCards('hs',{suit:'club'})>0; - }, - position:'hs', - filterCard:function(card){ - return get.suit(card)=='club'; - }, - viewAs:{name:'tiesuo'}, - prompt:'将一张梅花牌当铁锁连环使用', - check:function(card){return 4.5-get.value(card)} - }, - lianhuan2:{ - audio:2, - popup:'lianhuan', - enable:'phaseUse', - filter:(event,player)=>player.hasCard(card=>lib.skill.lianhuan2.filterCard(card,player),'h'), - filterCard:(card,player)=>get.suit(card)=='club'&&player.canRecast(card), - check:function(card){ - return 5-get.useful(card); - }, - content:function(){ - player.recast(cards); - }, - discard:false, - lose:false, - delay:false, - prompt:'将一张梅花牌置入弃牌堆并摸一张牌', - ai:{ - basic:{ - order:1 - }, - result:{ - player:1 - } - } - }, niepan:{ audio:2, audioname:['re_pangtong'], @@ -6238,30 +6260,33 @@ game.import('character',function(lib,game,ui,get,ai,_status){ useShan:true, effect:{ target:function(card,player,target,current){ - if(get.tag(card,'respondShan')){ - var hastarget=game.hasPlayer(function(current){ - return get.attitude(target,current)<0; - }); - var be=target.countCards('e',{color:'black'}); - if(target.countCards('h','shan')&&be){ - if(!target.hasSkill('guidao')) return 0; - return [0,hastarget?target.countCards('he')/2:0]; + if(get.tag(card,'respondShan')&&!player.hasSkillTag('directHit_ai',true,{ + target: target, + card: card + },true)){ + let club=0,spade=0; + if(game.hasPlayer(function(current){ + return get.attitude(target,current)<0&&get.damageEffect(current,target,target,'thunder')>0; + })){ + club=2; + spade=4; } - if(target.countCards('h','shan')&&target.countCards('h')>2){ - if(!target.hasSkill('guidao')) return 0; - return [0,hastarget?target.countCards('h')/4:0]; - } - if(target.countCards('h')>3||(be&&target.countCards('h')>=2)){ - return [0,0]; - } - if(target.countCards('h')==0){ - return [1.5,0]; - } - if(target.countCards('h')==1&&!be){ - return [1.2,0]; - } - if(!target.hasSkill('guidao')) return [1,0.05]; - return [1,Math.min(0.5,(target.countCards('h')+be)/4)]; + if(!target.isHealthy()) club+=2; + if(!club&&!spade) return 1; + if(!target.mayHaveShan(player)) return 1-0.1*Math.min(5,target.countCards('hs')); + if(!target.hasSkillTag('rejudge')) return [1,(club+spade)/4]; + let pos=player.hasSkillTag('viewHandcard',null,target,true)?'hes':'e',better=club>spade?'club':'spade',max=0; + target.hasCard(function(cardx){ + if(get.suit(cardx)===better){ + max=2; + return true; + } + if(spade&&get.color(cardx)==='black') max=1; + },pos); + if(max===2) return [1,Math.max(club,spade)]; + if(max===1) return [1,Math.min(club,spade)]; + if(pos==='e') return [1,Math.min(Math.max(1,target.countCards('hs'))*(club+spade)/4,Math.max(club,spade))]; + return [1,(club+spade)/4]; } } } @@ -6458,11 +6483,26 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger:{source:'damageSource'}, forced:true, filter:function(event,player){ - return get.distance(player,event.player)<=1&&player.isDamaged(); + return event.kuangguCheck&&player.isDamaged(); }, content:function(){ player.recover(trigger.num); - } + }, + group:'kuanggu_check', + subSkill:{ + check:{ + charlotte:true, + trigger:{source:'damage'}, + filter:function(event,player){ + return get.distance(player,event.player)<=1; + }, + firstDo:true, + silent:true, + content:function(){ + trigger.kuangguCheck=true; + }, + }, + }, }, tianxiang:{ audio:2, @@ -6859,6 +6899,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, xinhongyan:{ audio:2, + audioname:['sb_xiaoqiao'], mod:{ suit:function(card,suit){ if(suit=='spade') return 'heart'; @@ -7206,17 +7247,20 @@ game.import('character',function(lib,game,ui,get,ai,_status){ useShan:true, effect:{ target:function(card,player,target,current){ - if(get.tag(card,'respondShan')){ - var hastarget=game.hasPlayer(function(current){ - return get.attitude(target,current)<0; - }); - if(target.countCards('h','shan')&&target.countCards('e',{suit:'spade'})){ - return [0,hastarget?target.countCards('he')/2:0]; - } - if(target.countCards('h','shan')){ - return [1,hastarget?target.countCards('he')/2:0]; - } - return [1,target.countCards('h')/4]; + if(get.tag(card,'respondShan')&&!player.hasSkillTag('directHit_ai',true,{ + target: target, + card: card + },true)&&game.hasPlayer(function(current){ + return get.attitude(target,current)<0&&get.damageEffect(current,target,target,'thunder')>0; + })){ + if(!target.mayHaveShan(player)) return 1-0.1*Math.min(5,target.countCards('hs')); + if(!target.hasSkillTag('rejudge')) return [1,1]; + let pos=player.hasSkillTag('viewHandcard',null,target,true)?'hes':'e'; + if(target.hasCard(function(cardx){ + return get.suit(cardx)==='spade'; + },pos)) return [1,4]; + if(pos==='e') return [1,Math.min(4,1+0.75*Math.max(1,target.countCards('hs')))]; + return [1,1]; } } } @@ -8013,14 +8057,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ huoji:'火计', bazhen:'八阵', kanpo:'看破', - xinlianhuan:'连环', - ollianhuan:'连环', - lianhuan:'连环', - lianhuan1:'连环', - lianhuan3:'连环', - lianhuan2:'连铸', - lianhuan5:'连铸', - ollianhuan3:'连环', niepan:'涅槃', oldniepan:'涅槃', quhu:'驱虎', @@ -8033,12 +8069,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ luanji:'乱击', xueyi:'血裔', mengjin:'猛进', - xinlianhuan_info:' 你可以将一张♣手牌当【铁索连环】使用或重铸。你使用【铁索连环】选择目标的上限数+1。', - ollianhuan_info:' 你可以将一张♣牌当【铁索连环】使用或重铸。你使用【铁索连环】选择目标的上限数+1。', - huoji_info:'出牌阶段,你可以将你的任意一张红色手牌当作【火攻】使用。', + huoji_info:'你可以将一张红色手牌当作【火攻】使用。', bazhen_info:'锁定技,若你的防具栏内没有牌且没有被废除,则你视为装备着【八卦阵】。', kanpo_info:'你可以将你的任意一张黑色手牌当做【无懈可击】使用。', - lianhuan_info:'出牌阶段,你可以将一张♣手牌当做【铁索连环】使用或重铸。', niepan_info:'限定技,出牌阶段或当你处于濒死状态时,你可以弃置你区域内的所有牌并复原你的武将牌,然后摸三张牌并将体力回复至3点。', oldniepan_info:'限定技,当你处于濒死状态时,你可以弃置你区域内的所有牌并复原你的武将牌,然后摸三张牌并将体力回复至3点。', quhu_info:'出牌阶段限一次,你可以与一名体力值大于你的角色拼点,若你赢,则该角色对其攻击范围内另一名由你指定的角色造成1点伤害。若你没赢,该角色对你造成一点伤害。', @@ -8106,7 +8139,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ xinkuanggu:'狂骨', gzbuqu:'不屈', gzbuqu_info:'①当你扣减1点体力时,若你的体力值小于1,你可以将牌堆顶的一张牌置于你的武将牌上,称为“创”。②当你回复1点体力时,你移去一张“创”。③若你有“创”且点数均不相同,则你不结算濒死流程。', - xinkuanggu_info:'当你对距离1以内的一名角色造成1点伤害后,你可以回复1点体力或摸一张牌。', + xinkuanggu_info:'当你造成1点伤害后,若受伤角色受到此伤害时你与其的距离不大于1,则你可以回复1点体力或摸一张牌。', xinliegong_info:'①你使用【杀】可以选择你距离不大于此【杀】点数的角色为目标。②当你使用【杀】指定一个目标后,你可以根据下列条件执行相应的效果:1.其手牌数小于等于你的手牌数,此【杀】不可被响应,2.其体力值大于等于你的体力值,此【杀】伤害+1。', jiewei_info:'当你的武将牌翻面后,你可以摸一张牌。然后你可以使用一张锦囊牌或装备牌,并可以在此牌结算后弃置场上一张同类型的牌', releiji_info:'当你使用或打出一张【闪】时,你可令一名其他角色进行一次判定:若结果为梅花,其受到一点雷电伤害,然后你回复一点体力;若结果为黑桃,其受到两点雷电伤害。', @@ -8115,7 +8148,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ jushou_info:'结束阶段,你可以摸3张牌,并将武将牌翻面。', moon_jushou_info:'结束阶段,你可以摸一张牌,并将武将牌翻面。', liegong_info:'当你使用【杀】时,若目标的手牌数大于等于你的体力值,或小于等于你的攻击范围,你可令此【杀】不能被响应。', - kuanggu_info:'锁定技,当你造成伤害后,若受伤角色与你的距离不大于1,你回复X点体力(X为伤害值)。', + kuanggu_info:'锁定技,当你造成伤害后,若受伤角色受到此伤害时你与其的距离不大于1,你回复X点体力(X为伤害值)。', tianxiang_info:'当你即将受到伤害时,你可以弃置一张♥手牌,将伤害转移给一名其他角色,然后该角色摸X张牌(X为其已损失的体力值)。', hongyan_info:'锁定技,你区域内的黑桃牌和黑桃判定牌均视为红桃。', buqu_info:'锁定技,当你处于濒死状态时,你亮出牌堆顶的一张牌并置于你的武将牌上,称之为“创”。若此牌的点数与你武将牌上已有的“创”点数均不同,则你回复至1体力。若点数相同,则将此牌置入弃牌堆。只要你的武将牌上有“创”,你的手牌上限便与“创”的数量相等。', @@ -8152,6 +8185,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcwanglie_info:"①出牌阶段,你对其他角色使用的前两张牌无距离限制。②当你于出牌阶段内使用牌时,你可以令此牌不能被响应,然后你于本阶段内不能使用牌指定其他角色为目标。", nzry_shicai:"恃才", nzry_shicai_info:"当你使用非装备牌结算结束后,或成为自己使用装备牌的目标后,若此牌与你本回合使用的牌类型均不同,则你可以将此牌置于牌堆顶,然后摸一张牌。", + lianhuan:'连环', + lianhuan_info:'你可以将♣手牌当作【铁索连环】使用或重铸。', shenhua_feng:'神话再临·风', shenhua_huo:'神话再临·火', diff --git a/character/shiji.js b/character/shiji.js index fabf6e632..9191f86ee 100644 --- a/character/shiji.js +++ b/character/shiji.js @@ -4715,7 +4715,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var player=_status.event.player,evt=_status.event.getParent(); if(get.value(evt.card,evt.player)*get.attitude(player,evt.player)>0) return 0; return Math.random()>(get.value(evt.card,evt.player)/6)?1:0; - return 1; + //return 1; }); 'step 2' if(result.index+event.addIndex==0){ diff --git a/character/sp.js b/character/sp.js index 061f6739f..725d58edd 100755 --- a/character/sp.js +++ b/character/sp.js @@ -13,7 +13,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp_huben:['duanjiong','ol_mengda',"caohong","xiahouba","zhugeke","zumao","wenpin","litong","mazhong","heqi","quyi","luzhi","zangba","yuejin","dingfeng","wuyan","ol_zhuling","tianyu","huojun",'zhaoyǎn','dengzhong','ol_furong','macheng','ol_zhangyì','ol_zhujun','maxiumatie','luoxian','ol_huban','haopu','ol_qianzhao'], sp_liesi:['mizhu','weizi','ol_liuba','zhangshiping'], sp_default:["sp_diaochan","sp_zhaoyun","sp_sunshangxiang","sp_caoren","sp_jiangwei","sp_machao","sp_caiwenji","jsp_guanyu","jsp_huangyueying","sp_pangde","sp_jiaxu","yuanshu",'sp_zhangliao','sp_ol_zhanghe','sp_menghuo'], - sp_waitforsort:['ol_luyusheng','ol_pengyang','ol_tw_zhangji','ol_feiyi','ol_lvboshe'], + sp_waitforsort:['ol_luyusheng','ol_pengyang','ol_tw_zhangji','ol_feiyi','lvboshe','zhangyan','ol_dingshangwan'], sp_qifu:["caoying",'panshu',"caochun","yuantanyuanshang",'caoshuang','wolongfengchu','guansuo','baosanniang','fengfangnv','jin_zhouchu'], sp_wanglang:['ol_wanglang','ol_puyuan','ol_zhouqun'], sp_zhongdan:["cuiyan","huangfusong"], @@ -28,14 +28,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ol_dongzhao:function(mode){ return mode=='identity'&&['normal','zhong'].contains(_status.mode); }, - ol_lvboshe:function(mode){ + lvboshe:function(mode){ return mode=='doudizhu'; }, }, character:{ + ol_dingshangwan:['female','wei',3,['olfudao','olfengyan']], + zhangyan:['male','qun',4,['olsuji','ollangdao']], ol_tw_zhangji:['male','wei',3,['skill_zhangji_A','skill_zhangji_B'],['unseen']], ol_feiyi:['male','shu',3,['skill_feiyi_A','skill_feiyi_B'],['unseen']], - ol_lvboshe:['male','qun',4,['skill_lvboshe'],['unseen']], + lvboshe:['male','qun',4,['skill_lvboshe'],['unseen']], ol_luyusheng:['female','wu',3,['olcangxin','olrunwei']], caoxi:['male','wei',3,['olgangshu','oljianxuan']], ol_pengyang:['male','shu',3,['olqifan','oltuishi','nzry_cunmu']], @@ -116,7 +118,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ jianggan:["male","wei",3,["weicheng","daoshu"]], caoying:["female","wei",4,["xinfu_lingren","xinfu_fujian"],[]], - simahui:["male","qun",3,["xinfu_jianjie","xinfu_chenghao","xinfu_yinshi"],[]], + simahui:["male","qun",3,["jianjie","xinfu_chenghao","xinfu_yinshi"],[]], baosanniang:["female","shu",4,["olwuniang","olxushen"],[]], yangxiu:['male','wei',3,['jilei','danlao']], @@ -203,6 +205,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ luzhi:['male','wei',3,['qingzhong','weijing']] }, characterIntro:{ + zhangyan:'张燕,本姓褚,生卒年不详,常山真定(今河北正定南)人,东汉末年黑山军首领。张燕剽捍,敏捷过人,军中称为“飞燕”。官渡之战时投降曹操,被任命为平北将军,封安国亭侯。死后其子张方袭爵。', lushi:'卢氏,五斗米教主张衡妻,张鲁母,擅长驻颜之术,常年令自己保持少女的容颜。常拜访刘焉,与其交好。', lvboshe:'吕伯奢,东汉成皋(今河南荥阳)人,曹操父亲曹嵩的故友。曹操与陈宫在逃离董卓避祸,返回乡里的途中借宿于吕伯奢家,未伤其人,有贼八人欲捉曹操,曹操杀之,明罗贯中在历史小说《三国演义》中将这段历史进行了丑化加工,也成为小说中曹操名言“宁教我负天下人,休教天下人负我”的出处。', caoxi:'曹羲(?-249年),字昭叔。曹真之子,曹爽之弟。为人有学识,明律法。司马懿曾组织朝议改革九品中正制废除九品而留中正,曹羲认为此举并无区别,最终都是决定于人的人治。曹爽掌权后,受封中领军,掌握禁兵,封安乡侯。曹爽及诸兄弟轻视司马懿,恣意妄为,经常外出狩猎,曹羲屡次劝谏,不被采纳。249年,司马懿发动高平陵政变,被夷三族。', @@ -704,6 +707,380 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, skill:{ + //丁尚涴 + olfudao:{ + audio:2, + trigger:{ + global:'phaseBefore', + player:'enterGame', + }, + filter:function(event,player){ + return event.name!='phase'||game.phaseNumber==0; + }, + forced:true, + locked:false, + content:function(){ + 'step 0' + var list=[],num=player.countCards('he'); + for(var i=-4;i<=4;i++){ + if(num+i<0||i==0) continue; + list.push(i); + } + player.chooseControl(list).set('prompt','讽言:请选择一个数字').set('prompt2','令此数值作为调整的手牌数值').set('ai',function(){ + var list=[],num=_status.event.player.countCards('he'); + for(var i=-4;i<=4;i++){ + if(num+i<0||i==0) continue; + if(i>0&&i!=4) continue; + list.push(i); + } + return list.randomGet(); + }); + 'step 1' + var num=result.control + player.popup(num); + if(num>0) player.draw(num); + else player.chooseToDiscard('he',true,-num); + 'step 2' + player.storage.olfudao=player.countCards('he'); + player.markSkill('olfudao'); + }, + intro:{ + content:'一名角色的回合结束时,若其手牌数等于#,你可以与其各摸一张牌。', + }, + group:'olfudao_qiaoshi', + subSkill:{ + qiaoshi:{ + audio:'olfudao', + trigger:{global:'phaseEnd'}, + filter:function(event,player){ + if(typeof player.storage.olfudao!='number') return false; + return event.player.countCards('h')==player.storage.olfudao&&event.player.isIn(); + }, + check:function(event,player){ + return get.attitude(player,event.player)>=0; + }, + logTarget:'player', + prompt2:function(event,player){ + return '与'+get.translation(event.player)+'各摸一张牌'; + }, + content:function(){ + game.asyncDraw([trigger.player,player]); + }, + }, + }, + }, + olfengyan:{ + audio:2, + trigger:{player:['damageEnd','useCard','respond']}, + filter:function(event,player){ + if(event.name=='damage') return event.source&&event.source.isIn()&&event.source!=player; + return Array.isArray(event.respondTo)&&event.respondTo[0]!=player; + }, + logTarget:function(event,player){ + if(event.name=='damage') return event.source; + return event.respondTo[0]; + }, + forced:true, + content:function(){ + 'step 0' + var target=lib.skill.olfengyan.logTarget(trigger,player); + if(trigger.name=='damage'){ + event.target=target; + player.draw(); + } + else{ + target.draw(); + target.chooseToDiscard(2,'he',true); + event.finish(); + } + 'step 1' + var num=player.countCards('he'); + if(!num) event.finish(); + else if(num==1) event._result={bool:true,cards:player.getCards('he')}; + else player.chooseCard('he',true,'交给'+get.translation(target)+'一张牌'); + 'step 2' + if(result.bool) target.gain(result.cards,player,'giveAuto'); + }, + }, + //张燕 + olsuji:{ + audio:2, + trigger:{global:'phaseUseBegin'}, + filter:function(event,player){ + if(!event.player.isDamaged()) return false; + return _status.connectMode&&player.countCards('hes')||!_status.connectMode&&player.hasCard(card=>{ + return get.color(card)=='black'; + },'hes'); + }, + direct:true, + content:[ + (event,map)=>{ + var player=map.player,trigger=map.trigger; + var next=player.chooseToUse(); + next.set('openskilldialog',`###${get.prompt('olsuji')}###将一张黑色牌当【杀】使用${ + player==trigger.player?'':`。若${get.translation(trigger.player)}受到了此【杀】的伤害,你获得其一张牌。` + }`); + next.set('norestore',true); + next.set('_backupevent','olsuji_backup'); + next.set('addCount',false); + next.set('logSkill','olsuji'); + next.set('custom',{ + add:{}, + replace:{window:function(){}} + }); + next.backup('olsuji_backup'); + }, + (event,map)=>{ + if(map.result.bool){ + var player=map.player,trigger=map.trigger; + if(trigger.player.isIn()&&trigger.player.hasHistory('damage',evt=>{ + return evt.card&&evt.card.storage&&evt.card.storage.olsuji; + })&&trigger.player.countGainableCards(player,'he')) player.gainPlayerCard(trigger.player,'he',true); + } + }, + ], + subSkill:{ + backup:{ + filterCard:function(card){ + return get.itemtype(card)=='card'&&get.color(card)=='black'; + }, + viewAs:{ + name:'sha', + storage:{olsuji:true}, + }, + selectCard:1, + position:'hes', + ai1:function(card){ + return 5-get.value(card); + }, + precontent:function(){ + delete event.result.skill; + }, + }, + }, + }, + ollangdao:{ + audio:2, + trigger:{player:'useCardToPlayer'}, + filter:function(event,player){ + if(event.card.name!='sha') return false; + return event.isFirstTarget&&event.targets.length==1&&player.getStorage('ollangdao').length<3; + }, + logTarget:'target', + onremove:true, + check:function(event,player){ + if(get.attitude(player,event.target)>0){ + if(player.getStorage('ollangdao').includes(1)&&game.hasPlayer(current=>{ + return player.canUse(event.card,current)&&get.effect(current,event.card,player,player)>0; + })) return event.getRand()<0.5; + return false; + } + return event.target.getHp()<=2||player.getDamagedHp()>1||!player.hasCard({color:'black'},'hes'); + }, + content:function*(event,map){ + var player=map.player,trigger=map.trigger,result=map.result; + var target=trigger.target; + var send=function(card,list){ + var next=game.createEvent('ollangdao_choose',false); + next.setContent(lib.skill.ollangdao.contentx); + next.set('card',card); + next.set('list',list); + game.resume(); + }; + var sendback=function(result,player){ + if(!result) result={}; + if(typeof result.index!=='number'||result.index<0){ + result.index=[0,1,2].find(i=>!event.player.getStorage('ollangdao').includes(i)); + } + results.push([player,result]); + }; + var ai_targets=[]; + var results=[]; + var players=[player,target]; + var withme=false,withol=false,withai=false; + for(var i=0;i{ + return !trigger.targets.includes(current)&&player.canUse(trigger.card,current)&&get.effect(current,trigger.card,player,target)<0; + })) list.removeArray([0,2]); + if(player.getStorage('ollangdao').includes(2)) list.remove(0); + } + else{ + if(!game.hasPlayer(current=>{ + return !trigger.targets.includes(current)&&player.canUse(trigger.card,current)&&get.effect(current,trigger.card,player,target)>0; + })) list.remove(1); + if(!list.includes(1)) list.remove(0); + } + if(list.length) index=list.randomGet(); + sendback({index:index},target); + ai_targets.splice(i--,1); + } + } + if(ai_targets.length){ + ai_targets.randomSort(); + setTimeout(function(){ + event.interval=setInterval(function(){ + var target=ai_targets.shift(); + var list=[0,1,2].removeArray(player.getStorage('ollangdao')); + var index=list[0]; + if(get.attitude(target,player)<0){ + if(!game.hasPlayer(current=>{ + return !trigger.targets.includes(current)&&player.canUse(trigger.card,current)&&get.effect(current,trigger.card,player,target)<0; + })) list.removeArray([0,2]); + if(player.getStorage('ollangdao').includes(2)) list.remove(0); + } + else{ + if(!game.hasPlayer(current=>{ + return !trigger.targets.includes(current)&&player.canUse(trigger.card,current)&&get.effect(current,trigger.card,player,target)>0; + })) list.remove(1); + if(!list.includes(1)) list.remove(0); + } + if(list.length) index=list.randomGet(); + sendback({index:index},target); + if(!ai_targets.length){ + clearInterval(event.interval); + if(withai) game.resume(); + } + },_status.connectMode?750:75); + },500); + } + } + if(withme){ + result=yield next; + if(_status.connectMode){ + game.me.unwait(result,game.me); + } + else{ + if(!result) result={}; + if(typeof result.index!=='number'||result.index<0){ + result.index=[0,1,2].find(i=>!event.player.getStorage('ollangdao').includes(i)); + } + results.push([player,result]); + } + } + if(withol&&!event.resultOL){ + game.pause(); + yield null; + } + if(ai_targets.length>0){ + withai=true; + game.pause(); + yield null; + } + if(_status.connectMode){ + for(var i of [player,target]) i.hideTimer(); + } + var chosenCount=[0,0,0]; + results.sort((a,b)=>lib.sort.seat(a[0],b[0])); + player.when('useCardAfter') + .assign({ + card:trigger.card + }) + .then(()=>{ + var card=get.info(event.name).card; + var dieEvts=game.getGlobalHistory('everything',evt=>evt.name=='die'); + if(trigger.card==card&&!game.hasPlayer2(current=>{ + for(var evt of dieEvts){ + if(evt.player!=current) continue; + var evtx=evt.getParent(2); + if(evtx.name!='damage') continue; + if(evtx.card&&evtx.card==card) return true; + } + return false; + },true)){ + var toRemove=card.storage.ollangdao_remove; + var list=[0,1,2].filter(i=>(toRemove>>i)&1); + if(!list.length) return; + player.markAuto('ollangdao',list); + game.log(player,'移去了','#g【狼蹈】','的','#y选项'+list.map(i=>{ + return get.cnNumber(i+1,true); + }).join('、')); + } + }); + if(!trigger.card.storage) trigger.card.storage={}; + if(!trigger.card.storage.ollangdao_remove) trigger.card.storage.ollangdao_remove=0; + var config=[['伤害+1','fire'],['目标+1','wood'],['不能响应','water']]; + for(var res of results){ + var target=res[0],result=res[1]; + if(!target||!result) continue; + var ind=result.index; + var conf=config[ind]; + trigger.card.storage.ollangdao_remove|=1<{ + return !_status.event.targets.includes(target)&&player.canUse(_status.event.card,target); + }).set('targets',trigger.targets).set('ai',target=>{ + var player=_status.event.player; + return get.effect(target,_status.event.card,player,player); + }).set('card',trigger.card); + if(result.bool){ + if(!event.isMine()&&!event.isOnline()) game.delayex(); + var targets=result.targets; + player.line(targets); + trigger.targets.addArray(targets); + game.log(targets,'也成为了',trigger.card,'的目标'); + } + }, + contentx:function(){ + 'step 0' + var name=get.translation(card); + var choices=[],choiceList=[ + `令${name}伤害基数+1`, + `令${name}可以多选择一个目标`, + `令${name}不可被响应` + ]; + [0,1,2].forEach((item,index)=>{ + if(event.list.includes(item)){ + choiceList[index]=`${choiceList[index]}` + } + else choices.push(`选项${get.cnNumber(index+1,true)}`); + }); + game.me.chooseControl(choices).set('prompt','狼蹈:请选择一项').set('choiceList',choiceList).set('ai',()=>{ + return _status.event.controls.randomGet(); + }); + 'step 1' + event.result={index:['选项一','选项二','选项三'].indexOf(result.control)}; + }, + intro:{ + content:(storage,player)=>`已移除选项${storage.map(i=>get.cnNumber(i+1,true)).join('、')}`, + }, + }, //张既 skill_zhangji_A:{ audio:2, @@ -1225,7 +1602,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ 'step 0' var info=lib.skill.olgangshu.getInfo(player); - player.chooseControl('攻击范围('+info[0]+')','摸牌数('+info[1]+')','使用【杀】的上限('+info[2]+')','cancel2').set('prompt',get.prompt('olgangshu')).set('prompt2','
    令以下一个数值+1(每项至多+5):
    1.攻击范围;
    2.下个摸牌阶段的摸牌数;
    3.使用【杀】的次数上限。
    ').set('ai',()=>{ + player.chooseControl('攻击范围('+info[0]+')','摸牌数('+info[1]+')','使用杀的上限('+info[2]+')','cancel2').set('prompt',get.prompt('olgangshu')).set('prompt2','
    令以下一个数值+1(每项至多+5):
    1.攻击范围;
    2.下个摸牌阶段的摸牌数;
    3.使用【杀】的次数上限。
    ').set('ai',()=>{ return _status.event.choice; }).set('choice',function(){ var info=lib.skill.olgangshu.getInfo(player); @@ -2149,7 +2526,20 @@ game.import('character',function(lib,game,ui,get,ai,_status){ game.cardsGotoOrdering(card); 'step 1' if(player.countCards('he')>0){ - player.chooseCard('he','天候:是否用一张牌交换牌堆顶的'+get.translation(card)+'?').set('promptx',[[card]]).set('ai',()=>-1) + player.chooseCard('he','天候:是否用一张牌交换牌堆顶的'+get.translation(card)+'?').set('promptx',[[card]]).set('card',card).set('ai',cardx=>{ + let card=_status.event.card,val=get.value(card,player)-get.value(cardx,player); + if(val<0) return -val; + let suit=get.suit(card); + if(suit==='heart') return val+game.countPlayer((current)=>{ + if(player!==current&&!game.hasPlayer((tar)=>tar.hp-current.hp>1)) return get.sgn(get.attitude(player,current)); + return 0; + }); + if(suit=='club') return val+game.countPlayer((current)=>{ + if(player!==current&&(current.hp<2||!game.hasPlayer((tar)=>current.hp-tar.hp>1))) return get.sgn(get.attitude(player,current)); + return 0; + }); + return val+0.1; + }); } else{ event._result={bool:false}; @@ -2206,6 +2596,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ for(var current of players){ current.removeAdditionalSkill(key); } + game.removeGlobalSkill('oltianhou_'+player.playerid+'_ai'); game.broadcastAll(function(){ delete _status.tempBackground; game.updateBackground(); @@ -2241,20 +2632,20 @@ game.import('character',function(lib,game,ui,get,ai,_status){ global:'oltianhou_spade_ai', }, spade_ai:{ - effect:{ - player:function(card,player,target,current){ - if(get.tag(card,'fireDamage')&&!player.hasSkill('oltianhou_spade')){ - return 'zerotarget'; + ai:{ + effect:{ + player:function(card,player,target,current){ + if((typeof card=='object'&&game.hasNature(card,'fire')||get.tag(card,'fireDamage'))&&!player.hasSkill('oltianhou_spade')) return 'zeroplayertarget'; + if((typeof card=='object'&&game.hasNature(card,'thunder')||get.tag(card,'thunderDamage'))){ + var list=lib.skill.oltianhou_spade.logTarget({player:target}); + var eff=list.reduce(function(eff,current){ + eff+=get.effect(current,{name:'losehp'},player,player)/get.attitude(player,player); + },0); + return [1,eff]; + } } - else if(get.tag(card,'thunderDamage')){ - var list=lib.skill.oltianhou_spade.logTarget({player:target}); - var eff=list.reduce(function(eff,current){ - eff+=get.effect(current,{name:'losehp'},player,player) - },0); - return [1,eff]; - } - }, - }, + } + } }, miehuo:{ audio:'oltianhou_spade', @@ -2284,6 +2675,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ trigger.player.loseHp(); }, + global:'oltianhou_heart_ai' + }, + heart_ai:{ + mod:{ + aiOrder:function(player,card,num){ + if(num>0&&_status.event&&_status.event.type=='phase'&&!player.hasSkill('oltianhou_heart')&&get.tag(card,'recover')&&!player.isMaxHp()&&player.needsToDiscard()<=1&&!game.hasPlayer(function(current){ + return current.hp-player.hp>1; + })&&get.effect(player,{name:'losehp'},player,player)<0) return 0; + } + } }, club:{ audio:true, @@ -2301,6 +2702,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ trigger.player.loseHp(); }, + global:'oltianhou_club_ai' + }, + club_ai:{ + ai:{ + nokeep:true, + skillTagFilter:function(player,tag,arg){ + return _status.event&&_status.event.type=='phase'&&(!arg||arg.card&&get.name(arg.card)==='tao')&&!player.hasSkill('oltianhou_club')&&player.isMinHp()&&get.effect(player,{name:'losehp'},player,player)<0; + } + } }, diamond:{ audio:true, @@ -2336,13 +2746,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){ global:'oltianhou_diamond_ai', }, diamond_ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'&&!player.hasSkill('oltianhou_diamond')){ - if(target!=player.getNext()&&target!=player.getPrevious()) return 0.7; + ai:{ + effect:{ + player:function(card,player,target){ + if(get.name(card)=='sha'&&!player.hasSkill('oltianhou_diamond')&&target!=player.getNext()&&target!=player.getPrevious()){ + let num=get.number(card),max=_status.aiyh_MAXNUM||13; + return [num/max,0,num/max,0]; + } } - }, - }, + } + } }, } }, @@ -3650,15 +4063,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, mod:{ aiValue:function(player,card,num){ - if(get.itemtype(card)!='card'||!card.hasGaintag('oldaili_tag')) return; - if(get.distance(_status.currentPhase,player,'absolute')==1&&!player.isTurnedOver()) return; - if(player.countCards('h',card=>{ + if(num < 0 ||get.itemtype(card) != 'card' || !card.hasGaintag('oldaili_tag')) return; + if(get.distance(_status.currentPhase, player, 'absolute') == 1 && !player.isTurnedOver()) return; + let dai = player.countCards('h', (card) => { return card.hasGaintag('oldaili_tag'); - })%2==0&&!ui.selected.cards.some(card=>{ + }); + if(ui.selected.cards && ui.selected.cards.length) dai += ui.selected.cards.filter((card) => { return card.hasGaintag('oldaili_tag'); - })){ - return num/10; - } + }).length; + if(dai % 2) return Math.sqrt(num); + return num + 6; }, aiUseful:function(){ return lib.skill.oldaili.mod.aiValue.apply(this,arguments); @@ -4017,9 +4431,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 0' player.damage('nosource'); 'step 1' - var next=player.phaseUse(); - event.next.remove(next); - trigger.next.push(next); + trigger.phaseList.splice(trigger.num,0,'phaseUse|oldianjun'); }, }, olkangrui:{ @@ -6077,9 +6489,22 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, ai:{ threaten:1.2, - order:9, + order:9.1, result:{ - target:-1, + player:function(player){ + let min=24; + player.countCards('he',function(card){ + min=Math.min(min,get.value(card)); + }); + if(ui.selected.targets.length==1) return 1-min/6; + return 0.75-min/48; + }, + target:function(player,target){ + if(target.hasCard(function(card){ + return lib.filter.cardDiscardable(card,player,'olqingyi'); + },'he')) return -1; + return 0; + } }, }, group:'olqingyi_gain', @@ -8492,13 +8917,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return player!=event.player&&event.player.isIn()&&player.countCards('h')>0&&!player.hasSkill('yuanzi_round',null,null,false); }, check:function(event,player){ - if(get.attitude(player,event.player)<=4) return false; - if(event.player.hasJudge('lebu')) return false; + if(event.player.hasJudge('lebu')||get.attitude(player,event.player)<2) return false; return game.hasPlayer(function(current){ - return event.player!=player&&game.hasPlayer(function(current){ - return current!=player&¤t!=event.player&&event.player.inRange(current)&&get.attitude(event.player,current)<0; - }); - }) + return current!==player&¤t!==event.player&&event.player.inRange(current)&&get.attitude(event.player,current)<0; + }); }, content:function(){ var cards=player.getCards('h'); @@ -16325,10 +16747,21 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, yjixi:{ derivation:'rewangzun', + audio:'weidi', trigger:{player:'phaseJieshuBegin'}, forced:true, filter:function(event,player){ - return player.countMark('yjixi')>=3; + if(player.phaseNumber<3) return false; + var num=0; + for(var i=player.actionHistory.length-1;i>=0;i--){ + if(!player.actionHistory[i].isMe) continue; + if(_status.globalHistory[i].changeHp.some(evt=>evt.player==player&&evt.getParent().name=='loseHp')) return false; + else{ + num++; + if(num>=3) break; + } + } + return true; }, skillAnimation:true, animationColor:'gray', @@ -16384,6 +16817,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, xinyongsi:{ + audio:'yongsi1', group:['xinyongsi1','xinyongsi2'], locked:true, }, @@ -16397,7 +16831,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ player.draw(game.countGroup()); trigger.changeToZero(); - } + }, }, xinyongsi2:{ audio:'yongsi2', @@ -16412,13 +16846,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return 8-get.value(card); }; 'step 1' - if(!result.bool){ - player.loseHp(); - var num=player.countMark('yjixi'); - if(num) player.removeMark('yjixi',num,false); - } - else player.addMark('yjixi',1,false); - } + if(!result.bool) player.loseHp(); + }, }, lianzhu:{ audio:2, @@ -17713,6 +18142,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, zhidao:{ audio:2, + mod:{ + aiOrder:function(player,card,num){ + if(num>0&&!player.hasSkill('zhidao2')&&!get.tag(card,'damage')&&(!lib.filter.targetEnabled(card,player,player)||get.effect(player,card,player)<=0)) return num+10; + } + }, trigger:{source:'damageSource'}, filter:function(event,player){ if(event._notrigger.contains(event.player)) return false; @@ -17877,16 +18311,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ 'step 0' player.draw(3); + 'step 1' var list=lib.skill.zhengnan.derivation.filter(skill=>!player.hasSkill(skill)); if(list.length==1) event._result={control:list[0]}; - else if(list.length){ + else if(list.length>0){ player.chooseControl(list).set('prompt','选择获得一项技能').set('ai',function(){ if(_status.event.controls.contains('dangxian')) return 'dangxian'; return _status.event.controls[0]; }); } else event.finish(); - 'step 1' + 'step 2' if(result.control){ player.addSkillLog(result.control); player.popup(result.control); @@ -21594,6 +22029,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ "step 1" if(result.bool){ var nono=(get.damageEffect(trigger.player,player,trigger.player)>=0); + if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.15); trigger.player.chooseToDiscard('he','弃置一张装备牌并令'+get.translation(player)+'摸一张牌,或受到一点伤害',{type:'equip'}).set('ai',function(card){ if(_status.event.nono){ return 0; @@ -21612,10 +22048,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ else{ trigger.player.damage(); } - }, - ai:{ - expose:0.3, - threaten:1.3 } }, suishi:{ @@ -23465,356 +23897,301 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.addMark('xionghuo',1); }, }, - "xinfu_jianjie":{ - derivation:["jianjie_faq"], - group:["xinfu_jianjie1","xinfu_jianjie2"], + xinfu_jianjie:{ audio:3, + }, + jianjie:{ + group:["jianjie_use","jianjie_die"], + derivation:['jianjie_huoji','jianjie_lianhuan','jianjie_yeyan'], + audio:'xinfu_jianjie', trigger:{ player:"phaseZhunbeiBegin", }, - direct:true, + forced:true, + locked:false, filter:function(event,player){ - if(player.phaseNumber>1) return false; - return !game.hasPlayer(function(current){ - return current.hasSkill('smh_huoji')||current.hasSkill('smh_lianhuan'); - }); + return player.phaseNumber<=1&&game.hasPlayer(current=>current!=player); }, content:function(){ - "step 0" - player.chooseTarget('请将「龙印」交给一名角色',true,function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - return 10+get.attitude(player,target); + 'step 0' + player.chooseTarget('荐杰:选择一名其他角色获得“龙印”',lib.filter.notMe,true).set('ai',(target)=>{ + return get.attitude(get.player(),target); }); - "step 1" - if(result.bool&&result.targets&&result.targets.length){ + 'step 1' + if(result.bool){ var target=result.targets[0]; - player.logSkill('xinfu_jianjie',target); player.line(target,'fire'); - target.addSkill('smh_huoji'); - game.delay(); + lib.skill.jianjie.addMark('huoji',player,target); + event.target=target; + game.delayx(); } - if(game.hasPlayer(function(current){ - return !current.hasSkill('smh_huoji')&¤t!=player + else event.finish(); + 'step 2' + if(game.hasPlayer((current)=>{ + return current!=player&¤t!=target; })){ - player.chooseTarget('请将「凤印」交给一名角色',true,function(card,player,target){ - return target!=player&&!target.hasSkill('smh_huoji'); - }).set('ai',function(target){ - var player=_status.event.player; - return 10+get.attitude(player,target); + player.chooseTarget('荐杰:选择一名其他角色获得“凤印”',function(card,player,target){ + return target!=player&&target!=_status.event.getParent().target; + },true).set('ai',(target)=>{ + return get.attitude(get.player(),target); }); } else event.finish(); - "step 2" - if(result.bool&&result.targets&&result.targets.length){ + 'step 3' + if(result.bool){ var target=result.targets[0]; - player.logSkill('xinfu_jianjie',target); - player.line(target,'green'); - target.addSkill('smh_lianhuan'); - game.delay(); + player.line(target,'thunder'); + lib.skill.jianjie.addMark('lianhuan',player,target); + game.delayx(); } }, - }, - "xinfu_jianjie1":{ - audio:3, - prompt:"你的第一个准备阶段,你令两名不同的角色分别获得龙印与凤印;出牌阶段限一次(你的第一个回合除外),或当拥有龙印、凤印的角色死亡时,你可以转移龙印、凤印。", - enable:"phaseUse", - usable:1, - filter:function (event,player){ - if(player.phaseNumber==1) return false; - if(!game.hasPlayer(function(current){ - return current.hasSkill('smh_huoji')||current.hasSkill('smh_lianhuan'); - })) return false; - return true; + hasMark:(mark,player,target)=>{ + if(!target) return player.getStorage('jianjie_'+mark).length>0; + return target.getStorage('jianjie_'+mark).contains(player); }, - filterTarget:function (card,player,target){ - if(ui.selected.targets.length==1){ - return true; - }else{ - return target.hasSkill('smh_huoji')||target.hasSkill('smh_lianhuan'); + addMark:(mark,player,target)=>{ + mark='jianjie_'+mark; + target.addAdditionalSkill(`${mark}_${player.playerid}`,mark); + target.markAuto(mark,[player]); + game.log(player,'令',target,'获得了',`#g“${mark=='jianjie_huoji'?'龙印':'凤印'}”`); + }, + removeMark:(mark,player,target,log)=>{ + if(lib.skill.jianjie.hasMark(mark,player,target,log)){ + mark='jianjie_'+mark; + target.removeAdditionalSkill(`${mark}_${player.playerid}`); + target.unmarkAuto(mark,[player]); + if(log) game.log(target,'移去了',player,'给予的',`#g“${mark=='jianjie_huoji'?'龙印':'凤印'}”`); + else game.log(player,'移去了',target,'的',`#g“${mark=='jianjie_huoji'?'龙印':'凤印'}”`); } }, - targetprompt:["移走印","得到印"], - selectTarget:2, - multitarget:true, - content:function (){ - 'step 0' - if(targets[0].hasSkill('smh_huoji')&&targets[0].hasSkill('smh_lianhuan')){ - player.chooseControl('龙印','凤印').set('prompt','请选择要移动的印'); - } - else{ - if(targets[0].hasSkill('smh_huoji')) event._result={control:'龙印'}; - else event._result={control:'凤印'}; - } - 'step 1' - if(result.control=='龙印'){ - targets[0].removeSkill('smh_huoji'); - targets[1].addSkill('smh_huoji'); - } - else{ - targets[0].removeSkill('smh_lianhuan'); - targets[1].addSkill('smh_lianhuan'); - } - }, - ai:{ - order:8, - result:{ - target:function (player,target){ + subSkill:{ + use:{ + audio:'xinfu_jianjie', + enable:'phaseUse', + usable:1, + filter:function(event,player){ + if(player.phaseNumber<=1) return false; + const skill=lib.skill.jianjie; + return game.hasPlayer(function(current){ + return skill.hasMark('huoji',player,current)||skill.hasMark('lianhuan',player,current); + }); + }, + filterTarget:function(card,player,target){ if(ui.selected.targets.length==0){ - return get.attitude(player,target)<0?-999:-3; + const skill=lib.skill.jianjie; + return skill.hasMark('huoji',player,target)||skill.hasMark('lianhuan',player,target); + } + return true; + }, + selectTarget:2, + complexSelect:true, + complexTarget:true, + multitarget:true, + prompt:'移动场上的“龙印”或“凤印”', + targetprompt:['失去印','获得印'], + content:function(){ + 'step 0' + var skill=lib.skill.jianjie; + var bool1=skill.hasMark('huoji',player,targets[0]),bool2=skill.hasMark('lianhuan',player,targets[0]); + if(bool1&&bool2){ + player.chooseControl('龙印','凤印').set('prompt','选择要移动的“印”'); } else{ - return target.countCards('h')+1; + event._result={control:(bool1?'龙印':'凤印')} + } + 'step 1' + var skill=lib.skill.jianjie,mark=(result.control=='龙印'?'huoji':'lianhuan'); + skill.removeMark(mark,player,targets[0]); + skill.addMark(mark,player,targets[1]); + game.delayx(); + }, + ai:{ + order:8, + result:{ + target:function(player,target){ + if(ui.selected.targets.length==0){ + return get.attitude(player,target)<0?-999:-3; + } + else{ + return target.countCards('h')+1; + } + }, + }, + expose:0.4, + threaten:3, + }, + }, + die:{ + audio:'xinfu_jianjie', + trigger:{global:'die'}, + forced:true, + filter:function(event,player){ + const skill=lib.skill.jianjie; + return skill.hasMark('huoji',player,event.player)||skill.hasMark('lianhuan',player,event.player); + }, + content:function(){ + 'step 0' + if(lib.skill.jianjie.hasMark('huoji',player,trigger.player)){ + player.chooseTarget('荐杰:选择一名角色获得“龙印”',true).set('ai',(target)=>{ + return get.attitude(get.player(),target); + }); + } + else event.goto(3); + 'step 1' + if(result.bool){ + var target=result.targets[0]; + player.line(target,'fire'); + lib.skill.jianjie.addMark('huoji',player,target); + event.target=target; + game.delayx(); + } + else event.finish(); + 'step 2' + if(lib.skill.jianjie.hasMark('lianhuan',player,trigger.player)){ + player.chooseTarget('荐杰:选择一名角色获得“凤印”',true).set('ai',(target)=>{ + return get.attitude(get.player(),target); + }); + } + else event.finish(); + 'step 3' + if(result.bool){ + var target=result.targets[0]; + player.line(target,'thunder'); + lib.skill.jianjie.addMark('lianhuan',player,target); + game.delayx(); + } + }, + logTarget:'player', + }, + huoji:{ + marktext:'龙', + intro:{ + name:"龙印", + content:"
  • 出牌阶段限三次。你可以将一张红色牌当作【火攻】使用,且你以此法使用【火攻】的作用效果改为“目标角色随机展示一张手牌A,然后你可以弃置一张与A颜色相同的牌,对目标造成1点火属性伤害”。
  • 若你同时拥有“凤印”,则你视为拥有技能〖业炎〗。(发动〖业炎〗时,弃置所有“龙印”和“凤印”)", + }, + inherit:'rehuoji', + usable:3, + charlotte:true, + viewAsFilter:function(player){ + const storage=player.getStorage('jianjie_huoji'); + if(!storage.some(source=>{ + return source.isIn()&&source.hasSkill('jianjie'); + })) return false; + return player.hasCard(card=>get.color(card)=='red','she'); + }, + group:['jianjie_yeyan','jianjie_huoji_effect'], + }, + huoji_effect:{ + trigger:{player:'huogongBegin'}, + forced:true, + popup:false, + charlotte:true, + filter:function(event,player){ + return event.skill=='jianjie_huoji' + }, + content:function(){ + trigger.setContent(lib.skill.olhuoji.huogongContent); + }, + }, + lianhuan:{ + marktext:'凤', + intro:{ + name:"凤印", + content:"
  • 出牌阶段限三次。你可以将一张♣牌当作【铁索连环】使用或重铸,且你以此法使用【铁索连环】的目标数上限+1。
  • 若你同时拥有“龙印”,则你视为拥有技能〖业炎〗。(发动〖业炎〗时,弃置所有“龙印”和“凤印”)", + }, + charlotte:true, + usable:3, + filter:function(event,player){ + const storage=player.getStorage('jianjie_lianhuan'); + if(!storage.some(source=>{ + return source.isIn()&&source.hasSkill('jianjie'); + })) return false; + if(!player.hasCard(card=>get.suit(card)=='club','she')) return false; + return (event.type=='phase'||event.filterCard({name:'tiesuo'},player,event)); + }, + inherit:'ollianhuan', + group:['jianjie_yeyan','jianjie_lianhuan_effect'], + }, + lianhuan_effect:{ + trigger:{player:'useCard2'}, + filter:function(event,player){ + if(event.skill!='jianjie_lianhuan') return false; + var info=get.info(event.card); + if(info.allowMultiple==false) return false; + if(event.targets&&!info.multitarget){ + if(game.hasPlayer(current=>{ + return !event.targets.contains(current)&&lib.filter.targetEnabled2(event.card,player,current); + })) return true; + } + return false; + }, + charlotte:true, + forced:true, + popup:false, + content:function(){ + 'step 0' + player.chooseTarget('是否为'+get.translation(trigger.card)+'额外指定一个目标?',(card,player,target)=>{ + return !_status.event.sourcex.contains(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); + }).set('sourcex',trigger.targets).set('ai',function(target){ + var player=_status.event.player; + return get.effect(target,_status.event.card,player,player); + }).set('card',trigger.card); + 'step 1' + if(result.bool){ + if(!event.isMine()&&!event.isOnline()) game.delayex(); + } + else event.finish(); + 'step 2' + if(result.bool){ + var targets=result.targets; + player.line(targets,'thunder'); + trigger.targets.addArray(targets); + game.log(targets,'也成为了',trigger.card,'的目标'); } }, }, - expose:0.4, - threaten:3, - }, - }, - "smh_huoji":{ - charlotte:true, - group:["smh_yeyan"], - mark:true, - marktext:"龙", - intro:{ - name:"龙印", - content:"
  • 出牌阶段限三次,你可以将一张红色牌当【火攻】使用。
  • 若你同时拥有「凤印」,则你视为拥有技能〖业炎〗。(发动〖业炎〗后,弃置龙印和凤印)", - }, - usable:3, - audio:2, - enable:"chooseToUse", - position:"hes", - filterCard:function(card){ - return get.color(card)=='red'; - }, - viewAs:{ - name:"huogong", - }, - viewAsFilter:function (player){ - if(player.hasSkill('huoji')) return false; - if(!game.hasPlayer(function(current){ - return current.hasSkill('xinfu_jianjie'); - })) return false; - if(!player.countCards('hes',{color:'red'})) return false; - }, - prompt:"将一张红色牌当火攻使用", - check:function (card){ - var player=_status.currentPhase; - if(player.countCards('h')>player.hp){ - return 6-get.value(card); - } - return 4-get.value(card) - }, - ai:{ - fireAttack:true, - }, - }, - "smh_lianhuan":{ - audio:2, - charlotte:true, - enable:"phaseUse", - filter:function (event,player){ - if(player.hasSkill('lianhuan')||player.hasSkill('xinlianhuan')) return false; - if(!game.hasPlayer(function(current){ - return current.hasSkill('xinfu_jianjie'); - })) return false; - if((player.getStat().skill.smh_lianhuan||0)+(player.getStat().skill.smh_lianhuan1||0)>=3) return false; - return player.countCards('hs',{suit:'club'})>0; - }, - filterCard:function (card){ - return get.suit(card)=='club'; - }, - viewAs:{ - name:"tiesuo", - }, - position:'hs', - prompt:"将一张梅花牌当铁锁连环使用", - check:function (card){return 6-get.value(card)}, - mark:true, - marktext:"凤", - intro:{ - name:"凤印", - content:"
  • 出牌阶段限三次,你可以将你的任意一张梅花手牌当作【铁索连环】使用或重铸。", - }, - group:["smh_lianhuan1"], - }, - "xinfu_jianjie2":{ - trigger:{ - global:"dieAfter", - }, - forced:true, - direct:true, - silent:true, - popup:false, - filter:function (event,player){ - return event.player.hasSkill('smh_huoji')||event.player.hasSkill('smh_lianhuan'); - }, - content:function (){ - "step 0" - player.logSkill('xinfu_jianjie'); - "step 1" - if(trigger.player.hasSkill('smh_huoji')){ - player.chooseTarget('请将'+get.translation(trigger.player)+'的「龙印」交给一名角色',true).set('ai',function(target){ - var player=_status.event.player; - return 10+get.attitude(player,target); - }); - }else event.goto(2); - "step 2" - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,'fire'); - target.addSkill('smh_huoji'); - game.delay(); - } - "step 3" - if(trigger.player.hasSkill('smh_lianhuan')){ - player.chooseTarget('请将'+get.translation(trigger.player)+'的「凤印」交给一名角色',true).set('ai',function(target){ - var player=_status.event.player; - return 10+get.attitude(player,target); - }); - }else event.finish(); - "step 4" - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,'green'); - target.addSkill('smh_lianhuan'); - game.delay(); - } - }, - }, - "smh_lianhuan1":{ - enable:"phaseUse", - filter:function (event,player){ - if(player.hasSkill('lianhuan')||player.hasSkill('xinlianhuan')) return false; - if(!game.hasPlayer(function(current){ - return current.hasSkill('xinfu_jianjie'); - })) return false; - if((player.getStat().skill.smh_lianhuan||0)+(player.getStat().skill.smh_lianhuan1||0)>=3) return false; - return player.hasCard(card=>lib.skill.smh_lianhuan1.filterCard(card,player),'h'); - }, - filterCard:(card,player)=>get.suit(card)=='club'&&player.canRecast(card), - check:function(card){ - return -1; - }, - content:function(){ - player.recast(cards); - }, - discard:false, - lose:false, - delay:false, - prompt:"将一张梅花牌置入弃牌堆并摸一张牌", - ai:{ - basic:{ - order:1, - }, - result:{ - player:1 - } - }, - forced:true - }, - "smh_yeyan":{ - unique:true, - enable:"phaseUse", - audio:3, - skillAnimation:true, - animationColor:'gray', - prompt:"限定技,出牌阶段,你可以对一至三名角色造成至多共3点火焰伤害(你可以任意分配每名目标角色受到的伤害点数),若你将对一名角色分配2点或更多的火焰伤害,你须先弃置四张不同花色的手牌再失去3点体力。", - filter:function (event,player){ - if(!game.hasPlayer(function(current){ - return current.hasSkill('xinfu_jianjie'); - })) return false; - return player.hasSkill('smh_lianhuan'); - }, - filterTarget:function (card,player,target){ - var length=ui.selected.cards.length; - return (length==0||length==4); - }, - filterCard:function (card){ - var suit=get.suit(card); - for(var i=0;i0&&lianhuan.some(source=>{ + return huoji.includes(source)&&source.isIn()&&source.hasSkill('jianjie'); + }) + }, + contentBefore:function(){ + player.awakenSkill('jianjie_yeyan'); + var skill=lib.skill.jianjie; + var huoji=player.getStorage('jianjie_huoji').slice(0),lianhuan=player.getStorage('jianjie_lianhuan').slice(0); + huoji.forEach(source=>{ + skill.removeMark('huoji',source,player,true); + }); + lianhuan.forEach(source=>{ + skill.removeMark('lianhuan',source,player,true); + }); + }, + ai:{ + order:1, + fireAttack:true, + result:{ + //等PZ157来写 + /*target:function(player,target){ + if(target.hasSkillTag('nofire')) return 0; + if(lib.config.mode=='versus') return -1; + if(player.hasUnknown()) return 0; + return get.damageEffect(target,player); + }*/ + } + } }, }, }, - "xinfu_yinshi":{ + xinfu_yinshi:{ audio:2, - trigger:{ - player:"damageBegin4", - }, + trigger:{player:'damageBegin4'}, forced:true, - //priority:15, filter:function (event,player){ - if(player.hasSkill('smh_huoji')||player.hasSkill('smh_lianhuan')) return false; + const skill=lib.skill.jianjie; + if(skill.hasMark('huoji',player)||skill.hasMark('lianhuan',player)) return false; if(!player.hasEmptySlot(2)) return false; if(event.hasNature()) return true; return get.type(event.card,'trick')=='trick'; @@ -23828,7 +24205,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ nothunder:true, effect:{ target:function (card,player,target,current){ - if(target.hasSkill('smh_huoji')||target.hasSkill('smh_lianhuan')) return; + const skill=lib.skill.jianjie; + if(skill.hasMark('huoji',target)||skill.hasMark('lianhuan',target)) return false; if(player==target&&get.subtype(card)=='equip2'){ if(get.equipValue(card)<=8) return 0; } @@ -23911,7 +24289,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }).setContent('gaincardMultiple'); }, }, - "jianjie_faq":{}, "xinfu_wuniang":{ trigger:{ player:["useCard","respond"], @@ -24401,6 +24778,23 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(player.storage.skill_lvboshe) return '农民的回合结束时:阴,你可以令地主进行一个额外回合;阳,你可以令其进行一个额外回合。'; return '农民的回合结束时:阴,你可以令地主进行一个额外回合;阳,你可以令其进行一个额外回合。'; }, + ollangdao:function(player){ + var str='当你使用【杀】指定唯一目标时,你可以与该目标角色同时选择一项:'; + var list=[ + '1.令此【杀】伤害基数+1;', + '2.令你可以为此【杀】多选择一个目标;', + '3.令此【杀】不可被响应。' + ]; + var storage=player.getStorage('ollangdao'); + list.forEach((item,index)=>{ + if(storage.includes(index)){ + str+=`${item}`; + } + else str+=item; + }) + str+='然后若没有角色因此【杀】死亡,你移除本次被选择的项。'; + return str; + }, }, characterReplace:{ shixie:['shixie','dc_shixie'], @@ -24480,24 +24874,21 @@ game.import('character',function(lib,game,ui,get,ai,_status){ "xionghuo_low_info":"", "xinfu_shajue":"杀绝", "xinfu_shajue_info":"锁定技,其他角色进入濒死状态时,若其体力值小于0,则你获得一个“暴戾”标记,并获得使其进入濒死状态的牌。", - "xinfu_jianjie":"荐杰", - "xinfu_jianjie_info":"你的第一个准备阶段,你令两名其他角色分别获得龙印与凤印;出牌阶段限一次(你的第一个回合除外),或当拥有龙印、凤印的角色死亡时,你可以转移龙印、凤印。", - "xinfu_jianjie1":"荐杰", - "xinfu_jianjie1_info":"", - "smh_huoji":"火计", - "smh_huoji_info":"", - "smh_lianhuan":"连环", - "smh_lianhuan_info":"", - "xinfu_jianjie2":"荐杰", - "xinfu_jianjie2_info":"", - "smh_lianhuan1":"连铸", - "smh_lianhuan1_info":"", - "smh_yeyan":"业炎", - "smh_yeyan_info":"", - "xinfu_yinshi":"隐士", - "xinfu_yinshi_info":"锁定技,若你没有龙印、凤印且防具栏为空,则当你受到属性伤害或锦囊牌造成的伤害时,防止此伤害。", - "xinfu_chenghao":"称好", - "xinfu_chenghao_info":"当一名角色受到属性伤害后,若其存活且其武将牌横置且是伤害传导的起点,则你可以观看牌堆顶的X张牌并分配给任意角色。(X为横置的角色数量且包含该角色)", + xinfu_jianjie:"荐杰", + jianjie:'荐杰', + jianjie_info:'①你的第一个准备阶段开始时,你令一名其他角色获得“龙印”,然后令另一名其他角色获得“凤印”。②出牌阶段限一次。若当前回合不是你的第一个回合,则你可以移动场上的“龙印”或“凤印”。③拥有“龙印”或“凤印”的其他角色死亡时,你转移该角色的“龙印”和“凤印”。④拥有“龙印”/“凤印”的角色视为拥有〖火计〗/〖连环〗,且同时拥有这两种标记的角色视为拥有〖业炎〗。', + jianjie_huoji:'火计', + jianjie_huoji_effect:'火计', + jianjie_huoji_info:'出牌阶段限三次。你可以将一张红色牌当作【火攻】使用,且你以此法使用【火攻】的作用效果改为“目标角色随机展示一张手牌A,然后你可以弃置一张与A颜色相同的牌,对目标造成1点火属性伤害”。', + jianjie_lianhuan:'连环', + jianjie_lianhuan_effect:'连环', + jianjie_lianhuan_info:'出牌阶段限三次。你可以将一张♣牌当作【铁索连环】使用或重铸,且你以此法使用【铁索连环】的目标数上限+1。', + jianjie_yeyan:'业炎', + jianjie_yeyan_info:'限定技。出牌阶段,你可以移去你所有的“龙印”和“凤印”,对一至三名角色造成至多共3点火焰伤害(你可以任意分配每名目标角色受到的伤害点数),若你将对一名角色分配2点或更多的火焰伤害,你须先弃置四张不同花色的手牌再失去3点体力。', + xinfu_yinshi:"隐士", + xinfu_yinshi_info:"锁定技,若你没有“龙印”和“凤印”且防具栏为空,则当你受到属性伤害或锦囊牌造成的伤害时,防止此伤害。", + xinfu_chenghao:"称好", + xinfu_chenghao_info:"当一名角色受到属性伤害后,若其存活且其武将牌横置且是伤害传导的起点,则你可以观看牌堆顶的X张牌并分配给任意角色。(X为横置的角色数量且包含该角色)", "jianjie_faq":"关于龙凤印", "jianjie_faq_info":"龙印效果:视为拥有〖火计〗。凤印效果:视为拥有〖连环〗。(均一回合限使用三次) 龙凤印齐全:视为拥有〖业炎〗,〖业炎〗发动后移除龙凤印。", "xinfu_wuniang":"武娘", @@ -24827,7 +25218,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ refuhan:'扶汉', refuhan_info:'限定技,回合开始时,你可以移去所有"梅影"标记并摸等量的牌,然后从X张蜀势力武将牌中选择并获得至多两个技能(限定技、觉醒技、隐匿技、使命技、主公技除外)。若此时你是体力值最低的角色,你回复1点体力(X为场上角色数,且X∈[4,+∞))。', yjixi:'觊玺', - yjixi_info:'觉醒技,结束阶段,若你连续三回合没有因〖庸肆〗而失去过体力,则你增加1点体力上限并回复1点体力,然后选择一项:获得技能〖妄尊〗;摸两张牌并获得当前主公的主公技。', + yjixi_info:'觉醒技,结束阶段,若你已连续三个自己回合未失去过体力,则你增加1点体力上限并回复1点体力,然后选择一项:获得技能〖妄尊〗;摸两张牌并获得当前主公的主公技。', xinyongsi:'庸肆', xinyongsi1:'庸肆', xinyongsi2:'庸肆', @@ -25650,9 +26041,20 @@ game.import('character',function(lib,game,ui,get,ai,_status){ skill_feiyi_A_info:'出牌阶段各限一次,若你的手牌数为:①奇数,你可以摸三张牌,然后弃置至少一半手牌(向下取整);②偶数,你可以弃置至少一半手牌,然后摸三张牌。', skill_feiyi_B:'技能', skill_feiyi_B_info:'每回合每项限一次,当你的手牌数变为1后,你可以展示此唯一手牌A并摸一张牌,然后你选择一项:①本回合使用点数大于A的点数的牌额外结算一次;②本回合使用点数小于A的点数的牌额外结算一次。', - ol_lvboshe:'吕伯奢', + lvboshe:'吕伯奢', skill_lvboshe:'技能', skill_lvboshe_info:'农民的回合结束时:阴,你可以令地主进行一个额外回合;阳,你可以令其进行一个额外回合。', + zhangyan:'张燕', + olsuji:'肃疾', + olsuji_info:'一名角色的出牌阶段开始时,若其已受伤,你可以将一张黑色牌当【杀】使用。若其受到此【杀】的伤害,你获得其一张牌。', + ollangdao:'狼蹈', + ollangdao_info:'当你使用【杀】指定唯一目标时,你可以与该目标角色同时选择一项:1.令此【杀】伤害基数+1;2.令你可以为此【杀】多选择一个目标;3.令此【杀】不可被响应。然后若没有角色因此【杀】死亡,你移除本次被选择的项。', + ol_dingshangwan:'OL丁尚涴', + ol_dingshangwan_prefix:'OL', + olfudao:'抚悼', + olfudao_info:'①游戏开始时,你选择弃置或摸至多四张牌,然后记录你的手牌数。②一名角色的回合结束时,若其手牌数和你发动〖抚悼①〗记录的数值相同,则你可以与其各摸一张牌。', + olfengyan:'讽言', + olfengyan_info:'锁定技。①当你受到其他角色造成的伤害后,你摸一张牌,然后交给其一张牌。②当你响应其他角色使用的牌时,其摸一张牌,然后弃置两张牌。', sp_tianji:'天极·皇室宗亲', diff --git a/character/sp2.js b/character/sp2.js index cf89bfea1..c28fbda5a 100644 --- a/character/sp2.js +++ b/character/sp2.js @@ -7,7 +7,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dc_jikang:['male','wei',3,['new_qingxian','dcjuexiang']], dc_jsp_guanyu:['male','wei',4,['new_rewusheng','dcdanji']], dc_mengda:['male','wei',4,['dclibang','dcwujie']], - dc_zhangmancheng:['male','qun',4,['dclvecheng','dczhongji'],['unseen']], + dc_zhangmancheng:['male','qun',4,['dclvecheng','dczhongji']], //dc_fuwan:['male','qun',4,['dcmoukui']], guānning:['male','shu',3,['dcxiuwen','dclongsong']], sunhuan:['male','wu',4,['dcniji'],['unseen']], @@ -41,7 +41,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ qiuliju:['male','qun','4/6',['koulve','qljsuiren']], re_hucheer:['male','qun',4,['redaoji','fuzhong']], re_dongcheng:['male','qun',4,['xuezhao']], - tangji:['female','qun',3,['jielie','kangge']], + tangji:['female','qun',3,['kangge','jielie']], zhangheng:['male','qun',8,['dangzai','liangjue']], duanwei:['male','qun',4,['langmie']], re_niujin:['male','wei',4,['recuorui','reliewei']], @@ -608,10 +608,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ player.addTempSkill('dclvecheng_xiongluan'); player.markAuto('dclvecheng_xiongluan',[target]); + var cards=player.getCards('h','sha'); + if(cards.length) player.addGaintag(cards,'dclvecheng_xiongluan'); }, ai:{ - threaten:2.1, - order:9, + threaten:3.1, + order:3.5, expose:0.2, result:{ target:function(player,target){ @@ -632,7 +634,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ charlotte:true, forced:true, popup:false, - onremove:true, + onremove:function(player,skill){ + player.removeGaintag('dclvecheng_xiongluan'); + delete player.storage[skill]; + }, filter:function(event,player){ return player.getStorage('dclvecheng_xiongluan').some(i=>i.isIn()); }, @@ -673,11 +678,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ event.goto(1); }, intro:{ - content:'可以对$随意大喊大叫' + content:'对$使用“掠城”【杀】无任何次数限制', }, mod:{ cardUsableTarget:function(card,player,target){ - if(card.name=='sha'&&player.getStorage('dclvecheng_xiongluan').contains(target)) return true; + if(!card.cards||card.cards.length!=1) return; + if(card.name=='sha'&&card.cards[0].hasGaintag('dclvecheng_xiongluan')&&player.getStorage('dclvecheng_xiongluan').contains(target)) return true; }, } } @@ -687,6 +693,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ audio:2, trigger:{player:'useCard'}, filter:function(event,player){ + if(player.countCards('h')>=player.maxHp) return false; var suit=get.suit(event.card); return !lib.suit.contains(suit)||!player.countCards('h',{suit:suit}); }, @@ -2814,9 +2821,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ filterCard:true, selectCard:[1,Infinity], check:function(card){ - var player=_status.event.player; - if(ui.selected.cards.length<=Math.max(1,player.needsToDiscard(),player.countCards('h')-4)) return 6-get.value(card); - return 4-get.value(card); + let player=_status.event.player,num=player.hasSkill('nifu')?15:8; + if(ui.selected.cards.length<=Math.max(1,player.needsToDiscard(),player.countCards('h')-4)) return num-get.value(card); + return num/2-get.value(card); }, position:'h', discard:false, @@ -2870,7 +2877,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ viewAs:{name:'juedou'}, position:'h', filterTarget:lib.filter.targetEnabled, - check:(card)=>get.name(card)=='sha'?7:5.5-get.value(card), + check:(card)=>get.name(card)=='sha'?0:5.5-get.value(card), log:false, precontent:function(){ delete event.result.skill; @@ -4545,12 +4552,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //唐姬 - jielie:{ + kangge:{ audio:2, trigger:{player:'phaseBegin'}, direct:true, filter:function(event,player){ - return player.phaseNumber==1&&!player.storage.jielie&&game.hasPlayer(current=>current!=player); + return player.phaseNumber==1&&!player.storage.kangge&&game.hasPlayer(current=>current!=player); }, content:function(){ 'step 0' @@ -4560,31 +4567,31 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 1' if(result.bool){ var target=result.targets[0]; - player.logSkill('jielie',target); - player.addSkill('jielie_clear'); - player.storage.jielie=target; - player.markSkill('jielie'); + player.logSkill('kangge',target); + player.addSkill('kangge_clear'); + player.storage.kangge=target; + player.markSkill('kangge'); game.delayx(); } }, intro:{content:'已指定$为目标'}, - group:['jielie_draw','jielie_dying','jielie_die'], + group:['kangge_draw','kangge_dying','kangge_die'], subSkill:{ draw:{ - audio:'jielie', + audio:'kangge', trigger:{ global:['gainAfter','loseAsyncAfter'], }, forced:true, filter:function(event,player){ - if(player.countMark('jielie_draw')>=3) return false; - var target=player.storage.jielie; + if(player.countMark('kangge_draw')>=3) return false; + var target=player.storage.kangge; return target&&target!=_status.currentPhase&&event.getg(target).length>0; }, logTarget:'player', content:function(){ - var num=Math.min(3-player.countMark('jielie_draw'),trigger.getg(player.storage.jielie).length); - player.addMark('jielie_draw',num,false); + var num=Math.min(3-player.countMark('kangge_draw'),trigger.getg(player.storage.kangge).length); + player.addMark('kangge_draw',num,false); player.draw(num); }, }, @@ -4595,18 +4602,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ popup:false, charlotte:true, filter:function(event,player){ - return player.countMark('jielie_draw')>0; + return player.countMark('kangge_draw')>0; }, content:function(){ - player.removeMark('jielie_draw',player.countMark('jielie_draw'),false); + player.removeMark('kangge_draw',player.countMark('kangge_draw'),false); }, }, dying:{ - audio:'jielie', + audio:'kangge', trigger:{global:'dying'}, logTarget:'player', filter:function(event,player){ - return event.player==player.storage.jielie&&event.player.hp<1&&!player.hasSkill('jielie_temp'); + return event.player==player.storage.kangge&&event.player.hp<1&&!player.hasSkill('kangge_temp'); }, check:function(event,player){ return get.attitude(player,event.player)>0; @@ -4614,15 +4621,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ prompt2:'令其将体力值回复至1点', content:function(){ trigger.player.recover(1-trigger.player.hp); - player.addTempSkill('jielie_temp','roundStart'); + player.addTempSkill('kangge_temp','roundStart'); }, }, temp:{}, die:{ - audio:'jielie', + audio:'kangge', trigger:{global:'dieAfter'}, filter:function(event,player){ - return event.player==player.storage.jielie; + return event.player==player.storage.kangge; }, forced:true, content:function(){ @@ -4636,24 +4643,24 @@ game.import('character',function(lib,game,ui,get,ai,_status){ threaten:2, }, }, - kangge:{ + jielie:{ audio:2, trigger:{player:'damageBegin4'}, direct:true, filter:function(event,player){ - return ((!event.source)||(event.source!=player&&event.source!=player.storage.jielie))&&player.storage.jielie&&player.storage.jielie.isIn(); + return ((!event.source)||(event.source!=player&&event.source!=player.storage.kangge))&&player.storage.kangge&&player.storage.kangge.isIn(); }, content:function(){ 'step 0' - player.chooseControl(lib.suit.slice(0),'cancel2').set('prompt',get.prompt('kangge')).set('prompt2','防止伤害并改为失去等量体力,且令'+get.translation(player.storage.jielie)+'从弃牌堆中获得等量的花色牌').set('ai',function(){ + player.chooseControl(lib.suit.slice(0),'cancel2').set('prompt',get.prompt('jielie')).set('prompt2','防止伤害并改为失去等量体力,且令'+get.translation(player.storage.kangge)+'从弃牌堆中获得等量的花色牌').set('ai',function(){ var player=_status.event.player; - if(get.attitude(player,player.storage.jielie)<=0) return 'cancel2'; + if(get.attitude(player,player.storage.kangge)<=0) return 'cancel2'; return lib.suit.randomGet(); }); 'step 1' if(result.control!='cancel2'){ event.suit=result.control; - player.logSkill('kangge',player.storage.jielie); + player.logSkill('jielie',player.storage.kangge); trigger.cancel(); player.loseHp(trigger.num); } @@ -4667,7 +4674,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(card) cards.push(card); else break; } - if(cards.length) player.storage.jielie.gain(cards,'gain2'); + if(cards.length) player.storage.kangge.gain(cards,'gain2'); }, }, //张横 @@ -8836,7 +8843,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, zongkui:{ - trigger:{player:'phaseBefore',global:'roundStart'}, + trigger:{ + player:'phaseBeforeEnd', + global:'roundStart', + }, direct:true, audio:2, audioname:['tw_beimihu'], @@ -10127,6 +10137,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ mushun:['mushun','sp_mushun'], wangjun:['dc_wangjun','wangjun'], zoushi:['re_zoushi','jsrg_zoushi'], + zhangmancheng:['dc_zhangmancheng','tw_zhangmancheng'], }, translate:{ lijue:"李傕", @@ -10208,7 +10219,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ zongkui:'纵傀', zongkui_mark:'纵傀', zongkui_mark_bg:'傀', - zongkui_info:'回合开始时,你可以指定一名未拥有“傀”标记的其他角色,令其获得一枚“傀”标记。每轮游戏开始时,你指定一名体力值最少且没有“傀”标记的其他角色,令其获得一枚“傀”标记。', + zongkui_info:'回合开始前,你可以指定一名未拥有“傀”标记的其他角色,令其获得一枚“傀”标记。一轮游戏开始时,你指定一名体力值最少且没有“傀”标记的其他角色,令其获得一枚“傀”标记。', guju:'骨疽', guju_info:'锁定技,拥有“傀”标记的角色受到伤害后,你摸一张牌。', baijia:'拜假', @@ -10450,10 +10461,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ liangjue:'粮绝', liangjue_info:'锁定技,当有黑色牌进入或者离开你的判定区或装备区后,若你的体力值大于1,你失去1点体力,然后摸两张牌。', tangji:'唐姬', - jielie:'抗歌', - jielie_info:'你的第一个回合开始时,选择一名其他角色,该角色每次于其回合外得到牌后,你摸等量的牌(每回合至多摸三张);其进入濒死状态时,你可令其回复体力至1点(每轮限一次)。该角色死亡时,你弃置所有牌并失去1点体力。', - kangge:'节烈', - kangge_info:'当你受到除自己和“抗歌”角色以外的角色造成的伤害时,你可以防止此伤害并选择一种花色,然后你失去X点体力,令“抗歌”角色从弃牌堆中随机获得X张此花色的牌(X为伤害值)。', + kangge:'抗歌', + kangge_info:'你的第一个回合开始时,选择一名其他角色,该角色每次于其回合外得到牌后,你摸等量的牌(每回合至多摸三张);其进入濒死状态时,你可令其回复体力至1点(每轮限一次)。该角色死亡时,你弃置所有牌并失去1点体力。', + jielie:'节烈', + jielie_info:'当你受到除自己和“抗歌”角色以外的角色造成的伤害时,你可以防止此伤害并选择一种花色,然后你失去X点体力,令“抗歌”角色从弃牌堆中随机获得X张此花色的牌(X为伤害值)。', re_dongcheng:'董承', xuezhao:'血诏', xuezhao_info:'出牌阶段限一次,你可弃置一张手牌并选择至多X名其他角色(X为你的体力上限)。这些角色依次选择是否交给你一张牌,若选择是,该角色摸一张牌且你本回合可多使用一张【杀】;若选择否,该角色本回合无法响应你使用的牌。', @@ -10632,7 +10643,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dclongsong_info:'出牌阶段开始时,你可以将一张红色牌交给一名其他角色。然后其须选择其所有的发动时机包含“出牌阶段”的技能,其于此阶段这些技能失效,你获得这些技能且至多可以发动一次。', dc_zhangmancheng:'张曼成', dclvecheng:'掠城', - dclvecheng_info:'出牌阶段限一次。你可以选择一名其他角色,你于本回合对其使用【杀】无次数限制。然后回合结束时,其展示所有手牌,若其中有【杀】,其可以选择对你依次使用其中所有的【杀】。', + dclvecheng_info:'出牌阶段限一次。你可以选择一名其他角色,你于本回合对其使用当前手牌中的【杀】无任何次数限制。然后回合结束时,其展示所有手牌,若其中有【杀】,其可以选择对你依次使用其中所有的【杀】。', dczhongji:'螽集', dczhongji_info:'当你使用牌时,若此牌无花色或你手牌区里没有与此牌花色相同的手牌,你可以将手牌摸至体力上限并弃置X张牌(X为本回合发动〖螽集〗的次数)。', dc_mengda:'孟达', diff --git a/character/standard.js b/character/standard.js index aa9d2f484..89bd2846a 100755 --- a/character/standard.js +++ b/character/standard.js @@ -1459,6 +1459,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, xinzhiheng:{ audio:'zhiheng', + mod:{ + aiOrder:function(player,card,num){ + if(num<=0||get.itemtype(card)!=='card'||get.type(card)!=='equip') return num; + let eq=player.getEquip(get.subtype(card)); + if(eq&&get.equipValue(card)-get.equipValue(eq)get.value(i)>Math.max(6,9-player.hp),'he')) return 1; + return 10; + }, result:{ player:1 }, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg&&arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&!player.getStat().skill.xinzhiheng&&player.hasCard((card)=>get.name(card)!=='tao','h'); + }, threaten:1.55 }, }, zhiheng:{ audio:2, audioname:['gz_jun_sunquan'], + mod:{ + aiOrder:function(player,card,num){ + if(num<=0||get.itemtype(card)!=='card'||get.type(card)!=='equip') return num; + let eq=player.getEquip(get.subtype(card)); + if(eq&&get.equipValue(card)-get.equipValue(eq)get.distance(player,current)==2&&!player.inRange(current)); - if(cnt>=2){ - if(att<0) return true; - return false; - } - if(att<0&&cnt>=2||att>0&&!cnt) return true; - return false; - } - else{ - if(att<0) return false; - return true; - } + let att=get.attitude(player,event.player); + if(att>0) return true; + if(!player.hasSkill('twzhiqu')) return false; + let cnt=game.countPlayer(current=>get.distance(player,current)===2); + if(cnt>2||cnt===2&&Math.abs(att)<2||cnt&&Math.abs(att)<1) return true; + return false; }, content:function(){ 'step 0' @@ -1126,20 +1118,21 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return _status.event.choice; }).set('choice',function(){ var att=get.attitude(target,player); - if(att==0) return 0; + if(att===0) return 0; if(player.hasSkill('twzhiqu')){ - var cnt=game.countPlayer(current=>get.distance(player,current)==2&&!player.inRange(current)); - if(cnt>=2){ - if(att<0) return 1; - return 0; + var cnt=game.countPlayer(current=>get.distance(player,current)===2); + if(att>0){ + if(cnt||player.needsToDiscard(1)) return 0; + return 1; } - if(att<0&&cnt>=2||att>0&&!cnt) return 1; + if(!cnt) return 0; + if(cnt>=2||get.distance(target,player,'attack')===2||get.distance(target,player)===2) return 1; return 0; } - else{ - if(att<0) return 0; - return [0,1].randomGet(); - } + if(att<0||player.needsToDiscard(1)&&game.hasPlayer(function(current){ + return current!==player&¤t!==target&&!player.inRange(current); + })) return 0; + return [0,1].randomGet(); }()); 'step 1' if(result.index==0){ @@ -1360,6 +1353,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ locked:false, direct:true, onremove:true, + intro:{ + content:'players' + }, filter:function(event,player){ return game.hasPlayer(current=>current!=player)&&(event.name!='phase'||game.phaseNumber==0); }, @@ -4570,6 +4566,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ forced:true, logTarget:'target', init:function(player){ + var target=_status.currentPhase; + if(!target||!target!=player) return; if(!player.getStorage('twxiangyu_range').length){ var targets=game.filterPlayer(current=>{ return current.getHistory('lose').length; @@ -4591,7 +4589,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, mod:{ attackRange:function(player,num){ - return num+player.getStorage('twxiangyu_range').length; + return num+Math.min(5,player.getStorage('twxiangyu_range').length); }, }, subSkill:{ @@ -4622,7 +4620,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ marktext:'羽', intro:{ content:function(storage,player){ - var num=storage?storage.length:0; + var num=Math.min(5,storage?storage.length:0); return '攻击范围+'+num; }, }, @@ -8220,7 +8218,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return names.length>0&&player.hasCard(function(card){ return names.includes(get.name(card)); },'hs'); - return false; + //return false; }, group:'twchaofeng_compare', chooseButton:{ @@ -11389,6 +11387,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, twzhian:{ audio:2, + init:function(player){ + game.addGlobalSkill('twzhian_ai'); + }, + onremove:function(player){ + game.removeGlobalSkill('twzhian_ai'); + }, usable:1, trigger:{global:'useCardAfter'}, direct:true, @@ -11468,6 +11472,28 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 2' if(result.bool&&target.getCards('ej').contains(trigger.cards[0])) player.gain(trigger.cards,target,'give','bySelf'); }, + subSkill:{ + ai:{ + trigger:{player:'dieAfter'}, + filter:function(event,player){ + return !game.hasPlayer((current)=>current.hasSkill('twzhian'),true); + }, + silent:true, + forceDie:true, + content:function(){ + game.removeGlobalSkill('twzhian_ai'); + }, + ai:{ + effect:{ + player:function(card,player,target){ + if(get.type(card)!=='delay'&&get.type(card)!=='equip') return 1; + let za=game.findPlayer((cur)=>cur.hasSkill('twzhian')&&(!cur.storage.counttrigger||!cur.storage.counttrigger.twzhian)&&get.attitude(player,cur)<=0); + if(za) return [0.5,-0.8]; + } + } + } + } + } }, twyujue:{ audio:2, @@ -14119,7 +14145,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ equan_info:'锁定技。①当有角色于你的回合内受到伤害后,其获得X枚“毒”(X为伤害值)。②准备阶段,你令所有拥有“毒”标记的角色移去所有“毒”标记并失去等量的体力。③当有角色因〖恶泉②〗进入濒死状态时,你令其所有技能失效直到回合结束。', manji:'蛮汲', manji_info:'锁定技。其他角色失去体力后,若你的体力值:不大于该角色,你回复1点体力;不小于该角色,你摸一张牌。', - wuban:'吴班', + wuban:'TW吴班', + wuban_prefix:'TW', jintao:'进讨', jintao_info:'锁定技,你使用【杀】无距离限制且次数上限+1。你于出牌阶段内使用的第一张【杀】伤害+1,第二张【杀】不可被响应。', yuejiu:'TW乐就', @@ -14275,7 +14302,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ twbingde_info:'出牌阶段限一次。你可以选择一个本阶段未选择过的花色并弃置一张牌,你摸等同于本阶段你使用此花色的牌数,然后若你以此法弃置的牌的花色与你选择的花色相同,你令你〖秉德〗于此阶段发动的次数上限+1。', twqingtao:'清滔', twqingtao_info:'①摸牌阶段结束时,你可以重铸一张牌。若此牌为【酒】或非基本牌,你摸一张牌。②结束阶段,若你本回合未发动〖清滔①〗,你可以发动〖清滔①〗。', - tw_jiangji:'蒋济', + tw_jiangji:'TW蒋济', + tw_jiangji_prefix:'TW', twjichou:'急筹', twjichou_info:'①每回合限一次。你可以视为使用一张未被〖急筹①〗记录过的普通锦囊牌并记录此牌。②你无法响应或{使用对应实体牌包含你的手牌的}〖急筹①〗记录过的锦囊牌。③出牌阶段限一次。你可将手牌中的一张〖急筹①〗记录过的锦囊牌交给其他角色。', twjilun:'机论', @@ -14308,7 +14336,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ twxiongzheng_info:'一轮游戏开始时,①若你上一轮发动过〖雄争〗且选择过“雄争”角色,你可以选择一项:1.视为对任意名上一轮内未对“雄争”角色造成过伤害的角色依次使用一张【杀】;2.令任意名上一轮对“雄争”角色造成过伤害的角色摸两张牌。②你可以选择一名未以此法选择过的角色,称为“雄争”角色。', twluannian:'乱年', twluannian_info:'主公技。其他群势力角色的出牌阶段限一次。其可以弃置X张牌并对“雄争”角色造成1点伤害(X为所有角色于本轮发动〖乱年〗的次数+1)。', - tw_baoxin:'鲍信', + tw_baoxin:'TW鲍信', + tw_baoxin_prefix:'TW', twmutao:'募讨', twmutao_info:'出牌阶段限一次。你可以选择一名角色,令其将手牌中所有的【杀】依次交给其下家开始的每一名角色。然后其对最后一名以此法获得【杀】的角色A造成X点伤害(X为A手牌中【杀】的数量且至多为2)。', twyimou:'毅谋', @@ -14473,7 +14502,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ tw_liuzhang_prefix:'TW', twyaohu:'邀虎', twyaohu_info:'每轮限一次。回合开始时,你须选择场上的一个势力。该势力的角色的出牌阶段开始时,其获得你的一张“生”,然后其须选择一项:1.对你指定的另一名的其他角色使用一张【杀】(无距离限制);2.本回合其使用伤害牌指定你为目标时须交给你两张牌,否则取消此目标。', - tw_liwei:'李遗', + tw_liwei:'TW李遗', + tw_liwei_prefix:'TW', twjiaohua:'教化', twjiaohua_info:'当你或体力值最小的其他角色因摸牌而得到牌后,你可以令该角色从牌堆或弃牌堆中获得一张本次未获得的类别的牌(每种类别每回合限一次)。', tw_yanxiang:'阎象', diff --git a/character/xianding.js b/character/xianding.js index 9e66a7107..d56ec2ef2 100644 --- a/character/xianding.js +++ b/character/xianding.js @@ -94,8 +94,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp2_wangzhe:['dc_daxiaoqiao','dc_sp_machao'], sp2_doukou:['re_xinxianying','huaman','xuelingyun','dc_ruiji','duanqiaoxiao','tianshangyi'], sp2_jichu:['zhaoang','dc_liuye','dc_wangyun','yanghong','huanfan','xizheng'], - sp2_yuxiu:['dongguiren','dc_tengfanglan','zhangjinyun','zhoubuyi'], - sp2_qifu:['ol_guansuo','dc_zhaoxiang','dc_xujing'], + sp2_yuxiu:['dongguiren','dc_tengfanglan','zhangjinyun','zhoubuyi','dc_xujing'], + sp2_qifu:['ol_guansuo','dc_zhaoxiang'], sp2_gaoshan:['wanglang','liuhui'], sp2_wumiao:['wu_zhugeliang','wu_luxun'], } @@ -2358,22 +2358,28 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }).set('choice',(()=>{ var choicesx=choices.slice(); var cards=player.getCards('hs'); - var bool1=get.tag(trigger.card,'damage')&&choicesx.contains('选项一')&&trigger.targets.some(current=>{ + var bool1=get.tag(trigger.card,'damage')&&choicesx.includes('选项一')&&trigger.targets.some(current=>{ return get.attitude(player,current)<0; - }),bool2=choicesx.contains('选项二')&&game.countPlayer(current=>get.attitude(player,current)>0)>=1; - if(!bool1&&!bool2){ + }),bool2=choicesx.includes('选项二'); + if(bool2) bool2=game.countPlayer(function(current){ + return player!=current&&get.attitude(player,current)>0; + }); + else bool2=0; + if(bool1||bool2){ for(var i=0;i2) return '选项二'; + if(choicesx.includes('选项三')) return '选项三'; + if(bool2===2) return '选项二'; if(bool1) return '选项一'; if(bool2) return '选项二'; return 'cancel2'; @@ -2486,6 +2492,25 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, subSkill:{ effect:{ + mod:{ + aiOrder:function(player,card,num){ + if(num>0&&get.itemtype(card)==='card'&&card.hasGaintag('dczhizhe')) return num+0.16; + }, + aiValue:function(player,card,num){ + if(num>0&&get.itemtype(card)==='card'&&card.hasGaintag('dczhizhe')) return 2*num; + }, + aiUseful:function(player,card,num){ + if(num>0&&!player._dczhizhe_mod&&get.itemtype(card)==='card'&&card.hasGaintag('dczhizhe')){ + if(player.canIgnoreHandcard(card)) return Infinity; + player._dczhizhe_mod=true; + if(player.hp<3&&player.needsToDiscard(player.countCards('h',(cardx)=>{ + if(player.canIgnoreHandcard(cardx)||get.useful(cardx)>6) return true; + return false; + }))) return num*1.5; + return num*10; + } + } + }, trigger:{player:['useCardAfter','respondAfter']}, charlotte:true, forced:true, @@ -2778,7 +2803,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ order:1, result:{ target:function(player,target){ - if(game.roundNumber==1&&ui.cardPile.childNodes.length>game.countPlayer()*5&&!game.hasPlayer(current=>current.hp<=2)&&!player.hasSkill('dcjijiao_risutoa')) return 0; + if(ui.cardPile.childNodes.length>game.players.length*5&&!player.hasSkill('dcjijiao_risutoa')&& + !game.hasPlayer(current=>current.hp<=1)&&game.countPlayer(current=>current.hp===2&¤t.countCards('hes')<3)<=1) return 0; return 5; } } @@ -3028,8 +3054,43 @@ game.import('character',function(lib,game,ui,get,ai,_status){ },true); }, ai:{ - order:5.5, - result:{player:1} + order:function(){ + return 0.9*get.order({name:'juedou'}); + }, + tag:{ + respond:2, + respondSha:2, + damage:1, + }, + result:{ + player:function(player){ + let target=null, maxval=0; + for(let i of game.players){ + let jdeff=get.effect(i,{ + name:'juedou', + isCard:true, + cards:ui.selected.cards, + storage:{dcctjiuxian:true} + },player,player); + if(i===player||!player.canUse({ + name:'juedou', + isCard:true, + cards:ui.selected.cards, + storage:{dcctjiuxian:true} + },i)||jdeff<0) continue; + let receff=0; + game.filterPlayer(function(current){ + if(player!=current&&i.inRange(current)&¤t.isDamaged()) receff=Math.max(receff,get.recoverEffect(current,i,i)); + }); + if(jdeff+receff/5>maxval){ + target=i; + maxval=jdeff+receff/5; + } + } + if(target) return maxval/80; + return 0; + } + } }, subSkill:{ help:{ @@ -3609,6 +3670,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.logSkill('dcyuandi',target); if(result.control=='选项一'){ player.discardPlayerCard(target,'h',true); + if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.15); } else game.asyncDraw([target,player]); } @@ -3863,6 +3925,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, dcaichen:{ audio:2, + init:function(player){ + game.addGlobalSkill('dcaichen_hit'); + }, + onremove:function(player){ + game.removeGlobalSkill('dcaichen_hit'); + }, trigger:{ player:['loseAfter','phaseDiscardBefore'], global:'loseAsyncAfter', @@ -3886,6 +3954,25 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger.directHit.add(player); game.log(player,'不可响应',trigger.card); } + }, + subSkill:{ + hit:{ + trigger:{player:'dieAfter'}, + filter:function(event,player){ + return !game.hasPlayer(current=>current.hasSkill('dcaichen')); + }, + silent:true, + forceDie:true, + content:function(){ + game.removeGlobalSkill('dcaichen_hit'); + }, + ai:{ + directHit_ai:true, + skillTagFilter:function(player,tag,arg){ + return arg&&arg.card&&arg.target&&arg.target.hasSkill('dcaichen')&&ui.cardPile.childNodes.length<40&&get.suit(arg.card)==='spade'; + } + } + } } }, //杨彪 @@ -4348,7 +4435,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(cards.length){ player.chooseButton(['暗织:选择令'+get.translation(target)+'获得的牌',cards],true,Math.min(cards.length,2)).set('ai',button=>{ var player=_status.event.player,target=_status.event.getParent().target; - return get.sgnAttitude(player,target)*get.buttonValue(button); + return get.sgnAttitude(player,target)*get.value(button.link,target); }); } }else event.finish(); @@ -4498,11 +4585,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ //周宣 dcwumei:{ audio:2, - trigger:{player:'phaseBegin'}, + trigger:{player:'phaseBeginStart'}, filter:function(event,player){ return !player.hasSkill('dcwumei_used'); }, - priority:10,//离谱的优先机制 direct:true, content:function(){ 'step 0' @@ -4529,17 +4615,27 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger._triggered=5; var evt=player.insertPhase(); delete evt.skill; + game.broadcastAll(function(player){ + player.classList.remove('glow_phase'); + delete _status.currentPhase; + },player); } } }, subSkill:{ used:{charlotte:true}, wake:{ + init:function(player){ + game.addGlobalSkill('dcwumei_all'); + }, + onremove:function(player){ + game.removeGlobalSkill('dcwumei_all'); + delete player.storage.dcwumei_wake; + }, trigger:{player:'phaseJieshuBegin'}, charlotte:true, popup:false, forced:true, - onremove:true, filter:function(event,player){ return player.storage.dcwumei_wake&&player.storage.dcwumei_wake.length; }, @@ -4572,17 +4668,23 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } return str; } + } + }, + all:{ + trigger:{player:'dieAfter'}, + filter:function(event,player){ + return !game.hasPlayer(current=>current.hasSkill('dcwumei_wake')); + }, + silent:true, + forceDie:true, + content:function(){ + game.removeGlobalSkill('dcwumei_all'); }, ai:{ effect:{ player_use:function(card,player,target){ + if(get.tag(card,'recover')&&target.hp>0) return 0; if(get.tag(card,'damage')) return 0.5; - }, - target:function(card,player,target){ - if(_status.event.type!='phase') return; - if (get.tag(card,'recover')){ - return [1,1-target.hp]; - } } } } @@ -7722,6 +7824,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ onremove:true, subSkill:{ insert:{ + mark:true, + intro:{ + content:'players' + }, trigger:{global:'phaseAfter'}, forced:true, charlotte:true, @@ -10447,6 +10553,22 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ player.draw(2+get.sgn(trigger.player.hp-player.hp)); }, + ai:{ + effect:{ + target:function(card,player,target){ + if(get.itemtype(player)!=='player'||player===target) return 1; + let num=1,ds=2+get.sgn(player.hp-target.hp); + if(player===_status.currentPhase&&_status.currentPhase.group==='qun'&&target.hasZhuSkill('yuwei',player)) num=2; + if(target.getHistory('gain',function(evt){ + return evt.getParent(2).name==='shiyuan'&&evt.cards.length===ds; + }).length>=num) return 1; + let name=get.name(card); + if(get.tag(card,'lose')||name==='huogong'||name==='juedou'||name==='tiesuo') return [1,ds]; + if(!target.hasFriend()) return 1; + return [1,0.8*ds]; + } + } + } }, dushi:{ audio:2, @@ -10483,8 +10605,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, yuwei:{ + audio:2, + trigger:{player:'shiyuanBegin'}, + filter:function(event,player){ + return _status.currentPhase.group=='qun'; + }, zhuSkill:true, - locked:true, + forced:true, + content:function(){}, ai:{combo:'shiyuan'}, }, @@ -10903,11 +11031,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.judge(function(card){ var type=get.subtype(card); return ['equip1','equip4','equip3','equip6'].contains(type)?6:-6; - switch(type){ - case 'equip':return 4; - case 'trick':return -4; - default:return 0; - } + // switch(type){ + // case 'equip':return 4; + // case 'trick':return -4; + // default:return 0; + // } }).judge2=function(result){ return result.bool; }; @@ -10986,7 +11114,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return true; }, viewAs:{name:'nanman'}, - ai:{order:0.1}, + ai:{ + order:0.1, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&!player.getStat('skill').mansi_viewas&&player.hasCard((card)=>get.name(card)!=='tao','h'); + } + }, }, souying:{ audio:2, @@ -12235,6 +12369,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ luotong:['dc_luotong','luotong'], dc_wangchang:['dc_wangchang','tw_wangchang'], guozhao:['guozhao','xin_guozhao'], + dingshangwan:['dingshangwan','ol_dingshangwan'], }, translate:{ puyuan:'蒲元', diff --git a/character/yijiang.js b/character/yijiang.js index f3ef1ad37..0c594624c 100755 --- a/character/yijiang.js +++ b/character/yijiang.js @@ -2420,13 +2420,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var player=_status.event.player; var target=_status.event.target; var controls=_status.event.controls.slice(); - controls.sort(function(a,b){ - return [ - get.effect(target,{name:'wuzhong'},player,player)/2, - get.effect(target,{name:'guohe_copy2'},player,player), - get.effect(target,{name:'kaihua'},player,player), - ][['摸牌','弃牌','制衡'].indexOf(b)-['摸牌','弃牌','制衡'].indexOf(a)]; - }); + var map={ + '摸牌':get.effect(target,{name:'wuzhong'},player,player)/2, + '弃牌':get.effect(target,{name:'guohe_copy2'},player,player), + '制衡':get.effect(target,{name:'kaihua'},player,player), + }; + controls.sort((a,b)=>map[b]-map[a]); return controls[0]; }).set('target',target); } @@ -2509,10 +2508,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ol_guansuo:'dangxian_guansuo', }, content:function(){ - var next=player.phaseUse(); - next.xindangxian=true; - event.next.remove(next); - trigger.next.push(next); + trigger.phaseList.splice(trigger.num,0,'phaseUse|xindangxian'); }, group:'xindangxian_rewrite', subSkill:{ @@ -2521,7 +2517,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ forced:true, popup:false, filter:function(kagari){ - return kagari.xindangxian==true; + return kagari._extraPhaseReason=='xindangxian'; }, content:function(){ 'step 0' @@ -7665,9 +7661,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ audio:2, audioname:['guansuo'], content:function(){ - var next=player.phaseUse(); - event.next.remove(next); - trigger.next.push(next); + trigger.phaseList.splice(trigger.num,0,'phaseUse|dangxian'); } }, longyin:{ @@ -8484,6 +8478,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(target.countCards('h','sha')>1) return 'zeroplayertarget'; } } + }, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&player.countSkill('zhanjue_draw')<2&&player.hasCard((card)=>get.name(card)!='tao','h'); } } }, @@ -10585,6 +10583,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, content:function(){ "step 0" + if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.2); player.draw(2); "step 1" player.chooseCard(2,'he',true,'交给'+get.translation(trigger.player)+'两张牌').set('ai',function(card){ @@ -10599,8 +10598,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger.player.storage.xiantu4.push(player); }, ai:{ - threaten:1.1, - expose:0.3 + threaten:1.1 } }, xiantu1:{audio:true}, @@ -12567,13 +12565,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){ usable:1, audio:'qice_backup', filter:function(event,player){ - var hs=player.getCards('h'); + const hs=player.getCards('h'); if(!hs.length) return false; - for(var i=0;i{ + const mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); + return (mod2===false) + })) return false; + return lib.inpile.some(name=>{ + if(get.type(name)!='trick') return false; + const card=get.autoViewAs({name},hs); + return event.filterCard(card,player,event); + }); }, chooseButton:{ dialog:function(player){ @@ -12584,7 +12586,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return ui.create.dialog(get.translation('qice'),[list,'vcard']); }, filter:function(button,player){ - return lib.filter.filterCard({name:button.link[2]},player,_status.event.getParent()); + const event=_status.event.getParent(),card=get.autoViewAs({ + name:button.link[2], + },player.getCards('h')); + return event.filterCard(card,player,event); }, check:function(button){ var player=_status.event.player; @@ -12655,6 +12660,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return 12-num; } }, + nokeep:true, + skillTagFilter:function(player,tag,arg){ + if(tag==='nokeep') return (!arg||arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&!player.getStat('skill').qice&&player.hasCard((card)=>get.name(card)!='tao','h'); + }, threaten:1.6, } }, @@ -12793,7 +12802,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ audio:2, enable:'phaseUse', filter:function(event,player){ - return true;//player.countCards('h')>player.maxHp; + return player.countCards('h')>player.maxHp; }, usable:1, content:function(){ @@ -14499,7 +14508,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ olddanshou_info:'当你造成伤害后,你可以摸一张牌。若如此做,终止一切结算,当前回合结束。', xindanshou_info:'①每回合限一次,当你成为基本牌或锦囊牌的目标后,你可以摸X张牌(X为你本回合内成为过基本牌或锦囊牌的目标的次数)。②一名其他角色的结束阶段,若你本回合内没有发动过〖胆守①〗,则你可以弃置X张牌并对其造成1点伤害(X为其手牌数,无牌则不弃)。', yizhong_info:'锁定技,当你的防具栏为空时,黑色的【杀】对你无效', - xinzhan_info:'出牌阶段限一次,你可以观看牌堆顶的3张牌,然后展示其中任意数量♥的牌并获得之。', + xinzhan_info:'出牌阶段限一次,若你的手牌数大于你的体力上限,你可以观看牌堆顶的三张牌,然后展示其中任意红桃牌并获得之。', huilei_info:'锁定技,当你死亡时,杀死你的角色弃置所有的牌。', enyuan_info:'锁定技。①当其他角色令你回复1点体力后,该角色摸一张牌。②当其他角色对你造成伤害后,其须交给你一张♥手牌,否则失去1点体力。', xuanhuo_info:'出牌阶段限一次,你可以将一张红桃手牌交给一名其他角色,获得该角色的一张牌,然后交给除该角色外的一名其他角色', diff --git a/character/yingbian.js b/character/yingbian.js index e6f489f3c..181424f12 100644 --- a/character/yingbian.js +++ b/character/yingbian.js @@ -2592,10 +2592,21 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return player!=event.player&&event.num-2) return false; - if(player.hp>2) return true; - if(player.hp==2&&event.player.hp<3) return false; - return player.hp>1; + if(event.player.hasSkillTag('nodamage')) return false; + let tj = player.countCards('hs', function (card) { + return get.name(card) === 'tao' || get.name(card) === 'jiu'; + }), + att = get.attitude(_status.event.player, event.player), + eff = get.damageEffect(event.player, player, _status.event.player, event.nature), + fd = event.player.hasSkillTag('filterDamage', null, { + player: player, + card: event.card + }), + hp = player.hp + tj; + if(player.storage.tairan2) hp -= player.storage.tairan2; + if(eff <= 0 || fd || att >= -2 || Math.abs(hp) <= 1) return false; + if(hp > 2 || event.player.isLinked() && event.nature && eff > 0) return true; + return !event.player.countCards('hs') || event.player.hp > 2 * event.num && !event.player.hasSkillTag('maixie'); }, logTarget:'player', content:function(){ @@ -2604,6 +2615,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger.yimie_num=trigger.player.hp-trigger.num; trigger.num=trigger.player.hp; }, + ai:{ + damageBonus:true, + skillTagFilter:function(player,tag,arg){ + return arg && arg.target && arg.target.hp > 1 && player.hp > 1 && get.attitude(player, arg.target) < -2; + } + } }, yimie2:{ trigger:{player:'damageEnd'}, diff --git a/character/yxs.js b/character/yxs.js index cb0cc5364..bb9250ed1 100644 --- a/character/yxs.js +++ b/character/yxs.js @@ -92,40 +92,39 @@ game.import('character',function(lib,game,ui,get,ai,_status){ yxs_meixi:'妺喜,姓嬉(喜),生卒年不详,亦作妺嬉、末喜、末嬉,有施氏之女,夏朝最后一位君主夏桀的王后。根据先秦时代记述女子名时所用的全称和简称方式,妺喜应姓喜,即嬉(也作僖)。由于其名字的“妺”字与“妹妹”的“妹”字字形相似,且在《庄子》等作中也有以妺为妹的用法,因此常误作"妹喜"。', yxs_lanlinwang:'高长恭(541年―573年),又名高孝瓘、高肃,祖籍渤海调蓨(今河北省景县),神武帝高欢之孙,文襄帝高澄第四子,生母不详,南北朝时期北齐宗室、将领,封爵兰陵郡王。高长恭貌柔心壮,音容兼美。为将躬勤细事,每得甘美,虽一瓜数果,必与将士分享。累次升任至并州刺史。突厥攻入晋阳,高长恭奋力将其击退。邙山之战,高长恭为中军,率领五百骑兵再入周军包围圈,直至金墉城下,因高长恭戴着头盔,城中的人不确定是敌军或是我军,直到高长恭把头盔脱下来城上的人才知道是高长恭,派弓箭手开始放箭保护他,之后高长恭成功替金墉解围,高长恭在此次战中威名大振,士兵们为此战而讴歌他,即后来知名的《兰陵王入阵曲》。', }, - characterTitle:{ - "yxs_qinqiong":"Sukincen", - }, + characterTitle:{ + yxs_qinqiong:"Sukincen", + }, skill:{ yxs_fanji:{ - audio:2, - trigger:{ - player:"damageEnd", - }, - direct:true, - priority:12, - filter:function (event,player){ - if(!player.countCards('h',{name:'sha'})) return false; - return event.card.name=='sha'||event.card.name=='juedou'; - }, - content:function (){ - player.addTempSkill('yxs_fanji2','shaAfter'); - player.chooseToUse({name:'sha'},trigger.source,'反击:是否对'+get.translation(trigger.source)+'使用一张杀?').logSkill='yxs_fanji'; - }, - }, - yxs_fanji2:{ - audio:2, - trigger:{ - player:"shaBegin", - }, - direct:true, - filter:function (event,player){ - return event.card&&event.card.name=='sha'&&get.color(event.card)=='red'; - }, - content:function (){ - trigger.directHit=true; - }, - }, - + audio:2, + trigger:{ + player:"damageEnd", + }, + direct:true, + priority:12, + filter:function (event,player){ + if(!player.countCards('h',{name:'sha'})) return false; + return event.card&&(event.card.name=='sha'||event.card.name=='juedou'); + }, + content:function(){ + player.addTempSkill('yxs_fanji2','shaAfter'); + player.chooseToUse({name:'sha'},trigger.source,'反击:是否对'+get.translation(trigger.source)+'使用一张杀?').logSkill='yxs_fanji'; + }, + }, + yxs_fanji2:{ + audio:2, + trigger:{ + player:"shaBegin", + }, + direct:true, + filter:function (event,player){ + return event.card&&event.card.name=='sha'&&get.color(event.card)=='red'; + }, + content:function (){ + trigger.directHit=true; + }, + }, yxs_menshen3:{ trigger:{ player:['phaseBegin','dieBegin'], @@ -133,78 +132,75 @@ game.import('character',function(lib,game,ui,get,ai,_status){ silent:true, filter:function(event,player){ return game.hasPlayer(function(current){ - return current.hasSkill('yxs_menshen2'); - }); + return current.hasSkill('yxs_menshen2'); + }); }, content:function(){ - for(var i=0;i1; - }, - content:function (){ - "step 0" - player.chooseTarget('选择【门神】的目标',lib.translate.yxs_menshen_info,true,function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - return get.attitude(player,target); - }); - "step 1" - if(result.bool){ - var target=result.targets[0]; + }, + yxs_menshen:{ + audio:2, + trigger:{ + player:"phaseEnd", + }, + priority:15, + group:'yxs_menshen3', + onremove:true, + filter:function (event,player){ + return game.players.length>1; + }, + content:function(){ + "step 0" + player.chooseTarget('选择【门神】的目标',lib.translate.yxs_menshen_info,true,function(card,player,target){ + return target!=player; + }).set('ai',function(target){ + return get.attitude(player,target); + }); + "step 1" + if(result.bool){ + var target=result.targets[0]; player.line(target,'green'); game.log(target,'成为了','【门神】','的目标'); target.storage.yxs_menshen2=player; target.addSkill('yxs_menshen2'); - } - else { - event.finish(); - } - }, - ai:{ - expose:0.5, - }, - }, - - yxs_menshen2:{ - audio:2, - mark:'character', + } + else{ + event.finish(); + } + }, + ai:{ + expose:0.5, + }, + }, + yxs_menshen2:{ + audio:2, + mark:'character', intro:{ content:'当你成为【杀】或【决斗】的目标后,改为$成为目标' }, nopop:true, - priority:15, - trigger:{ - target:["shaBegin","juedouBegin"], - }, - forced:true, + priority:15, + trigger:{ + target:["shaBegin","juedouBegin"], + }, + forced:true, popup:false, filter:function(event,player){ return player.isAlive(); }, - content:function (){ - var target=player.storage.yxs_menshen2; - trigger.player.line(target,'green'); - trigger.targets.remove(player); - trigger.targets.push(target); - trigger.target = target; - }, - }, - + content:function (){ + var target=player.storage.yxs_menshen2; + trigger.player.line(target,'green'); + trigger.targets.remove(player); + trigger.targets.push(target); + trigger.target = target; + }, + }, guimian:{ trigger:{source:'damageEnd'}, forced:true, @@ -2938,12 +2934,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ yxs_qinqiong:"秦琼", yxs_fanji:"反击", - yxs_fanji2:"反击", - yxs_fanji_info:"当你受到【杀】或【决斗】造成的伤害后,你可以对伤害来源使用一张【杀】。若此【杀】为红色,其不可闪避", - yxs_menshen:"门神", - yxs_menshen2:"门神", - yxs_menshen3:"门神", - yxs_menshen_info:"回合结束阶段,你可选择一名其他角色,若如此做,直到你的下回合开始,所有角色对该角色使用的【杀】或【决斗】均视为对你使用", + yxs_fanji2:"反击", + yxs_fanji_info:"当你受到【杀】或【决斗】造成的伤害后,你可以对伤害来源使用一张【杀】。若此【杀】为红色,其不可闪避", + yxs_menshen:"门神", + yxs_menshen2:"门神", + yxs_menshen3:"门神", + yxs_menshen_info:"回合结束阶段,你可选择一名其他角色,若如此做,直到你的下回合开始,所有角色对该角色使用的【杀】或【决斗】均视为对你使用", zhuxin:'诛心', zhuxin_info:'出牌阶段限一次,你可以与一名其他角色拼点,若你赢,你对其造成一点伤害', wlianhuan:'连环', diff --git a/game/game.js b/game/game.js index c7cc4c2ba..094630e79 100644 --- a/game/game.js +++ b/game/game.js @@ -1,12 +1,12 @@ "use strict"; { + const userAgent=navigator.userAgent.toLowerCase(); 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'); + const ios=userAgent.includes('iphone')||userAgent.includes('ipad')||userAgent.includes('macintosh'); //electron if(typeof window.process=='object'&&typeof window.require=='function'){ const versions=window.process.versions; @@ -117,6 +117,7 @@ mirrorURL:'https://raw.fgit.cf/libccy/noname', hallURL:'47.99.105.222', assetURL:typeof nonameInitialized!='string'||nonameInitialized=='nodejs'?'':nonameInitialized, + userAgent:userAgent, compatibleEdition:Boolean(typeof nonameInitialized=='string'&&nonameInitialized.match(/\/(?:com\.widget|yuri\.nakamura)\.noname\//)), changeLog:[], updates:[], @@ -282,6 +283,17 @@ if(lineColor.length) lib.lineColor.set(nature,lineColor); lib.nature.set(nature,order); if(background.length>0) lib.natureBg.set(nature,background); + if(config.audio){ + for(let key in config.audio){ + if(!lib.natureAudio[key]){ + lib.natureAudio[key] = config.audio[key]; + }else{ + for(let key2 in config.audio[key]){ + lib.natureAudio[key][key2] = config.audio[key][key2]; + } + } + } + } let color1,color2; if (typeof config.color=="string"&&/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(config.color)){ @@ -621,6 +633,12 @@ general:{ name:'通用', config:{ + mount_combine:{ + name:'合并坐骑栏', + init:false, + intro:'
  • 将进攻坐骑栏和防御坐骑栏合并为同一个位置(重启后生效)。', + restart:true, + }, low_performance:{ name:'流畅模式', init:false, @@ -8417,7 +8435,7 @@ } }); /*Map prototype end*/ - Object.defineProperty(Array.prototype, "filterInD", { + Object.defineProperty(Array.prototype,"filterInD",{ configurable:true, enumerable:false, writable:true, @@ -8426,7 +8444,7 @@ return this.filter(card=>pos.includes(get.position(card,true))); } }); - Object.defineProperty(Array.prototype, "someInD", { + Object.defineProperty(Array.prototype,"someInD",{ configurable:true, enumerable:false, writable:true, @@ -8435,132 +8453,161 @@ 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. + *@legacy Use `Array.prototype.includes(searchElement)` instead. */ - Object.defineProperty(Array.prototype, "contains", { + Object.defineProperty(Array.prototype,"contains",{ configurable:true, enumerable:false, writable:true, value:Array.prototype.includes }); - Object.defineProperty(Array.prototype, "add", { + Object.defineProperty(Array.prototype,"containsSome",{ configurable:true, enumerable:false, writable:true, value:function(){ - for(var i=0;ithis.includes(i)); } }); - Object.defineProperty(Array.prototype, "addArray", { - configurable:true, - enumerable:false, - writable:true, - value:function(arr){ - for(var i=0;ithis.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;ithis.length){ - num=this.length; - } - var arr=this.slice(0); - var list=[]; - for(var i=0;ithis.length) num=this.length; + let arr=this.slice(0); + let list=[]; + for(let i=0;itrue)); + 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',{ @@ -8810,7 +8882,7 @@ } var noname_inited=localStorage.getItem('noname_inited'); if(noname_inited&&noname_inited!=='nodejs'){ - var ua=navigator.userAgent.toLowerCase(); + var ua=userAgent; if(ua.includes('android')){ lib.device='android'; } @@ -8976,7 +9048,7 @@ appearenceConfig.global_font.item.default='默认'; } - var ua=navigator.userAgent.toLowerCase(); + var ua=userAgent; if('ontouchstart' in document){ if(!lib.config.totouched){ game.saveConfig('totouched',true); @@ -10455,7 +10527,8 @@ 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']); + lib.extensions[i][4].skill.translate[j+'_append'], + lib.extensions[i][4].skill.translate[j+'_ab']); } } } @@ -11065,10 +11138,18 @@ }, parsex:function(item){ //by 诗笺、Tipx-L + /** + * @param {Function} func + */ 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(); + //判断代码中是否有debugger + var regex=/event\.debugger\(\)/g; + var hasDebugger=regex.test(str); + var insertDebugger=`yield code=>eval(code);`; + str=str.replaceAll(regex,insertDebugger); //获取第一个 { 后的所有字符 str=str.slice(str.indexOf('{')+1); //func中要写步骤的话,必须要写step 0 @@ -11092,7 +11173,7 @@ copy=copy.slice(0,skip+result.index)+insertStr+copy.slice(skip+result.index+result[0].length); //测试是否有错误 try{ - new Function(copy); + new (hasDebugger?GeneratorFunction:Function)(copy); str=copy; skip+=result.index+insertStr.length; }catch(error){ @@ -11102,7 +11183,7 @@ } str=`if(event.step==${k}){event.finish();return;}`+str; } - return (new Function('event','step','source','player','target','targets', + return (new (hasDebugger?GeneratorFunction:Function)('event','step','source','player','target','targets', 'card','cards','skill','forced','num','trigger','result', '_status','lib','game','ui','get','ai',str)); } @@ -12267,17 +12348,33 @@ 'step 0' event.cards=[]; event.num=0; - event.slotsx=[...new Set(event.slots)].sort(); + event.slotsx=[]; + if(get.is.mountCombined()){ + event.slots.forEach(type=>{ + if(type=='equip3'||type=='equip4') event.slotsx.add('equip3_4'); + else event.slotsx.add(type) + }); + } + else{ + event.slotsx.addArray(event.slots); + } + event.slotsx.sort(); if(!event.slots.length) event.finish(); 'step 1' var slot=event.slotsx[event.num]; - var left=player.countEnabledSlot(slot),lose=Math.min(left,get.numOf(event.slots,slot)); + var slot_key=slot; + var left=player.countEnabledSlot(slot),lose; + if(slot=='equip3_4'){ + lose=Math.min(left,Math.max(get.numOf(event.slots,'equip3'),get.numOf(event.slots,'equip4'))); + slot_key='equip3'; + } + else lose=Math.min(left,get.numOf(event.slots,slot)); if(lose<=0) event.goto(3); else{ game.log(player,'废除了'+get.cnNumber(lose)+'个','#g'+get.translation(slot)+'栏'); if(!player.disabledSlots) player.disabledSlots={}; - if(!player.disabledSlots[slot]) player.disabledSlots[slot]=0; - player.disabledSlots[slot]+=lose; + if(!player.disabledSlots[slot_key]) player.disabledSlots[slot_key]=0; + player.disabledSlots[slot_key]+=lose; var cards=player.getEquips(slot).filter(card=>!event.cards.contains(card)); if(cards.length>0){ if(lose>=left){ @@ -12292,6 +12389,7 @@ ],true,[1,num]).set('filterOk',function(){ var evt=_status.event; return ui.selected.buttons.reduce(function(num,button){ + if(evt.slot=='equip3_4') return num+Math.max(get.numOf(get.subtypes(button.link,false),'equip3'),get.numOf(get.subtypes(button.link,false),'equip4')); return num+get.numOf(get.subtypes(button.link,false),evt.slot) },0)==evt.required; }).set('required',num).set('slot',slot) @@ -12327,13 +12425,27 @@ }, expandEquip:function(){ if(!event.slots.length) return; - var slotsx=[...new Set(event.slots)].sort(); + var slotsx=[]; + if(get.is.mountCombined()){ + event.slots.forEach(type=>{ + if(type=='equip3'||type=='equip4') slotsx.add('equip3_4'); + else slotsx.add(type) + }); + } + else{ + slotsx.addArray(event.slots); + } + slotsx.sort(); for(var slot of slotsx){ - var expand=get.numOf(event.slots,slot); + var expand=get.numOf(event.slots,slot),slot_key=slot; + if(slot=='equip3_4'){ + expand=Math.max(get.numOf(event.slots,'equip3'),get.numOf(event.slots,'equip4')); + slot_key='equip3'; + } game.log(player,'获得了'+get.cnNumber(expand)+'个额外的','#g'+get.translation(slot)+'栏'); if(!player.expandedSlots) player.expandedSlots={}; - if(!player.expandedSlots[slot]) player.expandedSlots[slot]=0; - player.expandedSlots[slot]+=expand; + if(!player.expandedSlots[slot_key]) player.expandedSlots[slot_key]=0; + player.expandedSlots[slot_key]+=expand; } player.$syncExpand(); }, @@ -12353,13 +12465,25 @@ else{ event.num=0; event.slots=types; - event.slotsx=[...new Set(event.slots)].sort(); + event.slotsx=[]; + if(get.is.mountCombined()){ + event.slots.forEach(type=>{ + if(type=='equip3'||type=='equip4') event.slotsx.add('equip3_4'); + else event.slotsx.add(type) + }); + } + else{ + event.slotsx.addArray(event.slots); + } + event.slotsx.sort(); } } else event.goto(4); 'step 1' var slot=event.slotsx[event.num]; - var left=player.countEquipableSlot(slot),lose=Math.min(left,get.numOf(event.slots,slot)); + var left=player.countEquipableSlot(slot),lose; + if(slot=='equip3_4') lose=Math.min(left,Math.max(get.numOf(event.slots,'equip3'),get.numOf(event.slots,'equip4'))); + else lose=Math.min(left,get.numOf(event.slots,slot)); if(lose<=0) event.goto(3); else{ var cards=player.getEquips(slot).filter(card=>{ @@ -12378,6 +12502,7 @@ ],true,[1,num]).set('filterOk',function(){ var evt=_status.event; return ui.selected.buttons.reduce(function(num,button){ + if(evt.slot=='equip3_4') return num+Math.max(get.numOf(get.subtypes(button.link,false),'equip3'),get.numOf(get.subtypes(button.link,false),'equip4')); return num+get.numOf(get.subtypes(button.link,false),evt.slot) },0)==evt.required; }).set('required',num).set('slot',slot) @@ -13482,7 +13607,7 @@ if(player.hasEnabledSlot(i)) list.push('equip'+i); } if(event.horse){ - if(list.contains('equip3')&&list.contains('equip4')) list.push('equip3_4'); + if(list.contains('equip3')&&(get.is.mountCombined()||list.contains('equip4'))) list.push('equip3_4'); list.remove('equip3'); list.remove('equip4'); } @@ -14318,7 +14443,7 @@ next.setContent(info.content); next.skillHidden=event.skillHidden; if(info.forceDie) next.forceDie=true; - if(info.forceOut||event.skill=='_turnover') next.includeOut=true; + if(info.forceOut) next.includeOut=true; "step 4" if(player._hookTrigger){ for(var i=0;i0){ + 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;igame.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(num1){ + 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{ + game.playCardAudio(card,player); + /* if(!lib.config.background_audio||get.type(card)=='equip'&&!lib.config.equip_audio) return; const sex=player.sex=='female'?'female':'male'; var nature=get.natureList(card)[0]; @@ -17743,7 +18066,7 @@ 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); + else game.playAudio('card',sex,card.name);*/ },player,card); if(event.animate!=false&&event.line!=false){ if(card.name=='wuxie'&&event.getParent()._info_map){ @@ -18553,6 +18876,8 @@ } else if(!event.nopopup) player.tryCardAnimate(card,card.name,'wood'); if(cardaudio&&event.getParent(3).name=='useCard') game.broadcastAll((player,card)=>{ + game.playCardAudio(card,player); + /* if(!lib.config.background_audio) return; const sex=player.sex=='female'?'female':'male',audio=lib.card[card.name].audio; if(typeof audio=='string'){ @@ -18561,7 +18886,7 @@ 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); + else game.playAudio('card',sex,card.name);*/ },player,card); if(event.skill){ if(player.stat[player.stat.length-1].skill[event.skill]==undefined){ @@ -19299,29 +19624,30 @@ 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); + if(player.hujia>0 && !player.hasSkillTag('nohujia')){ + var damageAudioInfo = lib.natureAudio.hujia_damage[event.nature]; + if(!damageAudioInfo || damageAudioInfo == 'normal'){ + damageAudioInfo = 'effect/hujia_damage'+(num>1?'2':'')+'.mp3'; + }else if(damageAudioInfo == 'default'){ + damageAudioInfo = 'effect/hujia_damage_'+event.nature+(num>1?'2':'')+'.mp3'; + }else{ + damageAudioInfo = damageAudioInfo[num >1 ?2:1]; } - 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); + game.broadcastAll(function(damageAudioInfo){ + if(lib.config.background_audio) game.playAudio(damageAudioInfo); + },damageAudioInfo); + }else{ + var damageAudioInfo = lib.natureAudio.damage[event.nature]; + if(!damageAudioInfo || damageAudioInfo == 'normal'){ + damageAudioInfo = 'effect/damage'+(num>1?'2':'')+'.mp3'; + }else if(damageAudioInfo == 'default'){ + damageAudioInfo = 'effect/damage_'+event.nature+(num>1?'2':'')+'.mp3'; + }else{ + damageAudioInfo = damageAudioInfo[num >1 ?2:1]; } + game.broadcastAll(function(damageAudioInfo){ + if(lib.config.background_audio) game.playAudio(damageAudioInfo); + },damageAudioInfo); } var str=event.unreal?'视为受到了':'受到了'; if(source) str+='来自'+(source==player?'自己':get.translation(source))+'的'; @@ -19652,8 +19978,10 @@ game.playAudio(path); } } - else if(lib.character[player.name]&&lib.character[player.name][4].contains('die_audio')){ - game.playAudio('die',player.name); + else if(lib.character[player.name]&&lib.character[player.name][4].some(tag=>tag.startsWith('die_audio'))){ + var tag=lib.character[player.name][4].find(tag=>tag.startsWith('die_audio')); + var list=tag.split(':').slice(1); + game.playAudio('die',list.length?list[0]:player.name); } else{ game.playAudio('die',player.name,function(){ @@ -20348,7 +20676,12 @@ //type为要判断的区域 若为空 则判断玩家是否有任意一个被废除的区域 hasDisabledSlot:function(type){ var player=this; - if(type=='horse') return player.hasDisabledSlot(3)&&player.hasDisabledSlot(4); + if(type=='horse'||type=='equip3_4'){ + return player.hasDisabledSlot(3)&&(get.is.mountCombined()||player.hasDisabledSlot(4)); + } + else if(get.is.mountCombined()&&type=='equip4'){ + return false; + } return player.countDisabledSlot(type)>0; }, //判断一名角色的某个区域被废除的数量 @@ -20365,6 +20698,9 @@ } else{ if(typeof type=='number') type=('equip'+type); + if(get.is.mountCombined()&&type=='equip4'){ + return 0; + } var num=map[type]; if(typeof num=='number'&&num>0) return num; return 0; @@ -20373,7 +20709,12 @@ //判断一名角色是否有某个装备栏空着 hasEmptySlot:function(type){ var player=this; - if(type=='horse') return player.hasEmptySlot(3)&&player.hasEmptySlot(4); + if(type=='horse'||type=='equip3_4'){ + return player.hasEmptySlot(3)&&(get.is.mountCombined()||player.hasEmptySlot(4)); + } + else if(get.is.mountCombined()&&type=='equip4'){ + return false; + } return player.countEmptySlot(type)>0; }, //判断一名角色的某个装备栏空位的数量 @@ -20381,6 +20722,9 @@ if(!type) return 0; var player=this; if(typeof type=='number') type=('equip'+type); + else if(type=='equip3_4'){ + type='equip3'; + } 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); @@ -20397,6 +20741,12 @@ if(!type) return 0; var player=this; if(typeof type=='number') type=('equip'+type); + else if(type=='equip3_4'){ + type='equip3'; + } + else if(get.is.mountCombined()&&type=='equip4'){ + return 0; + } 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); @@ -20407,7 +20757,15 @@ //type为要判断的区域 若为空 则判断玩家是否有任意一个未被废除的区域 hasEnabledSlot:function(type){ var player=this; - if(type=='horse') return player.hasEnabledSlot(3)&&player.hasEnabledSlot(4); + if(type=='horse'||type=='equip3_4'){ + return player.hasEnabledSlot(3)&&(get.is.mountCombined()||player.hasEnabledSlot(4)); + } + else if(type=='equip3_4'){ + type='equip3'; + } + else if(get.is.mountCombined()&&type=='equip4'){ + return false; + } return player.countEnabledSlot(type)>0; }, //判断一名角色的某个区域未被废除的数量 @@ -20424,6 +20782,9 @@ } else{ if(typeof type=='number') type=('equip'+type); + if(get.is.mountCombined()&&type=='equip4'){ + return 0; + } var slots=1; var num=map[type]; if(typeof num=='number'&&num>0) slots+=num; @@ -20437,7 +20798,13 @@ var type=(typeof subtype); switch(type){ case 'string': - if(subtype.startsWith('equip')&&parseInt(subtype.slice(5))>0){ + if(subtype=='equip3_4'){ + const cards=[]; + cards.addArray(this.getEquips(3)); + cards.addArray(this.getEquips(4)); + return cards; + } + else if(subtype.startsWith('equip')&&parseInt(subtype.slice(5))>0){ break; } else if(lib.card[subtype]){ @@ -20575,8 +20942,9 @@ }, //同步装备区废除牌显示状态 $syncDisable:function(map){ - var player=this; - var suits={equip3:'+1马栏',equip4:'-1马栏',equip6:'特殊栏'}; + const player=this; + const suits={equip3:'+1马栏',equip4:'-1马栏',equip6:'特殊栏'}; + if(get.is.mountCombined()) suits.equip3='坐骑栏'; if(!map){ map=(player.disabledSlots||{}); } @@ -20585,29 +20953,29 @@ 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){ + const map2=get.copy(map); + const cards=Array.from(player.node.equips.childNodes); + for(const card of cards){ if(card.name.startsWith('feichu_')){ - var index=card.name.slice(7); + const index=card.name.slice(7); if(!map2[index]) map2[index]=0; map2[index]--; } } - for(var index in map2){ + for(const index in map2){ if(!index.startsWith('equip')||!(parseInt(index.slice(5))>0)) continue; - var num=map2[index]; + const num=map2[index]; if(num>0){ - for(var i=0;i=equipNum){ player.node.equips.insertBefore(card,player.node.equips.childNodes[j]); equipped=true; @@ -20623,8 +20991,8 @@ } } else if(num<0){ - for(var i=0;i>num;i--){ - var card=cards.find(card=>card.name=='feichu_'+index); + for(let i=0;i>num;i--){ + const card=cards.find(card=>card.name=='feichu_'+index); if(card){ player.node.equips.removeChild(card); cards.remove(card); @@ -20635,10 +21003,19 @@ }, //以下函数涉及到本次更新内容而进行修改 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); + const ranges=get.subtypes(name),rangex=[],player=this,combined=get.is.mountCombined(); + if(combined){ + ranges.forEach(type=>{ + if(type=='equip3'||type=='equip4') rangex.add('equip3_4'); + else rangex.add(type) + }) + } + else{ + rangex.push(...new Set(ranges)); + } + for(let range of rangex){ + let num=this.countEquipableSlot(range); + let num2=get.numOf(rangex,range); if(!replace) num-=this.getEquips(range).filter(card=>lib.filter.canBeReplaced(card,player)).length; if(num=this.maxHp) this.hp=this.maxHp; - var hp=this.node.hp; - hp.style.transition='none'; game.broadcast(function(player,hp,maxHp,hujia){ player.hp=hp; player.maxHp=maxHp; player.hujia=hujia; - player.update(); + 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'); @@ -22853,21 +23234,23 @@ var next; if(evt&&evt.parent&&evt.parent.next){ evt=evt.parent; - next=game.createEvent('phase',null,evt); + next=game.createEvent('phase',false,evt); } else if(_status.event.parent&&_status.event.parent.next){ evt=_status.event.parent; - next=game.createEvent('phase',null,evt); + next=game.createEvent('phase',false,evt); } else{ evt=null; - next=game.createEvent('phase'); + 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; @@ -22889,7 +23272,7 @@ return next; }, phase:function(skill){ - var next=game.createEvent('phase'); + var next=game.createEvent('phase',false); next.player=this; next.setContent('phase'); if(!_status.roundStart){ @@ -22898,6 +23281,8 @@ if(skill){ next.skill=skill; } + next.forceDie=true; + next.includeOut=true; return next; }, phaseZhunbei:function(){ @@ -23252,7 +23637,7 @@ else if(get.itemtype(arguments[i])=='select'||typeof arguments[i]=='number') select=arguments[i]; } for(var i=0;i{ + if(key===skillkey) return false; + if(Array.isArray(player.additionalSkills[key])) return player.additionalSkills[key].includes(skill); + return player.additionalSkills[key]==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); + if(!hasAnotherSKill(skill,target)) this.removeSkill(target); } } else{ delete this.additionalSkills[skill]; if(typeof additionalSkills=='string'){ - if(!this.skills.contains(additionalSkills)&&!this.tempSkills[additionalSkills]) this.removeSkill(additionalSkills); + if(!hasAnotherSKill(skill,additionalSkills)) this.removeSkill(additionalSkills); } else if(Array.isArray(additionalSkills)){ - for(var i=0;i!hasAnotherSKill(skill,target)) + this.removeSkill(skillsToRemove); } } } @@ -26601,7 +26995,7 @@ this.addSkill(skill,checkConflict,true,true); if(!expire){ - expire=['phaseAfter','phaseBefore']; + expire=['phaseAfter','phaseBeforeStart']; } this.tempSkills[skill]=expire; @@ -26747,6 +27141,7 @@ }, 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)=>{ @@ -29210,7 +29605,7 @@ this.classList.remove('gold'); this.classList.remove('unique'); this.style.background=''; - var subtype=get.subtype(this); + var subtype=get.subtype(this,false); if(subtype){ this.classList.remove(subtype); } @@ -29463,7 +29858,7 @@ } if(typeof info.init=='function') info.init(); this.node.range.innerHTML=''; - switch(get.subtype(this)){ + switch(get.subtype(this,false)){ case 'equip1': var added=false; if(lib.card[this.name]&&lib.card[this.name].distance){ @@ -30812,7 +31207,7 @@ } var fullskills=game.expandSkills(player.getSkills(false).concat(lib.skill.global)); var info=get.info(skill); - if((info.noHidden||get.mode()!='guozhan')&&!fullskills.contains(skill)){ + if(((info&&info.noHidden)||get.mode()!='guozhan')&&!fullskills.contains(skill)){ return false; } if(!info.trigger) return false; @@ -31272,7 +31667,7 @@ if(type=='trick') return 0; if(type=='delay') return 1; if(type=='equip'){ - var type2=get.subtype(name); + var type2=get.subtype(name,false); if(type2&&type2.slice) return 1+parseInt(type2.slice(5)||7); return 8.5 } @@ -31361,12 +31756,14 @@ 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]; + const keys=Object.keys(storage).sort(),combined=get.is.mountCombined(); + let str=''; + for(const key of keys){ + const num=storage[key]; if(typeof num=='number'&&num>0){ - str+='
  • '+get.translation(key)+'栏:'+num+'个
    ' + let trans=get.translation(key); + if(combined&&key=='equip3') trans='坐骑栏'; + str+='
  • '+trans+'栏:'+num+'个
    ' } } if(str.length) return str.slice(0,str.length-4); @@ -32209,6 +32606,7 @@ silent:true, charlotte:true, priority:-100, + lastDo:true, content:function(){ player.removeSkill('counttrigger'); delete player.storage.counttrigger; @@ -32216,9 +32614,10 @@ group:'counttrigger_2', subSkill:{ 2:{ - trigger:{global:'phaseBefore'}, + trigger:{global:['phaseBeforeStart','roundStart']}, silent:true, charlotte:true, + firstDo:true, priority:100, content:function(){ player.removeSkill('counttrigger'); @@ -32240,7 +32639,10 @@ trigger.cancel(); }, }, - _turnover:{ + /** + * @deprecated + */ + /*_turnover:{ trigger:{player:'phaseBefore'}, forced:true, forceOut:true, @@ -32311,7 +32713,7 @@ game.getGlobalHistory().isRound=true; } }, - }, + },*/ _usecard:{ trigger:{global:'useCardAfter'}, forced:true, @@ -33677,6 +34079,45 @@ ['stab',10], ['poison',50] ]), + natureAudio:{ + damage:{ + 'fire':'default',//默认,即语音放置在audio/effect下,以damage_fire.mp3 damage_fire2.mp3命名。 + 'thunder':'default', + 'ice':'default', + 'stab':'normal',//正常,即与普通伤害音效相同。 + /* + 'example':{ + 1:'../extension/XXX/damage_example.mp3',//1点伤害。 + 2:'../extension/XXX/damage_example2.mp3',//2点及以上伤害 + } + */ + }, + hujia_damage:{ + 'fire':'default',//默认,即语音放置在audio/effect下,以hujia_damage_fire.mp3 hujia_damage_fire2.mp3命名。 + 'thunder':'default', + 'ice':'normal',//正常,即与普通伤害音效相同。 + /* + 'example':{ + 1:'../extension/XXX/damage_example.mp3',//1点伤害。 + 2:'../extension/XXX/damage_example2.mp3',//2点及以上伤害 + } + */ + }, + sha:{ + 'fire':'default',//默认,即语音放置在audio/card/male与audio/card/female下,命名为sha_fire.mp3 + 'thunder':'default', + 'ice':'default', + 'stab':'default', + 'poison':'normal',//正常,即播放“杀”的音效。 + 'kami':'normal', + /* + 'example':{ + 'male':'../extension/XXXX/sha_example_male.mp3', + 'female':'../extension/XXXX/sha_example_female.mp3' + } + */ + } + }, linked:['fire','thunder','kami','ice'], natureBg:new Map([ ['stab','image/card/cisha.png'] @@ -34999,83 +35440,86 @@ }); return audio; }, - trySkillAudio:function(skill,player,directaudio){ - game.broadcast(game.trySkillAudio,skill,player,directaudio); + trySkillAudio:function(skill,player,directaudio,nobroadcast/*,index*/){ + if(!nobroadcast) game.broadcast(game.trySkillAudio,skill,player,directaudio,nobroadcast/*,index*/); var info=get.info(skill); if(!info) return; if(!lib.config.background_speak) return; + if(info.direct&&!directaudio) return; + if(lib.skill.global.includes(skill)&&!lib.skill[skill].forceaudio) 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; + + function getAudioList(skill,player,history,fixedNum){ + let info=lib.skill[skill]; + if(!info) return []; + if(!history) history=[]; + if(history.includes(skill)){//直接跳出 + console.trace(`${skill} in ${history} forms a deadlock`); + if(info.audio!==false) return [[skill]];//标记为playSkillAudio + return []; + } + history.push(skill); + + let audioInfo=info.audio; + if(info.audioname2&&player){ + if(info.audioname2[player.name]) audioInfo=info.audioname2[player.name]; + else if(info.audioname2[player.name1]) audioInfo=info.audioname2[player.name1]; + else if(info.audioname2[player.name2]) audioInfo=info.audioname2[player.name2]; + } + if(typeof audioInfo=='function') audioInfo=audioInfo(player); + + let audioname=''; + if(Array.isArray(info.audioname)&&player){ + if(info.audioname.includes(player.name)) audioname=`_${player.name}`; + else if(info.audioname.includes(player.name1)) audioname=`_${player.name1}`; + else if(info.audioname.includes(player.name2)) audioname=`_${player.name2}`; + } + + let audioList=parseAudio(skill,audioInfo,audioname,player,history,fixedNum); + if(fixedNum&&fixedNumtotal.addArray(parseAudio(skill,i,audioname,player,history,fixedNum)),[]); } - 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'}`); + + if(!['string','number','boolean'].includes(typeof audioInfo)) return []; + if(audioInfo===false) return []; + if(typeof audioInfo=='string'&&lib.skill[audioInfo]) return getAudioList(audioInfo,player,history,fixedNum); + audioInfo=String(audioInfo); + + let audioList=[]; + let list=audioInfo.match(/(?:(.*):|^)(true|\d*)(?::(.*)|$)/); + if(list&&list[2]){ + list=list.slice(1);//形如[路径,number/true,格式]的形式 + if(list[1]=='true') audioList.add(`${list[0]||'skill'}/${skill}${audioname}.${list[2]||'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'}`); + list[1]=parseInt(list[1]); + for(let i=1;i<=list[1];i++){ + audioList.add(`${list[0]||'skill'}/${skill}${audioname}${i}.${list[2]||'mp3'}`); + } } } + else audioList.add(`${/(?:^db:|^ext:|\/)/.test(audioInfo)?'':'skill/'}${audioInfo}`); + return audioList; } - else if(typeof audioInfo=='number'){ - if(fixedNum) audioInfo=Math.min(audioInfo, fixedNum); - game.playAudio('skill',`${audioName}${Math.floor(audioInfo*Math.random())+1}`); - } - else if(audioInfo) game.playAudio('skill',audioName); - else if(info.audio!==false) game.playSkillAudio(audioName); + + let list=getAudioList(skill,player); + // console.log(skill,lib.skill[skill]&&lib.skill[skill].audio,list); + if(!list.length) return; + // if(index) index=index%list.length||list.length; + // let audio=list[index?index-1:Math.floor(Math.random()*list.length)]; + let audio=list[Math.floor(Math.random()*list.length)]; + if(Array.isArray(audio)) return game.playSkillAudio(audio[0]); + return game.playAudio(audio); }, playSkillAudio:function(name,index){ if(_status.video&&arguments[1]!='video') return; @@ -35128,6 +35572,36 @@ }; ui.window.appendChild(audio); }, + playCardAudio:function(card,sex){ + if(typeof card === 'string'){ + card = {name:card}; + } + if(get.itemtype(sex) === 'player'){ + sex = (sex.sex == 'female'?'female':'male'); + }else if(typeof sex == 'string'){ + sex = (sex == 'female'?'female':'male'); + } + if(!lib.config.background_audio||get.type(card)=='equip'&&!lib.config.equip_audio) return; + var nature=get.natureList(card)[0]; + if(lib.natureAudio[card.name]){ + let useAudio = lib.natureAudio[card.name][nature]; + if(useAudio === 'default'){ + game.playAudio('card',sex,`${card.name}_${nature}`); + return; + }else if(useAudio && useAudio[sex]){ + game.playAudio(useAudio[sex]); + 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); + }, playBackgroundMusic:()=>{ if(lib.config.background_music=='music_off'){ ui.backgroundMusic.src=''; @@ -36962,7 +37436,7 @@ delete _status.waitingToReload; }, exit:function(){ - var ua=navigator.userAgent.toLowerCase(); + var ua=userAgent; var ios=ua.includes('iphone')||ua.includes('ipad')||ua.includes('macintosh'); //electron if(typeof window.process=='object'&&typeof window.require=='function'){ @@ -37173,14 +37647,16 @@ else if(e.keyCode==27){ clickCancel(); } + e.stopPropagation(); } - input.onkeyup=function(){ + input.onkeyup=function(e){ if(input.value){ confirmNode.classList.remove('disabled'); } else{ confirmNode.classList.remove('disabled'); } + e.stopPropagation(); } input.focus(); } @@ -37782,7 +38258,7 @@ } } }, - addSkill:function(name,info,translate,description,appendInfo){ + addSkill:function(name,info,translate,description,appendInfo,abInfo){ if(lib.skill[name]){ return false; } @@ -37793,6 +38269,7 @@ lib.translate[name]=translate; lib.translate[name+'_info']=description; lib.translate[name+'_append']=appendInfo; + lib.translate[`${name}_ab`]=abInfo; return true; }, addMode:function(name,info,info2){ @@ -38718,7 +39195,9 @@ } else if(event._triggered==1){ if(event.type=='card') event.trigger('useCardToBegin'); - if(event.name=='phase'&&!event._begun){ + 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; @@ -38728,7 +39207,7 @@ else{ event.trigger(event.name+'Begin'); event._triggered++; - } + }*/ } else{ if(player&&player.classList.contains('dead')&&!event.forceDie&&event.name!='phaseLoop'){ @@ -38754,9 +39233,36 @@ 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); + if(event.content instanceof GeneratorFunction){ + if(!event.debugging){ + if(event.generatorContent) event.generatorContent.return(); + event.generatorContent=event.content(event,step,source,player,target,targets, + card,cards,skill,forced,num,trigger,result, + _status,lib,game,ui,get,ai); + }else{ + delete event.debugging; + } + var next=event.generatorContent.next(); + if(typeof next.value=='function'&&next.value.toString()=='code=>eval(code)'){ + //TODO:触发debugger + var inputCallback=inputResult=>{ + if(inputResult===false){ + event.debugging=true; + game.resume2(); + }else{ + alert(get.stringify(next.value(inputResult))); + game.prompt('','debugger调试',inputCallback); + } + } + game.prompt('','debugger调试',inputCallback); + return game.pause2(); + } + if(event.finished) event.generatorContent.return(); + }else{ + 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); @@ -38765,9 +39271,36 @@ } } else{ - event.content(event,step,source,player,target,targets, - card,cards,skill,forced,num,trigger,result, - _status,lib,game,ui,get,ai); + if(event.content instanceof GeneratorFunction){ + if(!event.debugging){ + if(event.generatorContent) event.generatorContent.return(); + event.generatorContent=event.content(event,step,source,player,target,targets, + card,cards,skill,forced,num,trigger,result, + _status,lib,game,ui,get,ai); + }else{ + delete event.debugging; + } + var next=event.generatorContent.next(); + if(typeof next.value=='function'&&next.value.toString()=='code=>eval(code)'){ + //TODO:触发debugger + var inputCallback=inputResult=>{ + if(inputResult===false){ + event.debugging=true; + game.resume2(); + }else{ + alert(get.stringify(next.value(inputResult))); + game.prompt('','debugger调试',inputCallback); + } + } + game.prompt('','debugger调试',inputCallback); + return game.pause2(); + } + if(event.finished) event.generatorContent.return(); + }else{ + event.content(event,step,source,player,target,targets, + card,cards,skill,forced,num,trigger,result, + _status,lib,game,ui,get,ai); + } } } event.clearStepCache(); @@ -40471,7 +41004,17 @@ 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); + if(typeof skills.getModableSkills == 'function'){ + skills=skills.getModableSkills(_status.event.useCache === true); + }else if(typeof skills.getSkills == 'function'){ + skills=skills.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)); + } const arg=argumentArray.slice(0,-2); skills.forEach(value=>{ var mod = get.info(value).mod[name]; @@ -54773,6 +55316,16 @@ 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); @@ -55034,6 +55587,16 @@ 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); @@ -56035,7 +56598,7 @@ //Get the card name length //获取此牌的字数 cardNameLength:(card,player)=>{ - const actualCardName=lib.actualCardName,name=get.translation(get.name(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 @@ -56064,7 +56627,7 @@ return info&&info.defaultYingbianEffect||null; }, //优先度判断 - priority:function(skill){ + priority:skill=>{ const info=get.info(skill); if(!info) return 0; if(info.hasOwnProperty('_priority')) return info._priority; @@ -56084,13 +56647,19 @@ //新装备栏相关 //获取一张装备牌实际占用的装备栏(君曹操六龙) //用法同get.subtype,返回数组 - subtypes:function(obj,player){ + subtypes:(obj,player)=>{ if(typeof obj=='string') obj={name:obj}; if(typeof obj!='object') return; var name=get.name(obj,player); if(!lib.card[name]) return []; - if(lib.card[name].subtypes) return get.copy(lib.card[name].subtypes); - else if(lib.card[name].subtype) return [lib.card[name].subtype]; + if(lib.card[name].subtypes){ + const subtypes=get.copy(lib.card[name].subtypes); + return subtypes; + } + else if(lib.card[name].subtype){ + const subtype=lib.card[name].subtype; + return [subtype]; + } return []; }, //装备栏 END @@ -56104,7 +56673,7 @@ } return pinyinUtilx.getPinyin(chinese,null,withTone,true); }, - yunmu:function(str){ + yunmu:str=>{ //部分整体认读音节特化处理 const util=window.pinyinUtilx; if(util&&lib.pinyins._metadata.zhengtirendu.contains(util.removeTone(str))){ @@ -56134,7 +56703,7 @@ return str; }, //用于将参数转换为字符串,作为缓存的key。 - paramToCacheKey:function(){ + paramToCacheKey(){ var str = ""; for(var arg of arguments){ if(arg === null || arg === undefined){ @@ -56154,7 +56723,7 @@ } return str; }, - yunjiao:function(str){ + yunjiao:str=>{ const util=window.pinyinUtilx; if(util) str=util.removeTone(str) if(lib.pinyins._metadata.zhengtirendu.contains(str)){ @@ -56174,7 +56743,7 @@ } return null; }, - skillCategoriesOf:function(skill,player){ + skillCategoriesOf:(skill,player)=>{ var list=[],info=get.info(skill); if(!info) return list; if(get.is.locked(skill,player)) list.add('锁定技'); @@ -56197,54 +56766,44 @@ if(info.categories) list.addArray(info.categories(skill,player)); return list; }, - numOf:function(obj,item){ - var num=0; - for(var i=0;iobj.filter(element=>element==item).length, + connectNickname:()=>typeof lib.config.connect_nickname=='string'?(lib.config.connect_nickname.slice(0,12)):"无名玩家", + zhinangs:filter=>{ var list=(_status.connectMode?lib.configOL:lib.config).zhinang_tricks; if(!list||!list.filter||!list.length) return get.inpile('trick','trick').randomGets(3); if(filter===false) return list.slice(0); - list=list.filter(function(i){ - return lib.inpile.contains(i); - }); + list=list.filter(card=>lib.inpile.includes(card)); if(list.length) return list; return get.inpile('trick','trick').randomGets(3); }, - sourceCharacter:function(str){ + sourceCharacter:str=>{ if(str){ for(var i in lib.characterReplace){ - if(lib.characterReplace[i].contains(str)) return i; + if(lib.characterReplace[i].includes(str)) return i; } } return str; }, - isLuckyStar:function(player){ + isLuckyStar:player=>{ if(player&&player.hasSkillTag('luckyStar')) return true; if(_status.connectMode) return false; return (!player||player==game.me||player.isUnderControl())&&lib.config.lucky_star==true; }, - infoHp:function(hp){ + infoHp:hp=>{ if(typeof hp=='number') return hp; else if(typeof hp=='string'&&hp.includes('/')){ return parseInt(hp.split('/')[0]); } return 0; }, - infoMaxHp:function(hp){ + infoMaxHp:hp=>{ if(typeof hp=='number') return hp; else if(typeof hp=='string'&&hp.includes('/')){ return parseInt(hp.split('/')[1]); } return 0; }, - infoHujia:function(hp){ + infoHujia:hp=>{ if(typeof hp=='string'&&hp.includes('/')){ var splited=hp.split('/'); if(splited.length>2) return parseInt(splited[2]); @@ -56252,12 +56811,21 @@ return 0; }, is:{ + /** + * 判断坐骑栏是否被合并 + */ + mountCombined:function(){ + if(typeof _status.mountCombined!='boolean'){ + _status.mountCombined=lib.config.mount_combine; + } + return _status.mountCombined; + }, /** * 判断传入的参数的属性是否相同(参数可以为卡牌、卡牌信息、属性等) * @param ...infos 要判断的属性列表 * @param every {boolean} 是否判断每一个传入的属性是否完全相同而不是存在部分相同 */ - sameNature:function(){ + sameNature(){ let processedArguments=[],every=false; Array.from(arguments).forEach(argument=>{ if(typeof argument=='boolean') every=argument; @@ -56288,7 +56856,7 @@ * @param ...infos 要判断的属性列表 * @param every {boolean} 是否判断每一个传入的属性是否完全不同而不是存在部分不同 */ - differentNature:function(){ + differentNature(){ let processedArguments=[],every=false; Array.from(arguments).forEach(argument=>{ if(typeof argument=='boolean') every=argument; @@ -56327,7 +56895,7 @@ //是否是实体牌 ordinaryCard:card=>card.isCard&&("cards" in card)&&Array.isArray(card.cards)&&card.cards.length==1, //押韵判断 - yayun:function(str1,str2){ + yayun:(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; @@ -56335,7 +56903,7 @@ if(pron1==pron2) return true; return get.yunjiao(pron1)==get.yunjiao(pron2); }, - blocked:function(skill,player){ + blocked:(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; @@ -56375,7 +56943,7 @@ return false; }, yingbian:card=>get.is.yingbianConditional(card)||get.is.yingbianEffective(card), - emoji:function(substring){ + emoji:substring=>{ if(substring){ var reg=new RegExp("[~#^$@%&!?%*]",'g'); if(substring.match(reg)){ @@ -56421,28 +56989,11 @@ } 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;iget.is.emoji(str)||window.bannedKeyWords.some(item=>str.includes(item)), + converted:event=>!(event.card&&event.card.isCard), + safari:()=>userAgent.indexOf('safari'!=-1)&&userAgent.indexOf('chrome')==-1, + freePosition:cards=>!cards.some(card=>!card.hasPosition||card.hasPosition()), + nomenu:(name,item)=>{ var menus=['system','menu']; var configs={ show_round_menu:lib.config.show_round_menu, @@ -56476,34 +57027,29 @@ } return true; }, - altered:function(skill){ + altered:()=>false, + /* + skill=>{ return false; // if(_status.connectMode) return true; // return !lib.config.vintageSkills.contains(skill); }, - node:function(obj){ + */ + node: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){ + div:obj=>Object.prototype.toString.call(obj) === '[object HTMLDivElement]', + map:obj=>Object.prototype.toString.call(obj) === '[object Map]', + set:obj=>Object.prototype.toString.call(obj) === '[object Set]', + object:obj=>Object.prototype.toString.call(obj) === '[object Object]', + singleSelect:func=>{ if(typeof func=='function') return false; var select=get.select(func); return select[0]==1&&select[1]==1; }, - jun:function(name){ + jun:name=>{ if(get.mode()=='guozhan'){ if(name&&typeof name=='object'){ if(name.isUnseen&&name.isUnseen(0)) return false; @@ -56515,33 +57061,17 @@ } 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(){ + versus:()=>!_status.connectMode&&get.mode()=='versus'&&_status.mode=='three', + changban:()=>get.mode()=='single'&&_status.mode=='changban', + single:()=>get.mode()=='single'&&_status.mode=='normal', + mobileMe:player=>(game.layout=='mobile'||game.layout=='long')&&!game.chess&&player.dataset.position==0, + newLayout:()=>game.layout!='default', + phoneLayout:()=>{ 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){ + singleHandcard:()=>game.singleHandcard||game.layout=='mobile'||game.layout=='long'||game.layout=='long2'||game.layout=='nova', + linked2:player=>{ if(game.chess) return true; if(lib.config.link_style2!='rotate') return true; // if(game.chess) return false; @@ -56551,14 +57081,9 @@ } 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){ + empty:obj=>Object.keys(obj).length==0, + pos:str=>str=='h'||str=='e'||str=='j'||str=='he'||str=='hj'||str=='ej'||str=='hej', + locked:(skill,player)=>{ var info=lib.skill[skill]; if(typeof info.locked=='function') return info.locked(skill,player); if(info.locked==false) return false; @@ -56568,7 +57093,7 @@ return false; }, }, - bottomCards:function(num,putBack){ + bottomCards:(num,putBack)=>{ if(_status.waitingForCards){ ui.create.cards.apply(ui.create,_status.waitingForCards); delete _status.waitingForCards; @@ -56599,21 +57124,13 @@ if(card) return list[0]; return list; }, - discarded:function(){ - var list=_status.discarded.slice(0); - for(var i=0;i_status.discarded.filter(item=>item.parentNode==ui.discardPile), + cardOffset:()=>{ var x=ui.arena.getBoundingClientRect(); var y=ui.window.getBoundingClientRect(); return -y.width/2+(x.left+x.width/2); }, - colorspan:function(str){ + colorspan:str=>{ if(str[0]=='#'){ var color; switch(str[1]){ @@ -56627,7 +57144,7 @@ } return str; }, - evtprompt:function(next,str){ + evtprompt:(next,str)=>{ if(next.prompt){ next.set('prompt2',str); } @@ -56642,7 +57159,7 @@ } } }, - autoViewAs:function(card,cards){ + autoViewAs:(card,cards)=>{ let _card; if(get.itemtype(card)=='card'){ _card={ @@ -56734,7 +57251,7 @@ return card; } }, - max:function(list,func,type){ + max:(list,func,type)=>{ list=list.slice(0); if(typeof func=='string'){ var key=func; @@ -56761,7 +57278,7 @@ return func(list[0]); } }, - min:function(list,func,type){ + min:(list,func,type)=>{ list=list.slice(0); if(typeof func=='string'){ var key=func; @@ -56788,7 +57305,7 @@ return func(list[0]); } }, - character:function(name,num){ + character:(name,num)=>{ let info=lib.character[name]; if(!info){ const pack=Object.keys(lib.characterPack).find(pack=>lib.characterPack[pack].hasOwnProperty(name)); @@ -56802,7 +57319,7 @@ } return null; }, - characterIntro:function(name){ + characterIntro:name=>{ if(lib.characterIntro[name]) return lib.characterIntro[name]; var tags=get.character(name,4); if(tags){ @@ -56828,7 +57345,7 @@ } return raw?'':info[1]||''; }, - groupnature:function(group,method){ + groupnature:(group,method)=>{ var nature=lib.groupnature[group]; if(!nature) return ''; if(method=='raw'){ @@ -56836,12 +57353,12 @@ } return nature+'mm'; }, - sgn:function(num){ + sgn:num=>{ if(num>0) return 1; if(num<0) return -1; return 0; }, - rand:function(num,num2){ + rand:(num,num2)=>{ if(typeof num2=='number'){ return num+Math.floor(Math.random()*(num2-num+1)); } @@ -56849,23 +57366,9 @@ 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){ + sort:(arr,method,arg)=>method=="seat"?arr.sortBySeat(arg):void 0, + sortSeat:(arr,target)=>arr.sortBySeat(target), + zip:callback=>{ if(!window.JSZip){ lib.init.js(lib.assetURL+'game','jszip',function(){ callback(new JSZip()); @@ -56875,7 +57378,7 @@ callback(new JSZip()); } }, - delayx:function(num,max){ + delayx:(num,max)=>{ if(typeof num!='number') num=1; if(typeof max!='number') max=Infinity; switch(lib.config.game_speed){ @@ -56887,7 +57390,7 @@ default:return Math.min(max,num); } }, - prompt:function(skill,target,player){ + prompt:(skill,target,player)=>{ player=player||_status.event.player; if(target){ var str=get.translation(target); @@ -56900,12 +57403,12 @@ return '是否发动【'+get.skillTranslation(skill,player)+'】?'; } }, - prompt2:function(skill,target,player){ + prompt2(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){ + url:master=>{ var url=lib.config.updateURL||lib.updateURL; if(url[url.length-1]!='/'){ url+='/'; @@ -56917,14 +57420,11 @@ return url+'v'+lib.version+'/'; } }, - round:function(num,f){ - var round=1; - for(var i=0;i{ + var round=10**f; return Math.round(num*round)/round; }, - playerNumber:function(){ + playerNumber:()=>{ var num; if(_status.brawl&&_status.brawl.playerNumber){ num=_status.brawl.playerNumber @@ -56934,7 +57434,7 @@ } return parseInt(num)||2; }, - benchmark:function(func1,func2,iteration,arg){ + benchmark:(func1,func2,iteration,arg)=>{ var tic,toc; var key1,key2; if(!arg) arg=[]; @@ -56976,7 +57476,7 @@ toc=get.utc(); console.log('time2: '+(toc-tic)); }, - stringify:function(obj,level){ + stringify:(obj,level)=>{ level=level||0; var indent=''; var str; @@ -57033,7 +57533,7 @@ return str; } }, - copy:function(obj){ + copy:obj=>{ if(get.objtype(obj)=='object'){ var copy={}; for(var i in obj){ @@ -57052,7 +57552,7 @@ return obj; } }, - inpilefull:function(type){ + inpilefull:(type)=>{ var list=[]; for(var i in lib.cardPile){ for(var j=0;j{ var list=[]; if(filter=='trick'){ for(var i=0;iget.inpile(type,'trick'), + typeCard:(type,filter)=>{ var list=[]; for(var i in lib.card){ if(lib.card[i].mode&&lib.card[i].mode.contains(get.mode())==false) continue; @@ -57119,7 +57617,7 @@ } return list; }, - libCard:function(filter){ + libCard:filter=>{ var list=[]; for(var i in lib.card){ if(lib.card[i].mode&&lib.card[i].mode.contains(get.mode())==false) continue; @@ -57133,7 +57631,7 @@ } return list; }, - ip:function(){ + ip:()=>{ if(!require) return ''; var interfaces = require('os').networkInterfaces(); for(var devName in interfaces){ @@ -57146,7 +57644,7 @@ } } }, - modetrans:function(config,server){ + modetrans:(config,server)=>{ if(config.mode=='doudizhu'){ switch(config.doudizhu_mode){ case 'kaihei':return '开黑斗地主'; @@ -57194,7 +57692,7 @@ } } }, - charactersOL:function(func){ + charactersOL:func=>{ var list=[]; var libCharacter={}; for(var i=0;i{ var len=str.length-5; if(str.lastIndexOf(':8080')==len){ str=str.slice(0,len); @@ -57219,15 +57717,8 @@ return str; }, mode:()=>lib[_status.connectMode?'configOL':'config'].mode, - idDialog:function(id){ - for(var i=0;iui.dialogs.find(dialog=>dialog.videoId==id)||null, + arenaState:()=>{ var state={ number:ui.arena.dataset.number, players:{}, @@ -57245,7 +57736,7 @@ } return state; }, - skillState:function(player){ + skillState:player=>{ var skills={ global:lib.skill.global }; @@ -57272,10 +57763,8 @@ } return skills; }, - id:function(){ - return (Math.floor(1000000+9000000*Math.random())).toString()+(10+lib.status.globalId++); - }, - zhu:function(player,skill,group){ + id:()=>(Math.floor(1000000+9000000*Math.random())).toString()+(10+lib.status.globalId++), + zhu:(player,skill,group)=>{ if(typeof player=='string'){ skill=player; player=null; @@ -57320,12 +57809,12 @@ } return null; }, - config:function(item,mode){ + config:(item,mode)=>{ mode=mode||lib.config.mode; if(!lib.config.mode_config[mode]) return; return lib.config.mode_config[mode][item]; }, - coinCoeff:function(list){ + coinCoeff:list=>{ var num=0; for(var i=0;i{ if(typeof name=='object'&&name.name){ name=name.name; } @@ -57390,7 +57879,7 @@ } return num?Math.round(9*(num-1)/8+1):'x'; }, - skillRank:function(skill,type,grouped){ + skillRank:(skill,type,grouped)=>{ var info=lib.skill[skill]; var player=_status.event.skillRankPlayer||_status.event.player; if(!info) return 0; @@ -57484,48 +57973,26 @@ } return num; }, - targetsInfo:function(targets){ + targetsInfo:targets=>{ var info=[]; for(var i=0;iArray.from(infos||[]).map(info=>game.playerMap[info]), + cardInfo:card=>[card.suit,card.number,card.name,card.nature], + cardsInfo:cards=>Array.from(cards||[]).map(get.cardInfo), + infoCard:info=>{ var card=ui.create.card(); if(info[0]){ card.init(info); } return card; }, - infoCards:function(info){ - var cards=[]; - for(var i=0;iArray.from(infos||[]).map(get.infoCard), + cardInfoOL:card=>'_noname_card:'+JSON.stringify([card.cardid,card.suit,card.number,card.name,card.nature]), + infoCardOL:info=>{ if(!lib.cardOL) return info; var card; try{ @@ -57553,42 +58020,13 @@ } return card||info; }, - cardsInfoOL:function(cards){ - var info=[]; - for(var i=0;iArray.from(cards||[]).map(get.cardInfoOL), + infoCardsOL:infos=>Array.from(infos||[]).map(get.infoCardOL), + playerInfoOL:player=>'_noname_player:'+player.playerid, + infoPlayerOL:info=>lib.playerOL?(lib.playerOL[info.slice(15)]||info):info, + playersInfoOL:players=>Array.from(players||[]).map(get.playerInfoOL), + infoPlayersOL:infos=>Array.from(infos||[]).map(get.infoPlayerOL), + funcInfoOL:func=>{ if(typeof func=='function'){ if(func._filter_args){ return '_noname_func:'+JSON.stringify(get.stringifiedResult(func._filter_args,3)); @@ -57597,7 +58035,7 @@ } return ''; }, - infoFuncOL:function(info){ + infoFuncOL:info=>{ var func; try{ eval('func=('+info.slice(13)+');'); @@ -57610,7 +58048,7 @@ } return func; }, - eventInfoOL:function(item,level,nomore){ + eventInfoOL:(item,level,nomore)=>{ if(Object.prototype.toString.call(item)=='[object Object]'){ var item2={}; for(var i in item){ @@ -57627,7 +58065,7 @@ return ''; } }, - infoEventOL:function(item){ + infoEventOL:item=>{ var evt; try{ evt=JSON.parse(item.slice(14)); @@ -57641,7 +58079,7 @@ } return evt||item; }, - stringifiedResult:function(item,level,nomore){ + stringifiedResult:(item,level,nomore)=>{ if(!item) return item; if(typeof item=='function'){ return get.funcInfoOL(item); @@ -57691,7 +58129,7 @@ return item; } }, - parsedResult:function(item){ + parsedResult:item=>{ if(!item) return item; if(typeof item=='string'){ if(item.startsWith('_noname_func:')){ @@ -57731,11 +58169,11 @@ return item; } }, - verticalStr:function(str,sp){ + verticalStr:(str,sp)=>{ if(typeof str!='string') return ''; return Array.from(str).filter(value=>value!='`').join(''); }, - numStr:function(num,method){ + numStr:(num,method)=>{ if(num==Infinity){ if(method=='card') return get.selectableCards().length+ui.selected.cards.length; if(method=='target') return get.selectableTargets().length+ui.selected.targets.length; @@ -57743,7 +58181,7 @@ } return num.toString(); }, - rawName:function(str){ + rawName:str=>{ let str2=lib.translate[str]; if(lib.translate[str+'_ab']) str2=lib.translate[str+'_ab']; if(!str2) return ''; @@ -57753,7 +58191,7 @@ return str2; }, //作用修改:只读前缀 不读_ab - rawName2:function(str){ + rawName2:str=>{ let str2=lib.translate[str]; if(!str2) return ''; if(lib.translate[str+'_prefix']&&str2.startsWith(lib.translate[str+'_prefix'])){ @@ -57790,10 +58228,8 @@ if(config=='simple') return `${prefix}` return `${prefix}` }, - slimName:function(str){ - return get.verticalStr(get.slimNameHorizontal(str),true); - }, - time:function(){ + slimName:str=>get.verticalStr(get.slimNameHorizontal(str),true), + time:()=>{ if(lib.status.dateDelaying){ return lib.getUTC(lib.status.dateDelaying)-lib.getUTC(lib.status.date)-lib.status.dateDelayed; } @@ -57801,18 +58237,14 @@ return lib.getUTC(new Date())-lib.getUTC(lib.status.date)-lib.status.dateDelayed; } }, - utc:function(){ - return (new Date()).getTime(); - }, - evtDistance:function(e1,e2){ + utc:()=>(new Date()).getTime(), + evtDistance:(e1,e2)=>{ var dx=(e1.clientX-e2.clientX)/game.documentZoom; var dy=(e1.clientY-e2.clientY)/game.documentZoom; return Math.sqrt(dx*dx+dy*dy); }, - 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){ + xyDistance:(from,to)=>Math.sqrt((from[0]-to[0])*(from[0]-to[0])+(from[1]-to[1])*(from[1]-to[1])), + itemtype:obj=>{ var i,j; if(typeof obj=='string'){ if(obj.length<=5){ @@ -57864,13 +58296,13 @@ if(obj.isMine==lib.element.event.isMine) return 'event'; } }, - equipNum:function(card){ + equipNum:card=>{ if(get.type(card)=='equip'){ return parseInt(get.subtype(card)[5]); } return 0; }, - objtype:function(obj){ + objtype:obj=>{ if(Object.prototype.toString.call(obj) === '[object Array]') return 'array'; if(Object.prototype.toString.call(obj) === '[object Object]') return 'object'; if(Object.prototype.toString.call(obj) === '[object HTMLDivElement]') return 'div'; @@ -57879,7 +58311,7 @@ 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){ + type:(obj,method,player)=>{ if(typeof obj=='string') obj={name:obj}; if(typeof obj!='object') return; var name=get.name(obj,player); @@ -57887,22 +58319,21 @@ 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){ + type2:(card,player)=>get.type(card,'trick',player), + subtype:(obj,player)=>{ if(typeof obj=='string') obj={name:obj}; if(typeof obj!='object') return; - var name=get.name(obj,player); + const name=get.name(obj,player); if(!lib.card[name]) return; - return lib.card[name].subtype; + let subtype=lib.card[name].subtype; + return subtype; }, - equiptype:function(card,player){ + equiptype:(card,player)=>{ var subtype=get.subtype(card,player); if(subtype.startsWith('equip')) return parseInt(subtype[5]); return 0; }, - name:function(card,player){ + name:(card,player)=>{ if(get.itemtype(player)=='player'||(player!==false&&get.position(card)=='h')){ var owner=player||get.owner(card); if(owner){ @@ -57911,7 +58342,7 @@ } return card.name; }, - suit:function(card,player){ + suit:(card,player)=>{ if(!card) return; if(Array.isArray(card)){ if(card.length==1) return get.suit(card[0],player); @@ -57924,14 +58355,14 @@ if(player!==false){ const owner=player||get.owner(card); if(owner){ - return game.checkMod(card,card.suit,'suit',owner); + return game.checkMod(card,owner,game.checkMod(card,card.suit,'suit',owner),'cardsuit',owner); } } if(lib.suits.contains(card.suit)) return card.suit; return 'none'; } }, - color:function(card,player){ + color:(card,player)=>{ if(!card) return; if(Array.isArray(card)){ if(!card.length) return 'none'; @@ -57955,7 +58386,7 @@ return 'none'; } }, - number:function(card,player){ + number:(card,player)=>{ if(!card) return; //狗卡你是真敢出啊 var number=null; @@ -57975,7 +58406,7 @@ return number; }, //返回一张杀的属性。如有多种属性则用 lib.natureSeparator 分割开来。例:火雷【杀】的返回值为 fire|thunder - nature:function(card,player){ + nature:(card,player)=>{ if(typeof card=='string') return card.split(lib.natureSeparator).sort(lib.sort.nature).join(lib.natureSeparator); if(Array.isArray(card)) return card.sort(lib.sort.nature).join(lib.natureSeparator); var nature=card.nature; @@ -57988,7 +58419,7 @@ return nature; }, //返回包含所有属性的数组 - natureList:function(card,player){ + natureList(card,player){ if(!card) return []; if(get.itemtype(card)=='natures') return card.split(lib.natureSeparator); if(get.itemtype(card)=='nature') return [card]; @@ -57996,7 +58427,7 @@ if(typeof natures!='string') return []; return natures.split(lib.natureSeparator); }, - cards:function(num,putBack){ + cards:(num,putBack)=>{ if(_status.waitingForCards){ ui.create.cards.apply(ui.create,_status.waitingForCards); delete _status.waitingForCards; @@ -58027,15 +58458,9 @@ 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){ + judge:card=>card.viewAs?lib.card[card.viewAs].judge:get.info(card).judge, + judge2:card=>card.viewAs?lib.card[card.viewAs].judge2:get.info(card).judge2, + distance:(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; @@ -58100,21 +58525,21 @@ 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{ if(typeof item=='string'){ return lib.skill[item]; } @@ -58124,13 +58549,13 @@ return lib.card[name]; } }, - select:function(select){ + select: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){ + card:original=>{ if(_status.event.skill){ var card=get.info(_status.event.skill).viewAs; if(typeof card=='function') card=card(ui.selected.cards,_status.event.player); @@ -58148,31 +58573,19 @@ } return card; }, - player:function(){ - return _status.event.player; - }, - players:function(sort,dead,out){ + event:key=>key?_status.event[key]:_status.event, + player:()=>_status.event.player, + players:(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(typeof sort=='function') players.sort(sort); + else players.sortBySeat(get.itemtype(sort)=="player"?sort:_status.event.player); } if(dead) players=players.concat(game.dead); - if(!out){ - for(var i=0;i!current.isOut()); return players; }, - position:function(card,ordering){ + position:(card,ordering)=>{ if(get.itemtype(card)=='player') return parseInt(card.dataset.position); if(card.timeout&&card.destiny&&card.destiny.classList){ if(card.destiny.classList.contains('equips')) return 'e'; @@ -58196,7 +58609,7 @@ if(card.parentNode.id=='ordering') return ordering?'o':'d'; return null; }, - skillTranslation:function(str,player){ + skillTranslation:(str,player)=>{ var str2; if(str.startsWith('re')){ str2=str.slice(2); @@ -58220,7 +58633,7 @@ } return get.translation(str); }, - skillInfoTranslation:function(name,player){ + skillInfoTranslation:(name,player)=>{ if(player&&lib.dynamicTranslate[name]) return lib.dynamicTranslate[name](player,name); var str=lib.translate[name+'_info']; if(!str) return ''; @@ -58233,7 +58646,7 @@ // replace(/阵法技/g,'阵法技'). // replace(/主公技/g,'主公技'); }, - translation:function(str,arg){ + translation:(str,arg)=>{ if(str&&typeof str=='object'&&(str.name||str._tempTranslate)){ if(str._tempTranslate) return str._tempTranslate; var str2; @@ -58329,7 +58742,7 @@ } return ''; }, - strNumber:function(num){ + strNumber:num=>{ switch(num){ case 1:return 'A'; case 11:return 'J'; @@ -58338,7 +58751,7 @@ default:return num.toString(); } }, - cnNumber:function(num,two){ + cnNumber:(num,two)=>{ if(num==Infinity) return '∞'; if(isNaN(num)) return ''; if(typeof num!='number') return num; @@ -58364,7 +58777,7 @@ var x=Math.floor(num/10); return get.cnNumber(x,true)+'十'+(num>10*x?get.cnNumber(num-10*x,true):''); }, - selectableButtons:function(sort){ + selectableButtons:sort=>{ if(!_status.event.player) return[]; var buttons=_status.event.dialog.buttons; var selectable=[]; @@ -58379,7 +58792,7 @@ } return selectable; }, - selectableCards:function(sort){ + selectableCards:sort=>{ if(!_status.event.player) return[]; var cards=_status.event.player.getCards('hes'); var selectable=[]; @@ -58394,7 +58807,7 @@ } return selectable; }, - skills:function(){ + skills:()=>{ var skills=[]; if(ui.skills){ skills=skills.concat(ui.skills.skills); @@ -58407,7 +58820,7 @@ } return skills; }, - gainableSkills:function(func,player){ + gainableSkills:(func,player)=>{ var list=[]; for(var i in lib.character){ if(lib.filter.characterDisabled(i)) continue; @@ -58429,7 +58842,7 @@ } return list; }, - gainableSkillsName:function(name, func){ + gainableSkillsName:(name,func)=>{ var list=[]; if(name&&lib.character[name]){ if(lib.character[name][4]){ @@ -58448,7 +58861,7 @@ } return list; }, - gainableCharacters:function(func){ + gainableCharacters:func=>{ var list=[]; for(var i in lib.character){ var info=lib.character[i]; @@ -58468,7 +58881,7 @@ } return list; }, - selectableTargets:function(sort){ + selectableTargets:sort=>{ var selectable=[]; var players=game.players.slice(0); if(_status.event.deadTarget) players.addArray(game.dead); @@ -58484,7 +58897,7 @@ } return selectable; }, - filter:function(filter,i){ + filter(filter,i){ if(typeof filter=='function') return filter; if(i==undefined) i=0; var result=function(){ @@ -58557,8 +58970,9 @@ result._filter_args=[filter,i]; return result; }, - cardCount:function(card,player){ + cardCount:(card,player)=>{ var num; + if(player==undefined) player=_status.event.player; if(card==true){ num=0; var stat=player.getStat('card'); @@ -58567,7 +58981,6 @@ } return num; } - if(player==undefined) player=_status.event.player; if(typeof card=='object'){ card=card.name; } @@ -58575,51 +58988,25 @@ if(num==undefined) return 0; return num; }, - skillCount:function(skill,player){ + skillCount:(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;igame.players.concat(game.dead).find(current=> + current.getCards("hejsx").includes(card)||(current.judging[0]==card&&method!="judge")), + noSelected:()=>ui.selected.buttons.length+ui.selected.cards.length+ui.selected.targets.length==0, + population:identity=>identity==undefined? + game.players.length+game.dead.length: + game.players.filter(current=>current.identity==identity).length, + totalPopulation:identity=>identity==undefined? + game.players.length+game.dead.length: + game.players.concat(game.dead).filter(current=>current.identity==identity).length, + cardtag:(item,tag)=> + (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)) + ||(item.cardtags&&item.cardtags.contains(tag)), + tag:(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]; @@ -58627,7 +59014,7 @@ if(typeof result=='function') return result(item,item2); return result; }, - sortCard:function(sort){ + sortCard:sort=>{ var func; if(sort=='type_sort'){ func=function(card){ @@ -58664,7 +59051,7 @@ } return func; }, - difficulty:function(){ + difficulty:()=>{ switch(get.config('difficulty')){ case 'easy':return 1; case 'normal':return 2; @@ -58672,7 +59059,7 @@ default: return 1; } }, - cardPile:function(name,create){ + cardPile:(name,create)=>{ var filter=function(card){ if(typeof name=='string'){ if(card.name==name){ @@ -58723,13 +59110,9 @@ } return null; }, - cardPile2:function(name){ - return get.cardPile(name,'cardPile'); - }, - discardPile:function(name){ - return get.cardPile(name,'discardPile'); - }, - aiStrategy:function(){ + cardPile2:name=>get.cardPile(name,'cardPile'), + discardPile:name=>get.cardPile(name,'discardPile'), + aiStrategy:()=>{ switch(get.config('ai_strategy')){ case 'ai_strategy_1':return 1; case 'ai_strategy_2':return 2; @@ -58740,7 +59123,7 @@ default: return 1; } }, - skillintro:function(name,learn,learn2){ + skillintro:(name,learn,learn2)=>{ var str=''; var infoitem=lib.character[name]; if(!infoitem){ @@ -58768,7 +59151,7 @@ } return str; }, - intro:function(name){ + intro:name=>{ var info=lib.character[name]; var str='性别:'+get.translation(info[0])+'
    '; str+='势力:'+get.translation(info[1])+'
    '; @@ -58782,7 +59165,7 @@ } return str; }, - storageintro:function(type,content,player,dialog,skill){ + storageintro:(type,content,player,dialog,skill)=>{ switch(type){ case 'mark':{ if(content>0){ @@ -58890,7 +59273,7 @@ } } }, - nodeintro:function(node,simple,evt){ + nodeintro:(node,simple,evt)=>{ var uiintro=ui.create.dialog('hidden','notouchscroll'); if(node.classList.contains('player')&&!node.name){ return uiintro; @@ -58899,6 +59282,7 @@ if(node._nointro) return; if(typeof node._customintro=='function'){ if(node._customintro(uiintro,evt)===false) return; + if(evt)lib.placePoppedDialog(uiintro,evt); } else if(Array.isArray(node._customintro)){ var caption=node._customintro[0]; @@ -59118,7 +59502,7 @@ } tr.appendChild(td); td=document.createElement('td'); - td.innerHTML=node.countCards('h'); + td.innerHTML=`${node.countCards('h')}/${node.getHandcardLimit()}`; tr.appendChild(td); td=document.createElement('td'); td.innerHTML=node.phaseNumber; @@ -59557,7 +59941,7 @@ else{ if(lib.translate[name+'_info']){ if(!uiintro.nosub){ - if(get.subtype(name)=='equip1'){ + if(get.subtype(name,false)=='equip1'){ var added=false; if(lib.card[node.name]&&lib.card[node.name].distance){ var dist=lib.card[node.name].distance; @@ -59570,8 +59954,8 @@ uiintro.add('
    攻击范围:1
    '); } } - else if(get.subtype(name)){ - uiintro.add('
    '+get.translation(get.subtype(name))+'
    '); + else if(get.subtype(name,false)){ + uiintro.add('
    '+get.translation(get.subtype(name,false))+'
    '); } else if(lib.card[name]&&lib.card[name].addinfomenu){ uiintro.add('
    '+lib.card[name].addinfomenu+'
    '); @@ -59962,7 +60346,7 @@ } return uiintro; }, - linkintro:function(dialog,content,player){ + linkintro:(dialog,content,player)=>{ dialog.content.firstChild.remove(); dialog.add('
    已横置
    '); var list=[]; @@ -59975,10 +60359,8 @@ dialog.add(list,true,true); } }, - groups:function(){ - return ['wei','shu','wu','qun','jin','western','key']; - }, - types:function(){ + groups:()=>['wei','shu','wu','qun','jin','western','key'], + types:()=>{ var types=[]; for(var i in lib.card){ if(lib.card[i].mode&&lib.card[i].mode.contains(lib.config.mode)==false) continue; @@ -59990,14 +60372,14 @@ } return types; }, - links:function(buttons){ + links:buttons=>{ var links=[]; for(var i=0;i{ var threaten=1; var skills=target.getSkills(); if(!player&&player!==false){ @@ -60029,7 +60411,7 @@ } return threaten; }, - condition:function(player){ + condition:player=>{ var num=player.hp; if(num>4){ num=4+Math.sqrt(num-4); @@ -60054,7 +60436,7 @@ } return num; }, - attitude:function(from,to){ + attitude(from,to){ if(!from||!to) return 0; from=from._trueMe||from; arguments[0]=from; @@ -60080,10 +60462,10 @@ } return att; }, - sgnAttitude:function(){ + sgnAttitude(){ return get.sgn(get.attitude.apply(this,arguments)); }, - useful_raw:function(card,player){ + useful_raw:(card,player)=>{ if(get.position(card)=='j') return -1; if(get.position(card)=='e') return get.equipValue(card); if(card._modUseful){ @@ -60118,23 +60500,19 @@ result=game.checkMod(player,card,result,'aiUseful',player); return result; }, - useful:function(card,player){ + useful:(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){ + unuseful:card=>-get.useful(card), + unuseful2:card=>10-get.useful(card), + unuseful3:card=>{ if(card.name=='du') return 20; return 10-get.useful(card); }, - value:function(card,player,method){ + value:(card,player,method)=>{ var result=0; var value; if(Array.isArray(card)){ @@ -60173,7 +60551,7 @@ result=game.checkMod(player,card,result,'aiValue',player); return result; }, - equipResult:function(player,target,name){ + equipResult:(player,target,name)=>{ var card=get.card(); if(!card||card.name!=name){ card={name:name}; @@ -60192,7 +60570,7 @@ } return Math.max(0,value1-value2)/5; }, - equipValue:function(card,player){ + equipValue:(card,player)=>{ if(player==undefined||get.itemtype(player)!='player') player=get.owner(card); if(player==undefined||get.itemtype(player)!='player') player=_status.event.player; var info=get.info(card); @@ -60208,7 +60586,7 @@ if(typeof value=='function') return value(card,player,null,'raw2'); return 0; }, - equipValueNumber:function(card){ + equipValueNumber:card=>{ var info=get.info(card); if(info.ai){ if(typeof info.ai.equipValue=='number') return info.ai.equipValue; @@ -60216,13 +60594,9 @@ } 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){ + disvalue:(card,player)=>-get.value(card,player), + disvalue2:(card,player)=>-get.value(card,player,'raw'), + skillthreaten:(skill,player,target)=>{ if(!lib.skill[skill]) return 1; if(!lib.skill[skill].ai) return 1; var threaten=lib.skill[skill].ai.threaten; @@ -60234,7 +60608,7 @@ } return 1; }, - order:function(item){ + order:item=>{ var info=get.info(item); if(!info) return -1; var aii=info.ai; @@ -60252,7 +60626,7 @@ } return num; }, - result:function(item,skill){ + result:(item,skill)=>{ var result; var info=get.info(item); if(info.ai) result=get.copy(info.ai.result); @@ -60269,7 +60643,7 @@ } return result; }, - effect_use:function(target,card,player,player2,isLink){ + effect_use:(target,card,player,player2,isLink)=>{ var event=_status.event; var eventskill=null; if(player==undefined) player=_status.event.player; @@ -60463,7 +60837,7 @@ } return final; }, - effect:function(target,card,player,player2,isLink){ + effect:(target,card,player,player2,isLink)=>{ var event=_status.event; var eventskill=null; if(player==undefined) player=_status.event.player; @@ -60636,7 +61010,7 @@ } return final; }, - damageEffect:function(target,player,viewer,nature){ + damageEffect:(target,player,viewer,nature)=>{ if(get.itemtype(nature)=='natures'){ var natures=get.natureList(nature); return natures.map(n=>get.damageEffect(target,player,viewer,n)).reduce((p,c)=>p+c,0)/(natures.length||1); @@ -60661,7 +61035,7 @@ if(eff>0&&target.hujia>0) return eff/1.3; return eff; }, - recoverEffect:function(target,player,viewer){ + recoverEffect:(target,player,viewer)=>{ if(target.hp==target.maxHp) return 0; if(!player){ player=target; @@ -60671,7 +61045,7 @@ } return get.effect(target,{name:'recover'},player,viewer); }, - buttonValue:function(button){ + buttonValue:button=>{ var card=button.link; var player=get.owner(card); if(!player) player=_status.event.player; @@ -60705,9 +61079,7 @@ default:return 0.4; } }, - attitude2:function(to){ - return get.attitude(_status.event.player,to); - }, + attitude2:to=>get.attitude(_status.event.player,to) }; const ai={ basic:{ diff --git a/game/pinyinjs.js b/game/pinyinjs.js index 6bb5c691f..9d7682f3c 100644 --- a/game/pinyinjs.js +++ b/game/pinyinjs.js @@ -41586,7 +41586,7 @@ var pinyin_dict_withtone = "yī,dīng zhēng,kǎo qiǎo yú,qī,shàng,xià,hǎn temp = ''; for (var j = 0; j < max && (i + j) < chinese.length; j++) { if (!dict.withtone[chinese[i]]) { - i+=(result[i].length-1); + i+=(result[m].length-1); break; } // 如果碰到非汉字直接停止本次查找 temp += chinese[i + j]; diff --git a/image/character/dc_zhangmancheng.jpg b/image/character/dc_zhangmancheng.jpg new file mode 100644 index 000000000..6a84d6c2e Binary files /dev/null and b/image/character/dc_zhangmancheng.jpg differ diff --git a/image/character/ns_mengyou.jpg b/image/character/ns_mengyou.jpg new file mode 100644 index 000000000..1c9327fea Binary files /dev/null and b/image/character/ns_mengyou.jpg differ diff --git a/image/character/zhangyan.jpg b/image/character/zhangyan.jpg new file mode 100644 index 000000000..41b9486fc Binary files /dev/null and b/image/character/zhangyan.jpg differ diff --git a/layout/default/layout.css b/layout/default/layout.css index 1fb12685f..e9139f1b5 100644 --- a/layout/default/layout.css +++ b/layout/default/layout.css @@ -5528,4 +5528,8 @@ div[data-decoration="bronze"]::after{ /*--------其它--------*/ ::-webkit-scrollbar { display: none; +} +/* 火狐隐藏滚动条 */ +* { + scrollbar-width: none; } \ No newline at end of file diff --git a/mode/guozhan.js b/mode/guozhan.js index 773636147..a04e19548 100644 --- a/mode/guozhan.js +++ b/mode/guozhan.js @@ -12950,7 +12950,8 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, _mingzhi1:{ trigger:{player:'phaseBeginStart'}, - priority:19, + //priority:19, + ruleSkill:true, forced:true, popup:false, filter:function(event,player){ @@ -14036,6 +14037,10 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ 'step 0' game.broadcastAll(function(){ ui.arena.classList.add('choose-character'); + for(var i=0;iget.is.double(name1,true).contains(group)).randomGet(); - if(lib.character[name1][1]=='ye') return get.is.double(name2,true).randomGet(); - }(); - } - game.broadcast(function(result,result2){ - for(var i in result){ - if(!lib.playerOL[i].name){ - lib.playerOL[i].init(result[i][0],result[i][1],false); - } - if(result2[i]&&result2[i].length) lib.playerOL[i].trueIdentity=result2[i]; - } - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); - },result2,result); - for(var i in result2){ - if(!lib.playerOL[i].name){ - lib.playerOL[i].init(result2[i][0],result2[i][1],false); - } - if(result[i]&&result[i].length) lib.playerOL[i].trueIdentity=result[i]; - } - for(var i=0;i